What's new

VPN on/off via cron script

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Fr3d

New Around Here
RT-AC86U running AsusWRT Merlin v 384.9

I would like to disconnect VPN client at midnight and then reconnect VPN at 7am. Can somebody please give me some pointers to where I can learn to do this?
Can somebody please explain how the VPN features are exposed to the cron script variables?
 
Thanks that has helped a lot. I feel like a real chop for not finding those links myself. I will read up on cru and service command and the other options to access the vpn clients.

I created 3 files in /jffs/scripts services-start, vpnon.sh, vpnoff.sh
services-start contains 2 cru commands that create the 2 cron jobs after every reboot.
#!/bin/sh
cru a vpndown "59 23 * * * /jffs/scripts/vpnoff.sh"
cru a vpnup "01 7 * * * /jffs/scripts/vpnon.sh"

vpnon.sh contains the commands to start the vpn service at 7:01am and write to syslog.
#!/bin/sh
service start_vpnclient1
# echo "VPN client is now up"
logger -t VPN client "up"

vpnoff.sh contains the commands to stop the service at 23:59
#!/bin/sh
service stop_vpnclient1
# echo "VPN client is now down"
logger -t VPN client "down"
 
Last edited:
Looks good.:)

Don't forget to start your scripts with a shebang (#!/bin/sh). Personally I wouldn't have the echo command or use -s in logger because there's no stdout or stderr when invoked from cron.
 
Thank you, I have made those improvements for future readers.
I actually have 3 vpnclients configured on the AC86U and I want to start a random one each morning. I guess I need to generate a random number between 1 and 3 and then use a case statement to start one vpnclient at 7:01am.

option=$(( $RANDOM % 3 + 1 ))
case ${option} in

1)
service start_vpnclient1
logger -t VPN client1 "on"
;;

2)
service start_vpnclient2
logger -t VPN client2 "on"
;;

3)
service start_vpnclient3
logger -t VPN client3 "on"
;;
esac
 
Last edited:
I guess I need to generate a random number between 1 and 3 and then use a case statement to start one vpnclient at 7:01am.
Maybe your router is different, but mine doesn't have the $RANDOM variable (I think that's a bash thing). So I had to write my own random number generator. This is the best I've been able to come up with (using just the router's native functions):

EDIT: This doesn't work on Merlin's firmware, only John's fork!
Code:
#!/bin/sh

# Generate numbers between 1 and 6.
let N=6
let BASE=1

while true
do
  RND=$(dd if=/dev/random bs=2 count=8 2>/dev/null | od -i | head -n1 | awk '{print $2}')
  RND2=$(( (RND+32768) % N + BASE ))
  echo $RND2
done
 
Last edited:
Maybe your router is different, but mine doesn't have the $RANDOM variable (I think that's a bash thing). So I had to write my own random number generator. This is the best I've been able to come up with (using just the router's native functions):
Code:
#!/bin/sh

# Generate numbers between 1 and 6.
let N=6
let BASE=1

while true
do
  RND=$(dd if=/dev/random bs=2 count=8 2>/dev/null | od -i | head -n1 | awk '{print $2}')
  RND2=$(( (RND+32768) % N + BASE ))
  echo $RND2
done

octopus@RT-AC68U:/tmp/home/root# /jffs/configs/rnd.sh
/jffs/configs/rnd.sh: line 12: od: not found
 
octopus@RT-AC68U:/tmp/home/root# /jffs/configs/rnd.sh
/jffs/configs/rnd.sh: line 12: od: not found
Oh dear. Maybe od is something that John added to his firmware that isn't in Merlin's. That's unfortunate, I'll have to think of some other way :(.

EDIT: John added it in 374.43_31E1j9527 (21-February-2018).

@octopus Do you mind checking whether $RANDOM exists in Merlin's firmware? If it does then there's no point in me rewriting my script (because it would only be useful to users of John's fork).
 
Last edited:
Oh dear. Maybe od is something that John added to his firmware that isn't in Merlin's. That's unfortunate, I'll have to think of some other way :(.

EDIT: John added it in 374.43_31E1j9527 (21-February-2018).

@octopus Do you mind checking whether $RANDOM exists in Merlin's firmware? If it does then there's no point in me rewriting my script (because it would only be useful to users of John's fork).
sure..
I can se both: /dev/random and /dev/urandom
 
You guys are so far ahead of me, I was ready to call it a day. Took me all day to get this far. I was testing on my Mint laptop. I don't understand the random generator but I was getting a nice spread of random numbers. Then "od not found" on the RT-AC86U stopped me dead. My vpnon.sh looks like this now:
#!/bin/sh

BASE=1 #random numbers start at BASE upto N, ie. 1..3
N=3 #number of configured vpnclients to choose from, max 5 on Asus AC86U

service stop_vpnclient1
service stop_vpnclient2
service stop_vpnclient3

RND=$(dd if=/dev/random bs=2 count=1 2>/dev/null | od -i | head -n1 | awk '{print$2}')
option=$(( $RND % $N + $BASE ))

case ${option} in

1)
service start_vpnclient1
logger -t VPN client1 "on"
;;

2)
service start_vpnclient2
logger -t VPN client2 "on"
;;

3)
service start_vpnclient3
logger -t VPN client3 "on"
;;
esac
 
You guys are so far ahead of me, I was ready to call it a day. Took me all day to get this far. I was testing on my Mint laptop. I don't understand the random generator but I was getting a nice spread of random numbers. Then "od not found" on the RT-AC86U stopped me dead.
Yeah, that's not going to work now. As @octopus pointed out the od command doesn't exist on your router.

Leave it with me. I'm trying to decide on what method to use as an alternative.

N.B. Even if od was present, the way you have changed the RND= and option= lines means it wouldn't have worked properly anyway.
 
OK This is all I've got so far. I can't say I'm that happy with it.

It tries to emulate bash's $RANDOM function, i.e. produce an integer between 0 and 32767. The problem is that awk always produces the same numbers each time you run it unless you use srand(). And even if you do use srand() the seed only changes every second. So probably OK if you just want one random number but no good for generating a sequence.
Code:
# Generate a number between 1 and 6.
let N=6
let BASE=1

RANDOM=$(awk 'BEGIN {srand(); print int(32768 * rand())}')
option=$(( RANDOM % N + BASE ))
echo $option
 
OK This is all I've got so far. I can't say I'm that happy with it.

It tries to emulate bash's $RANDOM function, i.e. produce an integer between 0 and 32767. The problem is that awk always produces the same numbers each time you run it unless you use srand(). And even if you do use srand() the seed only changes every second. So probably OK if you just want one random number but no good for generating a sequence.
Code:
# Generate a number between 1 and 6.
let N=6
let BASE=1

RANDOM=$(awk 'BEGIN {srand(); print int(32768 * rand())}')
option=$(( RANDOM % N + BASE ))
echo $option
I have put your new algorithm into a loop with a 'sleep 1s' and run it on my mint19 laptop. Works like a charm with good spread of randomness. Thank you, if I can get it to work on the router I think I'm home and dry!! I only need to choose a random vpn server once a day.
Code:
8 ones
10 twos
7 threes
neil@neil-Parrot:~/Dropbox/ASUS Router$ bash rndness.sh
76 ones
89 twos
85 threes
neil@neil-Parrot:~/Dropbox/ASUS Router$
I'll copy over to the router and test there.
 
Well done it works like magic, first time. Here is the vpnon.sh
Code:
#!/bin/sh

service stop_vpnclient1
service stop_vpnclient2
service stop_vpnclient3

# Generate a number between BASE and N, ie.1 and 3 to choose which vpnclient is started
let N=3     #number of configured vpnclients to choose from, max 5 on Asus 86U
let BASE=1  #random numbers start at BASE upto N, ie. 1..3

RANDOM=$(awk 'BEGIN {srand(); print int(32768 * rand())}')
option=$(( RANDOM % N + BASE ))

case ${option} in

    1)
        service start_vpnclient1
        logger -t VPN client1 "on"
    ;;

    2)
        service start_vpnclient2
        logger -t VPN client2 "on"
    ;;

    3)
        service start_vpnclient3
        logger -t VPN client3 "on"
    ;;
esac

exit 0
 
EDIT: See post #20.

OK, just to finish this off (in the unlikely event anybody cares :rolleyes:) here is an improved RNG function.

Whilst the solution in the previous post is more than adequate for that task there were a couple of issues that annoyed my OCD. Firstly, it couldn't be used as-is to generate a sequence of numbers. Secondly, the distribution of numbers wasn't truly random because of the use of the % operator. With large number ranges the probability became skewed towards to lower numbers.

Anyway, here it is...
Code:
#!/bin/sh

# Generate random numbers from BASE to BASE+N-1
N=6
BASE=1

while true
do
  RND=$(awk "BEGIN {srand(); print int(rand() * $N) + $BASE; system(\"usleep 1100000\")}")
  echo $RND
done

If anyone can think of a better/alternative way I'd love to see it.:)
 
Last edited:
OK, just to finish this off (in the unlikely event anybody cares :rolleyes:) here is an improved RNG function.

Whilst the solution in the previous post is more than adequate for that task there were a couple of issues that annoyed my OCD. Firstly, it couldn't be used as-is to generate a sequence of numbers. Secondly, the distribution of numbers wasn't truly random because of the use of the % operator. With large number ranges the probability became skewed towards to lower numbers.

Anyway, here it is...
Code:
#!/bin/sh

# Generate random numbers from BASE to BASE+N-1
N=6
BASE=1

while true
do
  RND=$(awk "BEGIN {srand(); print int(rand() * $N) + $BASE; system(\"usleep 1100000\")}")
  echo $RND
done

If anyone can think of a better/alternative way I'd love to see it.:)
Off-topic for the original question, but is the sleep delay necessary, or can it be shortened? I might be looking to borrow this for something :D
 
Off-topic for the original question, but is the sleep delay necessary, or can it be shortened? I might be looking to borrow this for something :D
The sleep is only required if you want to generate more than one random number. As noted in post #14 the srand() function seeds on the current date/time (to a 1 second resolution) and therefore keeps generating the same number until the next second rolls over.

If you remove the sleep from the script and run it you will see how it works.
 
Prompted by @smasher's recent post here I revisited this thread.

His technique of using openssl's rand option solves the issue I had in post #6 with converting raw data into numeric strings. It also negates the need for my ugly workaround (a 1 second sleep) in post #17. :)

So here is the new and improved :p version of the random number generator script.
Code:
#!/bin/sh

# Generate random numbers from BASE to BASE+N-1
N=6
BASE=1

while true
do
  RND=$(printf "%d" 0x$(openssl rand -hex 3))
  RND2=$(( RND % N + BASE ))
  echo $RND2
done

Unlike @smasher and my previous script I don't bother reseeding the random number generator this time as I don't believe that is necessary when using openssl. That's partly because of the inclusion of haveged in current firmwares.

Note: This method still suffers from the "skew" problem I mentioned in post #17 because of it's use of the modulo. By increasing the resolution of the random number generator from 16 to 24 bits this is somewhat relieved.
 
Last edited:

Similar threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top