OpenVPN Login Bash Shell script for DD-WRT router
Be paranoid about $PATH
It's a good idea to start this script with
PATH=/usr/bin:/bin

Also consider using full paths for programs.
Get the shell to check some errors
set -e -u

Use lower-case for variables
Upper-case is used for communicating well-known environment variables between programs.  Prefer lower-case for our own internal shell variables, to avoid any conflicts.
Simplify the valid-character checking
The while-do loop could be a simple grep:
if /bin/grep -q '[^-_a-zA-Z0-9]' &quot;$1&quot;
then exit 1
fi

With set -e, that's simply
! /bin/grep -q '[^-_a-zA-Z0-9]' &quot;$1&quot;

To be honest, I'm not convinced this checking is needed, provided we don't pass the username as a regular expression - see &quot;Match exactly&quot; below.
Options to echo are not portable
Consider printf '%s' instead (or, in Bash, &lt;&lt;&lt; redirection)
Consider for instead of while for counted loop
With Bash, we could use an arithmetic for loop.  For standard shell, consider
for i in $(seq 10)
do
     hashpass=$(printf '%s%s' &quot;$hashpass&quot; &quot;$hashpass&quot; | \
                /usr/bin/md5sum | /usr/bin/cut -d' ' -f1)
done

You could instead write a filter function and just put that in the code 10 times (which might work slightly faster, as parts can work in parallel, and built-in read is better than starting a process to remove the filename part of the output):
function hashround() {
    local hash rest
    read hash rest
    printf '%s%s' &quot;$hash&quot; &quot;$hash&quot; | /usr/bin/md5sum
}

hashpass=$(printf '%s%s' &quot;$Username&quot; &quot;$Password&quot; | /usr/bin/md5sum \
           | hashround | hashround | hashround | hashround | hashround \
           | hashround | hashround | hashround | hashround | hashround \
           | /usr/bin/cut -d' ' -f1)

(We could even eliminate that final cut if we agree to use it as ${hashpass%% *} to remove the second field as a shell substitution.)
Match exactly
Instead of passing a regular expression to the final grep, use grep -F, and also match the entire line (-x):
if /bin/grep -Fxq &quot;$Username:$hashpass&quot; &quot;$users&quot;
then
    echo &quot;User Authenticated.&quot; &gt;&amp;2
    exit 0
fi

I've also redirected the output to standard error stream, so it doesn't interfere with actual output.