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!

Does that need to run in a loop? Or just spit out one random number per invocation?

If the output is in the range of 1-6, do you need 3 bytes? or is 1 byte sufficient? 1 byte gives output in the decimal range of 0-255. Skew isn't a problem, see below.

As for the seed, "openssl rand" will automatically create a ".rnd" file in the home directory. Might not be there on the script's first run after (re)boot, but if the file is there, it will automatically be used as a seed. If one was concerned about that, they could just create that seed file from the init-start script, with something like "head -c 512 /dev/urandom > /root/.rnd", or even better, "openssl rand 1 > /dev/random".

Here's what I've got...
Code:
#!/bin/sh

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

#while [ '0' == ${?} ]
#do
  RND=$(printf "%d" 0x$(openssl rand -hex 1))
  RND2=$(( RND % N + BASE ))
  echo $RND2
#done

In practice, the "skew" isn't a problem. I collected output from 64,200 invocations of that script (directly above, run on an AC68U) and here's the distribution of the output:
Code:
  10772 1
  10762 2
  10805 3
  10726 4
  10487 5
  10648 6
But... If you really want to convert raw data into numeric strings, here's an ugly and inefficient way to do it:
Code:
head -c 100 /dev/urandom | tr -c -d '0-9'
The two biggest problems with that, are (1) there's no guarantee that the output will contain any numbers, and (2) you're consuming a lot more entropy than needed. You could also wind up with a number that's 100 digits long. An improvement would be something like this:
Code:
printf "%d" 0x$( head -c 1 /dev/urandom | openssl md5 | cut -c 10-11 )
That hashes one byte of random (raw) data (0-127 range, in decimal), then converts the first hexadecimal character (any character of the hash would work; each hexadecimal character is 6 bits, or 0-31, in decimal) of the hexadecimal hash into a random decimal number in the 0-15 range. If you want larger random numbers, just make sure that what's read from urandom and the hashed bytes that are converted into a decimal output are both scaled up proportionately.

Just some ideas, but yeah, I think "openssl rand" is your best bet.
 
Last edited:
Does that need to run in a loop? Or just spit out one random number per invocation?
No it doesn't need to run in a loop. That was just done to demonstrate whether or not the sequence of numbers was truly random. The problem with using awk's rand() in a script is that it generates the same number every time. To get around that I used srand() but that only changes the seed value every second. Hence the need for the sleep command.

If the output is in the range of 1-6, do you need 3 bytes? or is 1 byte sufficient? 1 byte gives output in the decimal range of 0-255. Skew isn't a problem, see below.
Yes 1 byte would be good enough for simulating things with small ranges like dice rolls. The problem with skew comes when trying to generate larger number ranges using the % (modulus) operator. For example, using a 1 byte generator gives numbers from 0 to 255. If you were to use n%192 to create random numbers from 0 to 191 the probability of "7" occurring is 2 in 256 (once in 0-191 and once in 192-255). The probability of "99" occurring is only 1 in 256 (once in 0-191).

An alternative to using modulus which doesn't suffer from skew would be as follows.
Code:
RND=$(printf "%d" 0x$(openssl rand -hex 2))
RND2=$(( RND * N / 65536 + BASE ))
Note that this technique must use only 2 bytes (16 bits) for random numbers (0-65535) because it exploits the shell's integer arithmetic functions which are signed 32 bit numbers. It should be good enough for random numbers between 0 and 32767. (Note that the "probability problem" that the modulus technique has still exists with this method, only now it's distributed evenly over the entire range so it's less obvious.)

Thanks for the other ideas about converting strings, I'll think about what you've said later today when I've got more time. But as a general principle I don't tend to like anything which tries to create random numbers from apparently random set of strings (like md5 output) because the fact that they're based on human-readable alphanumeric characters usually means that the distribution is not random.
 
Last edited:
But as a general principle I don't tend to like anything which tries to create random numbers from apparently random set of strings (like md5 output) because the fact that they're based on human-readable alphanumeric characters usually means that the distribution is not random.
There are reasons to be suspicious of hashes as a source of "randomness", but the randomness of the hexadecimal representation of a hash is just as random as it would be in binary form. In hexadecimal, there's 4 bits of entropy per character, and the limiting factor is the quality of the input, not the format of the output.

Anyway, here's one that doesn't rely on hashing. Instead, it just uses the nanosecond counter (since boot) as a "seed" for the modulus operation:
Code:
#!/bin/sh

BOUND_LOWER=1
BOUND_UPPER=10

NANOSECONDS=$( awk 'NR==3 {print $3}' /proc/timer_list | tail -c 10 )
expr ${NANOSECONDS} % $(( ${BOUND_UPPER} - ${BOUND_LOWER} + 1 )) + ${BOUND_LOWER}
That's subject to skew, but in practice it's not a problem because the seed is up to 9 digits long.

Then there's this, which eliminates skew, but it can run much slower:
Code:
#!/bin/sh

BOUND_LOWER=1
BOUND_UPPER=10

false
while [ '0' -ne ${?} ]
do
 NANOSECONDS=$( awk 'NR==3 {print $3}' /proc/timer_list | tail -c $(( ${#BOUND_UPPER} + 1 )) )
 [ ${BOUND_UPPER} -ge ${NANOSECONDS} ] && [ ${BOUND_LOWER} -le ${NANOSECONDS} ] && expr ${NANOSECONDS} + 0
done
Of course there's nothing at all random about a nanosecond counter, but in practice it works well.

nb, on both of those scripts, both the lower and upper bounds can be used to set a range of numbers that you want output.
 
Last edited:
And here's a re-write of my "openssl rand" script from comment #21, to correctly make use of upper and lower bounds:
Code:
#!/bin/sh

## IMPORTANT ##
## use more than 1 byte of random data from "openssl rand"
## for higher ranges and/or less skew from the modulus operation

BOUND_LOWER=1
BOUND_UPPER=10

RND=$( printf "%d" 0x$( openssl rand -hex 4 ) )
expr ${RND} % $( expr ${BOUND_UPPER} - ${BOUND_LOWER} + 1 ) + ${BOUND_LOWER}
 
Last edited:
Note that this technique must use only 2 bytes (16 bits) for random numbers (0-65535) because it exploits the shell's integer arithmetic functions which are signed 32 bit numbers.
This limit can be overcome by using "expr", instead of the shell's arithmetic functions.

This is as high as we can go using the shell's built-in arithmetic functions:
Code:
echo $(( $(printf "%d" 0x7fffffff) ))
Only just past two billion.

But this works fine:
Code:
expr $(printf "%d" 0x7fffffffffffffff)
So we can work with up 7.5 bytes (60 bits), using expr, for a range of 0 - 9,223,372,036,854,775,807.

That's nine quintillion. Should be enough.
 
Last edited:
This limit can be overcome by using "expr", instead of the shell's arithmetic functions.
Thanks for the expr idea, I think that solves everything we could want. I had already worked out that internally printf was using signed 64 bit integers but it hadn't occurred to me to use expr which appears to do the same. So as long as all of the calculations are done with expr that gives us a working range of -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. :)

Of course we have to be careful of any calculations that creates fractions (i.e. division) as that would force it to use floating point arithmetic which I believe is double-precision 64 bit, and therefore less accurate. But that's a whole new area I don't want to get into. :eek::D

So we can work with up 7.5 bytes (60 bits), using expr...
Strictly speaking it's 8 bytes, 1 sign bit and 63 bits for the number.
 
Last edited:
Can someone write/help me how to schedule a ON/OFF for my VPN Client?

I want the VPN client to turn on Fridays, Saturdays, Sundays and Mondays at 10:30AM and turn off at 2:30PM.

Is it possible to schedule this specific?
 
Last edited:
Can someone write/help me how to schedule a ON/OFF for my VPN Client?

I want the VPN client to turn on Fridays, Saturdays, Sundays and Mondays at 10:30AM and turn off at 2:30PM.

Is it possible to schedule this specific?

Yep... Add these statements to your 'services-start':

cru a vpnup "30 10 * * FRI,SAT,SUN,MON /jffs/scripts/vpnon.sh"
cru a vpndown "30 14 * * FRI,SAT,SUN,MON /jffs/scripts/vpnoff.sh"

And, like how Fr3d explained near his OP, create 2 files under your /jffs/scripts:

vpnon.sh contains the commands to start the vpn service at 10:30 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 14:30
#!/bin/sh
service stop_vpnclient1
# echo "VPN client is now down"
logger -t VPN client "down"
 
FYI: The OP's use of quotes in his logger statement makes no sense.

I can't guess what his intention was but it should either have been:
Code:
logger -t "VPN client" "up"
or
Code:
logger -t "VPN" "client up"
 
FYI: The OP's use of quotes in his logger statement makes no sense.

I can't guess what his intention was but it should either have been:
Code:
logger -t "VPN client" "up"
or
Code:
logger -t "VPN" "client up"
It sounded about right! LOL ;)
 
Thanks!
OK. I created the services-start. I added the cru to services-start but it does start automatically regardless of the time/day.

How can this be fixed?

I also have added the syslog scripts to jffs/scripts folder.
 
Last edited:
Thanks!
OK. I created the services-start. I added the cru to services-start but it does start automatically regardless of the time/day.

How can this be fixed?

I also have added the syslog scripts to jffs/scripts folder.
Could you send a screenshot of what your scheduled CRU tasks are?

Code:
cru l

Could you explain what starts automatically regardless of the time/day? What are you seeing?

I added the vpnon cru task on my end, and it didn't start the /jffs/scripts/vpnon.sh for me?
 
This is the screenshot. (Don’t mind the hours. I was trying to make it work by changing the time). This is the only cru I have. Nothing else.

What happens is; after adding this cru at services-start, the VPN automatically starts when I reboot the router. I have to manually stop the client. Otherwise, it will not stop by itself even at “scheduled” cru.
 

Attachments

  • 7F209D43-C024-4176-AF77-89AE644AFCA8.jpeg
    7F209D43-C024-4176-AF77-89AE644AFCA8.jpeg
    64.9 KB · Views: 49
  • 4C45BD52-2D78-49B4-B084-988DABBBA3ED.jpeg
    4C45BD52-2D78-49B4-B084-988DABBBA3ED.jpeg
    104.1 KB · Views: 44
  • ED440C22-F83B-44DF-A406-3D9578613C55.jpeg
    ED440C22-F83B-44DF-A406-3D9578613C55.jpeg
    155.2 KB · Views: 50
This is the screenshot. (Don’t mind the hours. I was trying to make it work by changing the time). This is the only cru I have. Nothing else.

What happens is; after adding this cru at services-start, the VPN automatically starts when I reboot the router. I have to manually stop the client. Otherwise, it will not stop by itself even at “scheduled” cru.
If that's your "services-start" file, make sure you have a she-bang at the top...

Code:
#!/bin/sh

Are you sure your VPN client isn't starting by itself after you reboot your router because you have enabled "Automatic start at boot time"?

Screenshot 2022-02-14 18.10.45.png


To look and see what is currently scheduled in your cru list... type this:

Code:
cru l
 
OK. The automatic start at boot was on BUT it still doesn’t work. Yes, I added the #!/bin/sh in the services-start file.

When I did cru l, nothing shows/lists. So, the task actually isn’t working.
 
OK. The automatic start at boot was on BUT it still doesn’t work. Yes, I added the #!/bin/sh in the services-start file.

When I did cru l, nothing shows/lists. So, the task actually isn’t working.

OK... so your "services-start" file should contain this... does it look right on your end? I made a small modification... make sure you add "sh" in front of the "/jffs/scripts/..."

Code:
#!/bin/sh

cru a vpnup "30 10 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnon.sh"
cru a vpndown "30 14 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnoff.sh"

Then, reboot your router... and these cru commands should automatically add themselves to your cru tasks. So when you run "cru l", you should see something like this:

Code:
ASUSWRT-Merlin RT-AC86U 386.4_0 Sat Jan  1 18:43:23 UTC 2022
adminz@RT-AC86U-BE10:/jffs/scripts# cru l
25 13 * * * sh /jffs/scripts/firewall banmalware #Skynet_banmalware#
22 1 * * Mon sh /jffs/scripts/firewall update #Skynet_autoupdate#
0 * * * * sh /jffs/scripts/firewall save #Skynet_save#
0 0 * * * /jffs/scripts/vpnmgr refreshcacheddata #vpnmgr_cacheddata#
43 */12 * * * sh /jffs/scripts/firewall debug genstats #Skynet_genstats#
30 10 * * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnon.sh #vpnup#
30 14 * * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnoff.sh #vpndown#
adminz@RT-AC86U-BE10:/jffs/scripts#

You can manually test your scripts by just running:

Code:
sh /jffs/scripts/vpnon.sh

sh /jffs/scripts/vpnoff.sh
 
OK. It works ONLY when I do this manually


sh /jffs/scripts/vpnon.sh

sh /jffs/scripts/vpnoff.sh

otherwise, it doesn’t work automatically.

cru l still doesn’t show anything.
 
OK. It works ONLY when I do this manually


sh /jffs/scripts/vpnon.sh

sh /jffs/scripts/vpnoff.sh

otherwise, it doesn’t work automatically.

cru l still doesn’t show anything.
Try adding them manually... do you see anything in your cru task list (cru l) after you type this command?

Code:
cru a vpnup "30 10 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnon.sh"
 
Yes, when I do cru l, I get this: 30 10 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnon.sh #vpnup
AFTER adding the command.
I also
see the off version after adding this command, cru a vpndown "30 14 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnoff.sh"
 
Last edited:
Yes, when I do cru l, I get this: 30 10 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnon.sh #vpnup
AFTER adding the command.
I also
see the off version after adding this command, cru a vpndown "30 14 * * FRI,SAT,SUN,MON sh /jffs/scripts/vpnoff.sh"

Show me a screenshot of your "cru l"?
 

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

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