What's new

VPNMON VPNMON-R2 v2.52 -Mar 27, 2023- Monitor your VPN connection's Health (Thread locked/closed)

  • 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!

Viktor Jaep

Part of the Furniture
v2.52 - Now with even more SuperRandom(tm) goodness!!
Updated March 27, 2023

Executive Summary: VPNMON-R2 is an all-in-one script that works for any VPN service of your choice, but is optimized for NordVPN, SurfShark VPN, WeVPN and Perfect Privacy VPN services. It can also compliment @JackYaz's VPNMGR program to maintain a NordVPN/PIA/WeVPN setup. This script will check the health of (up to) 5 VPN connections on a regular interval to see if one is connected, and sends a ping to a host of your choice through the active connection. If it finds that connection has been lost, it will execute a series of commands that will kill all VPN clients, will optionally whitelist all NordVPN/PerfectPrivacy VPN servers in the Skynet Firewall, and randomly picks one of your (up to) 5 VPN Clients to connect to. One of VPNMON-R2's unique features is called "SuperRandom", where it will randomly assign VPN endpoints for a random county (or your choice) to your VPN slots, and randomly connect to one of these. It will now also test your WAN connection, and put itself into standby until the WAN is restored before reconnecting your VPN connections. Major features: Now included in AMTM, Remote VPN Reset, Remote Router Reboot, KILLMON integration, Round-Robin, Fastest Connection Switching, AirVPN/WeVPN/Perfect Privacy/SurfShark/NordVPN VPN Compatible, WAN Awareness, YazFi Compatible, Multi-Country Capable.

VPNMON is free to use under the GNU General Public License version 3 (GPL 3.0).

This project is hosted on GitHub

Changelog here / What's new: AirVPN+Remote Reboot+Auto Start, KILLMON Suppression, KILLMON Integration, More Commandline Parameters, Round Robin + Stats, NordVPN Recommended Servers, Screen Utility Optimizations, Now Supporting WeVPN! -- VPNMON-R2 is now available in AMTM!

Screenshot:
vpnmon-r2-248-main.png

The Problem I was trying to solve​

  • As a former VPNMGR user, I had 5 different NordVPN VPN Client configurations populated on my Asus router running Merlin FW, each with a different city. There were times that I would lose connection to one of these servers, and the router would just endlessly keep trying to reconnect to no avail. Also, sometimes the SKynet firewall would block these NordVPN endpoints, and it would again, endlessly try to connect to a blocked endpoint. Other times, freakishly, I would have more than 1 VPN Client kick on for some reason. This program was built as a way to check to make sure VPN is connected, that the connection is clean, and that there aren't multiple instances running. If anything was off, it would launch a full-on assault and try to reset everything back to a normal state.
  • I also wanted a way for my VPN connection to reset each night, so that it would randomly select and connect to a different configuration, thus endpoint, so that I wouldn't be connected to the same city 24x7x365.
  • NordVPN literally has thousands of VPN endpoint servers which change frequently, depending on the distance or latency from your location scattered across the globe. On several occations, my Asus-Merlin-based Skynet firewall would block these VPN servers, and wanted to make sure I had a way to find all the latest VPN server IPs, and add them to the Skynet whitelist.
  • Above all, I wanted to make this script flexible enough for those who aren't running VPNMGR, using NordVPN or making use of the Skynet Firewall, so options have been built-in to bypass this functionality to make it usable in any VPN usage scenario.

How is this script supposed to run?​

Personally, I run this script from a SCREEN utility window running directly on the router itself, reachable through its own SSH window... but could very well just run from a PC that's connected directly to the Asus router, as it loops and checks the connection every 60 seconds. Instructions:
  1. Download and install directly from AMTM, or using your favorite SSH tools, copy & paste this command:
    Code:
    curl --retry 3 "https://raw.githubusercontent.com/ViktorJp/VPNMON-R2/master/vpnmon-r2-2.52.sh" -o "/jffs/scripts/vpnmon-r2.sh" && chmod 755 "/jffs/scripts/vpnmon-r2.sh"
  2. To initially configure this script, open up a dedicated SSH window, and simply execute the script::
    Code:
    sh /jffs/scripts/vpnmon-r2.sh -setup
  3. Once you've successfully configured the various options, you can run the script using this command:
    Code:
    sh /jffs/scripts/vpnmon-r2.sh -monitor
One particular ingenious way to run this is using the "screen" utility continuously from the router itself, instead of an attached session. (FYI, during the 'vpnmon-r2 -setup' process, you will be prompted to install the "screen" utility)
  1. First, make sure you install the "screen" utility (and have Entware installed):
    Code:
    opkg install screen
  2. The screen utility allows you to run the script in the background, detached from your current ssh session. Type:
    Code:
    screen -dmS vpnmon-r2 sh /jffs/scripts/vpnmon-r2.sh -monitor
  3. You can then reattach to the running script at any time, from any ssh session, on any client machine! Type:
    Code:
    screen -r vpnmon-r2
  4. Perform the detach by hitting CTRL-A + D (NOTE: if you don't do this, you will kill your VPNMON-R2 session!)
  5. To make life easier, can now also just launch or reconnect to VPNMON-R2 with the -screen switch. Type:
    Code:
    vpnmon-r2 -screen
What an awesome way to keep an SSH script running! Thanks @eibgrad!
 
Last edited:

What this script does​

  1. Checks the VPN State from NVRAM and determines if each of the 5 Clients are connected or not
  2. If a VPN Client is connected, it sends a PING through to Google's DNS server to determine if the link is good (configurable)
  3. If it determines that the VPN Client is down, or connection is broken, it will attempt to reset the VPN
  4. If it determines that multiple VPN Clients are running, it will attempt to reset the VPN
  5. If it determines that the NordVPN server load is too high (optional), it will attempt to reset the VPN
  6. Updates Skynet whitelist with all US-based NordVPN endpoint IP addresses (optional) - FYI, you can easily change this for the country of your choice.
  7. Updates vpnmgr cache with recommended NordVPN/PIA/WeVPN endpoint information (optional), and merges/refreshes these changes with your VPN Client configurations
  8. Uses a randomizer to pick one of 5 different VPN Clients to connect to (configurable between 1 and 5)
  9. It will loop through this process every 60 seconds (configurable)
  10. Logs major events (resets/connection errors/etc) to a log file.
  11. It will reset your VPN connection at a regularly scheduled time using the settings at the top of the script (optional)
  12. It now shows the last time a VPN reset happened indicated by "Last Reset:", an indicator when the next reset will happen, and how often the interval happens (in seconds) on the easy-to-read VPNMON-R2 interface in your SSH shell, along with a progressbar to show script activity
  13. Added a new API lookup to display the VPN exit node city/location next to the active VPN connection. This API is free, and guarantees at least 1000 lookups per month. In lieu of doing a lookup each single refresh interval, a location lookup is only done when either the script starts up fresh, or if VPNMON-R2 initiates a reset.
  14. Added the concept of SuperRandom(tm) NordVPN Connections! This is a NordVPN/SurfShark/PerfectPrivacy feature only! When enabled, it will fill your VPN client slots with random VPN servers across the country of your choice. Distance, load, and performance be damned!!
  15. Added an integrated configuration utility (by running "vpnmon-r2.sh -config") that steps you through all the options and saves results to a config file, without the need to manually edit and configure the script itself.
  16. Added a script update checker, which notifies you when a new version becomes available, and allows you to easily download an install the latest script by using the 'vpnmon-r2.sh -update' command.
  17. Optionally shows a row of stats on bottom row, indicating low/high ping times, server load, Avg sent/received bandwidth (in Mbps), and total traffic sent/received on the active tunnel.
  18. Added the ability to specify up to 2 additional countries (for a total of 3) to randomly pick VPN servers located within that country. Yes, we have gone completely international!
  19. Happy to report that VPNMON-R2 now integrates beautifully with YazFi - the premier expanded guest network utility for Merlin firmware! For those running multiple guest networks, VPNMON-R2 can now automatically update your guest network slots with the latest VPN slot that VPNMON-R2 just made a connection to, then performs the necessary steps to make YazFi acknowledge the change to ensure your guest client devices continue to work without interruption!
  20. Added capabilities to check if your modem goes down, or your ISP stops working, then falls back and waits until your WAN comes back up in order to re-establish a VPN connection.
  21. VPNMON-R2 is now compatible with Perfect Privacy and SurfShark VPN services!
  22. Added capabilities to switch to the fastest connections based on ping ms to your VPN endpoints.
  23. Happy to announce that VPNMON-R2 is now being included in AMTM! Many thanks to @thelonelycoder!
  24. VPNMON-R2 is now compatible with WeVPN!
  25. Added the NordVPN "Recommended Servers" functionality, giving you access to the closest, fastest, lowest latency servers to you!
  26. Added the "Round Robin" method of picking your VPN slots!
  27. Integrated with KILLMON and showing integrity status within the UI
  28. Added AirVPN support!
  29. Added Remote Reboot -- using a simple command in an internet-accessible file, you can remotely reset the VPN or reboot your router!
  30. Added Auto Start after a router reboot... VPNMON-R2 will now run in the screen environment automatically.

What if I'm not running VPNMGR/NordVPN(PIA/WeVPN)/Skynet?​

  1. As long as your VPN slots are configured and tested using the VPN provider of your choice, this script will run perfectly fine, and can monitor, reset and randomly start a new VPN client slot for you each day. Please know, this script was written to compliment NordVPN, Surfshark, WeVPN, Perfect Privacy, and AirVPN and gives a heavy preference to VPNMGR, but none of which is required.
  2. While stepping through the configuration utility ("vpnmon-r2.sh -config"), you can choose to disable the ability to update VPNMGR hosts, enable/disable specific NordVPN, Surfshark, WeVPN, Perfect Privacy, and AirVPN functionality, and the ability to whitelist the latest NordVPN/Perfect Privacy/AirVPN servers in Skynet.
  3. Let me know how you're using this script! Feel free to post in this forum. ;)

Usage​

VPNMON-R2 is driven with commandline parameters. These are the available options:
  • vpnmon-r2 -h (or vpnmon-r2.sh -help) -- displays a short overview of available commands
  • vpnmon-r2 -log -- displays the contents of the VPNMON-R2 activity log in the NANO text editor
  • vpnmon-r2 -config -- launches the configuration utility and saves your settings to a local config file
  • vpnmon-r2 -update -- launches the script update utility to download the newest version
  • vpnmon-r2 -setup -- launches the setup menu to configure and add optional Entware components
  • vpnmon-r2 -reset -- initiates a VPN reset for use with setting up external CRON jobs (like the vpnon script did)
  • vpnmon-r2 -pause -- pauses all operations, sits back and waits for a -resume command
  • vpnmon-r2 -resume -- resumes normal operations of VPNMON-R2, coming from a -pause
  • vpnmon-r2 -status -- indicates the current status of VPNMON-R2, along with the last known used VPN slot
  • vpnmon-r2 -failover -- stops and resumes all operations during a manual WAN failover/failback
  • vpnmon-r2 -uninstall -- launches the uninstall utility that removes VPNMON-R2 from your router
  • vpnmon-r2 -screen -- launches VPNMON-R2 using the "screen" utility, and places it in -monitor mode
  • vpnmon-r2 -monitor -- launches VPNMON-R2 in a normal operations mode, ready to monitor the health of your VPN connections
Screenshots

Persistent screen of VPNMON-R2 v2.48 running from your favorite SSH window:
vpnmon-r2-248-main.png


Example of VPNMON-R2 dealing with a dropped VPN connection:
vpnmon-r2-224-reset.jpg


You can optionally refresh VPNMGR, update/whitelist VPN hosts in the Skynet firewall, or randomly populate your VPN client slots using NordVPN/SurfShark/WeVPN/Perfect Privacy/AirVPN SuperRandom(tm), and update your YazFi Guest networks as well with the current active VPN connection!

Example of the log file contents:
vpnmon-r2-15-log.jpg


A setup menu is available by using the "vpnmon-r2.sh -setup" switch, or entering it directly from either AMTM, or from the main VPNMON-R2 UI itself.
vpnmon-r2-224-setup.jpg


And here is the configuration utility that takes you through the options step-by-step to ensure a compatible experience for your setup and keeps that VPN connection healthy! Please note, there are now 2 pages of options as of v2.48! :)
vpnmon-r2-248-config1.png
 
Last edited:

OK, you've convinced me -- how do I setup a VPN or run VPNMON-R2?​

In case you're curious about how to configure your own amazing whole-home VPN setup, here are some basic instructions... Please understand that this is how I have my OVPN client slots setup, and your needs may differ, so feel free to jump into this thread if you have any other setup questions!

1.) Insert a Flashdrive - First plug a flashdrive into the back of your router, where a lot of these scripts, cache and swap file will end up being located.

2.) Use the AMTM tool - Log into your router using an SSH terminal tool, like PuTTY (for Windows), execute "AMTM", and use the commands "fd" to format your flashdrive, and "sw" to configure a swap file. Minimum recommended size is at least 2GB.

3.) Configure your router to handle scripts - You must first enable the ability for your router to handle custom scripts. From your router UI, go to Administration -> System -> "Format JFFS partition at next boot" (yes) and "Enable JFFS custom scripts and configs" (yes)... reboot your router to enable these changes.

4.) Subscribe to a VPN provider - Picking NordVPN, SurfShark or Perfect Privacy will give you some more awesome functionality with VPNMON-R2, but you can basically pick anything you want. I'm going to use NordVPN in these examples...

5.) Download your VPN server config - Go to your VPN providers server config download page (ex: https://nordvpn.com/servers/tools/), and pick one (or a selection) of OpenVPN UDP server configs, and download them. It will probably end up with a name like this: "us9488.nordvpn.com.udp.ovpn"

1657465836470.png



6.) Check the .ovpn contents - The contents of the .ovpn file will contain the security certificates, vpn server name, and configuration parameters. Give it a cursory glance to make sure it looks like everything's there.

7.) Configure your VPN Client Slots - From the Asus-Merlin VPN Client page, pick your 1st OpenVPN Client Slot... click on the "Choose File" button, and select the file you just downloaded, and click the "Upload" button to import it. This will populate most of your settings on this page, but will need to go through, name some things, and make some configuration tweaks. For example, these are the settings I use below... yours might differ based on your preferences.

Screenshot 2022-02-20 19.11.11.png

Screenshot 2022-02-20 19.11.56.png



8.) Apply these custom configuration entries on the bottom of the page - This is an important step! The custom config entries that come with the .ovpn file may work, but aren't the greatest. Please over-copy them with these configuration entries below. These work great for NordVPN, but for many other VPN providers as well. If they don't, revert back or look for some best practice entries for your particular VPN provider:

Code:
remote-random
resolv-retry infinite
remote-cert-tls server
ping 15
ping-restart 0
ping-timer-rem
persist-key
persist-tun
reneg-sec 0
fast-io
disable-occ
mute-replay-warnings
auth-nocache
sndbuf 524288
rcvbuf 524288
push "sndbuf 524288"
push "rcvbuf 524288"
pull-filter ignore "auth-token"
pull-filter ignore "ifconfig-ipv6"
pull-filter ignore "route-ipv6"
explicit-exit-notify 3
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450

9). Test your VPN Client! After you hit "APPLY" on the bottom of the Asus-Merlin VPN Client page, slide the on/off switch to ON, and see if you can make a successful VPN connection. If you don't see any errors, and have been able to test that your client(s), network(s), etc. can browse through the VPN, you can crack open that beer in celebration. ;)

10.) Now go configure your other 4 slots! To make the best use of VPNMON-R2, you would want each of your 5 standalone VPN client slots pre-configured in the same way you just did your first. Note: If you're considering using the VPNMON-R2 SuperRandom functionality, you can actually use the same .ovpn file for each of your 4 other slots. Your VPN Slot's "server address" and "description" fields will be automatically filled in by the VPNMON-R2 script when it finds new random servers for you to connect to.

Important: VPN Director is an important element to consider as well, and would recommend creating 5 different entries for each of your 5 VPN Client slots to ensure that your local subnet will ALWAYS route through the VPN no matter which VPN client is currently connected. See below:

1657476560112.png


11.) Download VPNMON-R2 -- Using the AMTM tool, download and install VPNMON-R2. From it's main menu, type "sc" to setup and configure the script. You can use the defaults in place to run it with minimal functionality, or go through and make selections based on your particular environment.

12.) Profit! Now go ahead and enjoy the experience... :)

Gotchas​

  • If you want to make the integration with VPNMGR, please make sure you have installed VPNMGR, have populated your VPN slots with it, have tested refreshing its cache, and that you are able to successfully connect to your VPN provider before running this script. You may find the program and installation/configuration information here: https://www.snbforums.com/threads/v...ent-configurations-for-nordvpn-and-pia.64930/
  • Make sure you keep your VPN Client slots sequential... don't use 1, 2, and 4... for instance. Keep it to 1, 2, and 3.
  • If you're using the NordVPN SuperRandom(tm) functionality, please be sure that each of your VPN slots are fully configured, as this function will only replace your "server address" IP and the "description" in NordVPN - [CITY] format. It is also important to disable the VPNMGR update so they don't conflict.

Known Issues
  • After installing, and if you see VPNMON-R2 continually resetting due to a "Ping/HTTP response failed" in your logs, then please read the following...
  • It has recently come to my attention that if you are using AdGuard Home, (perhaps even other site blocking tools like Diversion or Skynet), there is a chance that it may break VPNMON-R2's functionality, because it's blocking sites that I need to resolve IP addresses. Namely, please make sure you have unblocked from your blacklists.
  • Here are the instructions on how to add this to your whitelist in AdGuard Home (thanks to @cptnoblivious)
    • Adguard home web interface | Filters | Custom filtering rules
      Add: @@||ipv4.icanhazip.com^
      Hit "Apply"

Auto-Startup Guidance
  • Great news! Auto start capabilities have been added to VPNMON-R2 as of v2.48! It uses the basic methodology as described below...
  • This is the way that many prefer to start the script using something more simple (below), or going all out (courtesy of @iTyPsIDg), though the choice is yours:
Code:
Editing your 'post-mount' file under /jffs/scripts, use the 'nano' commandline tool add this line:

(sleep 30 && /jffs/scripts/vpnmon-r2.sh -screen) & # Added by vpnmon-r2
 
Last edited:
Sorry everyone... our original thread hit its limit, and had to start a new one...
welcome-back-we-missed-you.jpg
:)

I have v2.01rc (Release Candidate) available for you to try @Stephen Harrington ... @JAX1337 seems to be having decent luck with it I believe:
Code:
curl --retry 3 "https://raw.githubusercontent.com/ViktorJp/VPNMON-R2/master/vpnmon-r2-2.01rc.sh" -o "/jffs/scripts/vpnmon-r2.sh" && chmod a+rx "/jffs/scripts/vpnmon-r2.sh"

Also, @Kal1975, I've included your idea about screen, and checking if one is running, and asking if you want to connect to it, instead of starting another. Let me know if are able to give this a try. ;)
 
Last edited:
I have v2.01rc (Release Candidate) available for you to try @Stephen Harrington ... @JAX1337 seems to be having decent luck with it I believe:
@Viktor Jaep deep apologies but testing this means quite a bit of “outage” time I can’t quite organise right now with WFH and normal family activity. But @JAX1337 appears to be doing a sterling job, thanks to you both.

My 4G USB dongle has previously just been sitting there unplugged as a (very cold) standby “in case” and the couple of times I’ve had to use it I’ve just plugged it in and manually switched over the WAN setting, as consensus was the Asus dual-WAN is pretty broken. The @Ranger802004 dual-WAN script got me interested in making this a bit more “automatic”, but not sure I can live without daily VPNMON-R2 functionality now so that’s what I’ve “run away” back to, pending more time to play with the dual-WAN which possibly won’t happen until next week sometime.
 
Last edited:
@Viktor Jaep deep apologies but testing this means quite a bit of “outage” time I can’t quite organise right now with WFH and normal family activity. But @JAX1337 appears to be doing a sterling job, thanks to you both.

My 4G USB dongle has previously just been sitting there unplugged as a (very cold) standby “in case” and the couple of times I’ve had to use it I’ve just plugged it in and manually switched over the WAN setting, as consensus was the Asus dual-WAN is pretty broken. The @Ranger802004 dual-WAN script got me interested in making this a bit more “automatic”, but not sure I can live without daily VPNMON-R2 functionality now so that’s what I’ve “run away” back to, pending more time to play with the dual-WAN which possibly won’t happen until next week sometime.
No worries, @Stephen Harrington! I can completely understand. ;) Just reach out if you see anything wonky! Lol!
 
Hi @Viktor Jaep, last night I had to sleep early

Sorry to see that we had to abandon the previous thread.

About the script, all seems well except the fact that in the initial 4-5 Wan Checks, the script takes considerable time going through WAN 1 eth0. Later on, it goes through it as it's supposed to.
 
Last edited:
After reboot, stuck here even after 2 mins

1657706677083.png

FTR i didn't initiate the reset

Wan 1 working fine, while wan0 is down due to a fiber cut

1657706753210.png
 
Primary Wan just got fixed, and Dual Monitor script did its Job, but Vpnmon still hasn't recovered

1657711235331.png


Even after reboot the script was stuck at the above screen, tried a manual command line reset, and it started working
Don't know how it works, if reboot also doesn't have any effect.
 
Last edited:
Nope, nothing like that there
Sorry... Not in front of my PC at the moment... Delete this:

LOCKFILE="/jffs/scripts/VPNMON-R2-Lock.txt
 

Attachments

  • SmartSelect_20220713-175100_JuiceSSH.jpg
    SmartSelect_20220713-175100_JuiceSSH.jpg
    65.4 KB · Views: 108
My attempt at replying in the other thread:

You guys have some great ping times. Here's mine in Costa Rica:
1657720104024.png

I leave Costa Rica Saturday and probably won't be very active on the site until I get somewhere I can use my router again. That's probably not until mid-October. I'm looking forward to seeing what else develops here during that time.
 
Even after reboot the script was stuck at the above screen, tried a manual command line reset, and it started working
Don't know how it works, if reboot also doesn't have any effect.
So I'm guessing you may have tried a manual reset while you were experiencing issues, and then possibly killed the script during the period of time when it was struggling or locked up on that NC command. I think during that time, a lockfile was generated, but it didn't get cleared. The only time a lockfile is generated is if the -reset switch is used. So then when the script was restarted, it got stuck in that loop where it thought a reset was happening because it saw that lockfile, but in actuality, nothing was happening. Then, when you ran that -reset again, it completed, and deleted the lockfile, so vpnmon-r2 would continue.

I've built a few more checks to clear the lockfile on startup, and added another layer of timeout capabilities on the NC command that should let it bypass any error after 60 seconds so it can keep trying again to make a connection. The NC command only uses whatever the primary connection is... so if the router switches from WAN0 to WAN1, NC should follow along.

In the interim, RC was renamed to beta 4, so here's the latest beta v2.01b5 with some of the latest fixes:
Code:
curl --retry 3 "https://raw.githubusercontent.com/ViktorJp/VPNMON-R2/master/vpnmon-r2-2.01b5.sh" -o "/jffs/scripts/vpnmon-r2.sh" && chmod a+rx "/jffs/scripts/vpnmon-r2.sh"

Also... as luck has it, I've been able to (temporarily) acquire a wired USB wifi hotspot, and will hopefully be able to test dual wan/failover/loadbalancing/etc and ensure that vpnmon-r2 can handle these different scenarios. Probably won't be able to start on this until Saturday though.
 
My attempt at replying in the other thread:

You guys have some great ping times. Here's mine in Costa Rica:

I leave Costa Rica Saturday and probably won't be very active on the site until I get somewhere I can use my router again. That's probably not until mid-October. I'm looking forward to seeing what else develops here during that time.
Not bad, @iTyPsIDg! Good luck, and see you in October! :)
 
Also... as luck has it, I've been able to (temporarily) acquire a wired USB wifi hotspot, and will hopefully be able to test dual wan/failover/loadbalancing/etc and ensure that vpnmon-r2 can handle these different scenarios. Probably won't be able to start on this until Saturday though.
That would be great. Nothing like experiencing it first hand.
So I'm guessing you may have tried a manual reset while you were experiencing issues,

I didn't do a manual reset, the script itself does this and shows the following message

1657724595151.png



Will try v2.01b5
 
Similar threads
Thread starter Title Forum Replies Date
Ripshod (Not specifically) VPNMON-R3 1.11 failure domino effect Asuswrt-Merlin AddOns 20

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