Restarting a Netgear Modem.
By Gerry Patterson
In an earlier article, I presented a simple method of restarting a
Dynalink modem connected to my ISP's network.
This is no longer relevant, since churning to a new ISP.
This article looks at automatically restarting a Netgear modem connected
to my new ISP's network.
Network Outages.
If you only use your Internet connection for getting access to the Internet, a network outage is no big deal. Depending on the quality of your connection, network outages may not occur frequently. Since many Internet users turn off their modem and their computer when it is not in use, it is not usually a problem for the average user if an outage does occur while online. The problem will usually rectify itself after a little while, and it may be necessary to reset the modem.
However for a small business, using the connection to provide a website, the outage means that the site is not available. Sometimes it can take a long time for the connection to be re-established. Often it is necessary to give the process a kick start, by re-setting the modem. If the domain hosts a website, it needs to be available 24 by 7.
If you chose Unix as your Operating System, it is fairly easy to create a script that restarts the modem. In a previous article, I described how to use the shell and expect to reboot a Dynalink modem. What follows, below, is a description of the method I used to restart a Netgear modem connected to (my new ISP) Netspace's network. The reason I churned is outlined in another article written this month (See the bibliography).
Netspace provide a Netgear modem, which obtains an address by DHCP. For customers who require a static IP, they have kludged the modem to always return the same IP address. Presumably there is a lookup table of IP addresses that Netspace have made available for their SME accounts.
My firewall is an Ubuntu Linux machine with two ethernet cards, eth0
and eth2. These are configured as follows:
eth0 Link encap:Ethernet HWaddr 00:0D:61:1F:2C:6A inet addr:202.45.111.200 Bcast:1.2.3.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 eth2 Link encap:Ethernet HWaddr 00:19:E0:0C:DD:6C inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 |
I use a custom modified version of rc.firewall-iptables-stronger version 0.88, which has been saved in the location /etc/init.d/rc.firewall. The rc.firewall script uses the ifconfig command to detect the address of the external interface, which is specified in the $EXTIF variable (set to eth0 in the script).
When the Netgear modem is started with the default settings (as shipped by Netspace), it starts up with a local address of 192.168.0.1. The network then configures eth0 to the public address. I have allowed telnet traffic for 192.168.0.1 only through eth0. All other private communication via eth0 are banned (anti-spoofing measure).
If the connection to Netspace is lost however, the Netgear modem loses its' public addresses. In this state communication can only be established via the default private network. However, since my external interface is broadcasting on the public address, the 192.168.0/24 network is unreachable via that interface. In this situation the restart script reconfigures eth0 to the address 192.168.0.2 connects to the modem via telnet and reboots it. Then after waiting 5 minutes, it reconfigures eth0 back to the public address and calls the /etc/init.d/rc.firewall script again.
This usually does the trick. If it doesn't than it tries again.
Sometimes when there is a network problem, the public address is not lost, but there is some difficulty reaching the Internet. In this case the modem is restarted from the public address (without reconfiguring eth0).
One additional problem needs to be addressed. The SMTP server is running on the firewall. When the network is re-established, the postfix resolver config file is over-written. After which postfix will attempt to use 192.168.1.1 for DNS queries. The config file is at /var/spool/postfix/etc/resolv.conf. The script checks the date of this file. If it is less than thirty minutes old, it checks that it is configured for one of the Netspace Domain Name Servers. If it isn't than it re-writes the config file and restarts postfix.
Get Acquainted With Your Modem.
Although it is possible to configure your modem with a browser (provided of course you have a route to it), most scripts depend on telnet. It might be possible to configure the modem with cURL via the HTTP interface, but this would be a lot of work, and you'd have to be cURL enthusiast to consider it.
Most of the support staff at Netspace are only familiar with the HTTP interface. However all of these functions can be performed with telnet. Since there does not appear to be any documentation on this, you can find out yourself.
Telnet to the modem and enter the command "help". There are a bunch of familiar Unix commands which can help you with diagnosis, trouble shooting, configuration and automation.
Here is a sample of brief telnet session with my modem.
$ telnet 192.168.0.1 Trying 192.168.0.1... Connected to 192.168.0.1. Escape character is '^]'. Netgear DM111 ADSL2+ Modem Software Version: 3.29z Login name: user Password: > dns show Primary 210.15.254.240 Secondary 210.15.254.241 > route show Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 202.45.111.200 * 255.255.255.255 UH 0 0 0 br0 203.17.101.67 * 255.255.255.255 UH 1 0 0 ppp_8_35_1 192.168.0.0 * 255.255.255.0 U 0 0 0 br0 default 203.17.101.67 0.0.0.0 UG 0 0 0 ppp_8_35_1 > logout Bye bye. Have a nice day!!! Connection closed by foreign host. |
You will have to supply your own user/password (depending on how you have setup the modem).
Netgear runs a Linux kernel. The commands appear to have been modified for the Netgear environment, but most of them behave similarly to the corresponding commands in the standard Linux distributions.
In most cases you can find out more by entering a command followed by --help.
Restart Scripts.
The bash restart script is shown below. It is installed in the folder /root/crontab.
This script contains the following dummy values:
- P1.P2.P3.P4 The public address assigned by your ISP. In my case this is the address 202.45.111.200, which Netspace supplied.
- D1.D2.D3.D40 The primary DNS (supplied by your ISP).
- D1.D2.D3.D41 The secondary DNS (supplied by your ISP).
- dsl-XXX-XXX- A search string used to confirm that the default route exists. For my site this is dsl-202-45-111-. To find out what the value is for your site enter the "route command" and look at the line marked "default".
It will be necessary to write your own regular expression to verify that postfix is using one of the public DNS servers. If your two DNS addresses end in 0 and 1, then you can just substitute the appropriate values for D1.D2.D3.D4 (just add the "0" or "1" to get the DNS address).
Since I didn't have time to go through all the rules in the rc.firewall script, I took a copy of it, modified it, and stored it in /root/crontab/firewall_reset. This has the necessary modifications to reconfigure eth0 to use the address 192.168.1.2 and talk to the modem on the telnet port.
The bash script also use the following perl one-liner to check the date/time of files:
perl -e "exit 1 if ((-M '/foo/bar') > 0.02083)"
If the file /foo/bar exists and is more than thirty minutes old this
command returns "1". Otherwise it returns "0".
#!/bin/bash export PATH=/sbin:$PATH LOCKFILE=/root/crontab/reboot_modem.lock MODEM=192.168.0.1 # local ip addr of modem EXTIP=P1.P2.P3.P4 # public ip addr of eth0 DNS=D1.D2.D3.D41 # netspace secondary DNS # check for lockfile ... exit if it exists and is current if [ -f $LOCKFILE ] ; then # is the LOCKFILE more than thirty minutes old? perl -e "exit 1 if ((-M '$LOCKFILE') > 0.02083)" if [ $? -eq 1 ] ; then echo removing stale lockfile: $LOCKFILE rm -f $LOCKFILE else echo lockfile: $LOCKFILE exists -- $0 waiting for modem reboot. exit 0 fi fi # # Do anything else that needs to be done -- I check the status of mailboxes for the Webmail Interface4 # # Make sure that this something is also network related -- i.e. dependant on active Internet connection. /usr/local/bin/blah.blah something foo bar # # ping a DNS, use primary for odd hour, secondary for even. # date +%H | awk '{exit ($1 % 2)}' if [ $? -eq 1 ] ; then # on odd hours, use netspace primary DNS DNS=D1.D2.D3.D40 fi ping -qc 1 $DNS > /dev/null 2>&1 if [ $? -ne 0 ] ; then # # ping failed, reboot the modem, first create the lockfile # date > $LOCKFILE # sometimes the modem/router loses its' public address ping -qc 1 $MODEM > /dev/null 2>&1 if [ $? -ne 0 ] ; then # force eth0 to the same subnet as the modem LAN /root/crontab/firewall_reset # call the expect script which reboots the modem /root/crontab/reboot_modem # wait at least one 5 minute interval (reboot script has a 40 second sleep) sleep 260 # call the default firewall script to reconfigure eth0 /etc/init.d/rc.firewall else /root/crontab/reboot_modem # wait at least one 5 minute interval sleep 260 # check to see if the default route is missing # NB: You will have to modify this regular expression ... /sbin/route | grep '^default' |awk '{if ($2~/^dsl-XXX-XXX-/) exit(1)}' if [ $? -ne 1 ] ; then echo attempting to add default route /sbin/route delete default /sbin/route add default gw $EXTIP fi fi rm -f $LOCKFILE else # check the date on the postfix resolv.conf -- is it less than 30 min old? perl -e "exit 1 if ((-M '/var/spool/postfix/etc/resolv.conf') < 0.02083)" if [ $? -eq 1 ] ; then # postfix has its' own resolver POSTRESOLV=/var/spool/postfix/etc/resolv.conf # check that it is a netspace primary or secondary DNS # NB: You will have to modify this regular expression ... grep '^nameserver' $POSTRESOLV | awk '{if ($2~/D1.D2.D3.D4[01]/) exit(1)}' if [ $? -ne 1 ] ; then echo setting postfix nameserver: $DNS # re-write the config file and restart postfix echo "search home" > $POSTRESOLV echo "nameserver $DNS" >> $POSTRESOLV /etc/init.d/postfix restart fi fi fi |
This script should be scheduled to run every 5 minutes with root's crontab. You would not want it to run more regularly than this, because of the timing of the various events. If the modem needs to be rebooted an email will be sent to root (because output sent to STDOUT or STDIN from a cron job is usually emailed to the job owner). If you have setup your machine to redirect root's email, then the email will be redirected. If a modem reboot is initiated, a lockfile is written. This locks the process and prevents crontab initiating another reboot while one is in progress.
The script calls an expect script to send the reboot command to the modem. For more details on how to install and configure expect, see the bibliography.
In Ubuntu you can install the expect processor with:
sudo apt-get install expect
The expect script is shown below:
#!/usr/bin/expect # reboot the Netgear DM111 ADSL2+ Modem # set modem "192.168.0.1" set login "user" set passwd "password" eval spawn telnet "$modem" expect "Login name:" {send "$login\r"} expect "Password:" {send "$passwd\r"} expect ">" {send "reboot\r"} sleep 40 send "\r" |
BIBLIOGRAPHY:
The following are some links which may be useful.
rc.firewall-iptables-stronger. At the time of writing this was the location of rc.firewall-iptables-stronger version 0.88. |
|
Australian ISPs Race To the Bottom. Where I describe the truly dreadful behaviour of my previous ISP. This was the reason I churned. |
|
Great Expectations. Where I describe a technique of restarting a Dynalink modem. |