Saturday, February 17, 2007

Auto WOL on DD-WRT on Linksys WRT54GL

I am running a webserver on my desktop, to host a website from home. One of the problems I faced, is that I have to now leave my desktop "on" all the time. Between the higher electricity bill and depreciation on the desktop, I wondered if I was saving much hosting from home.

So when I bought the Linksys WRT54GL and installed DD-WRT on it recently, I thought I would try to set it up to wake up the computer on a Port 80 (http) access if it was in "sleep" mode.

For DD-WRT and Linksys routers, see http://www.dd-wrt.com/

DD-WRT allows you to write shell scripts on the router and I thought I would use this facility and use the builtin commands. Ideally I would want a trigger on a port 80 access on the router, but this might be a little inefficient since it would happen on every port 80 access and I could not find a way to trigger a script in DD-WRT.

So I thought instead that I would parse the syslog to detect port 80 activity. I could then control things like how often I check for activity etc. Here is the script I came up with

#!/bin/sh

INTERVAL=5
NUMP=3
OLD=""
WOL=/usr/sbin/wol
TARGET=192.168.1.100
MAC=00:00:00:00:00:00
logfile="/tmp/www/wol.log"

while sleep $INTERVAL
do
NEW=`cat /var/log/messages | grep ACCEPT | grep "DST=$TARGET" | grep "DPT=80" | tail -1 | awk '{print $3}'`
SRC=`cat /var/log/messages | grep ACCEPT | grep "DST=$TARGET" | grep "DPT=80" | tail -1 | awk '{print $10}' | sed -e "s/SRC=//g"`
LINE=`cat /var/log/messages | grep ACCEPT | grep "DST=$TARGET" | grep "DPT=80" | tail -1 `
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
echo "$SRC $LINE" >> $logfile
RET=`ping -c $NUMP $TARGET 2> /dev/null | awk '/packets received/ {print $4}'`
if [ "$RET" -ne "$NUMP" ]; then
echo "$SRC causes WOL at" `date` >> $logfile
$WOL -i 192.168.1.255 -p 7 $MAC >> $logfile
sleep 5
fi
OLD=$NEW
fi
done


TARGET is the LAN IP of your webserving machine, and MAC is its MAC Address. INTERVAL is how often you want to check for a transaction. To get the syslog in /var/log/messages, enable syslogd in DD-WRT with an empty field for IP address. I also had to set the log level to High and at least log all ACCEPT s in the log settings.

I create a logfile in /tmp/www to debug the script, the logfile references can be deleted if you want to make the script smaller to fit in nvram. The script does not send a WOL if the webserving machine is not in "sleep" mode. I use the built in WOL command on DD-WRT.

For more on DD-WRT scripts check http://www.dd-wrt.com/wiki/index.php/Index:Scripting

There is a lag now, when the computer is asleep to access a page on the computer. However I find that in most cases, the browser timeout is long enough to wake the computer up and deliver the webpage.

Comments and improvement suggestions are welcome.

19 comments:

Daniel said...

How do I enable logsysd?
I'm trying your script with my Media Center PC, so that when I turn my Media Center Extender on, it will wake up the PC...

CB said...

To enable syslogd on the dd-wrt, go to Administration->Service, enable syslogd on that page and leave the "remote server" field empty.
Also in Administration-> Log enable the log with Log Level = "High" and in the Options, turn "Accepted" = "On".

Hope this helps,
-cb

s2s2 said...

I tried your script: it doesn't work (for me).
I'm running a March 2007 beta of v24 6107M.
Wonder if something changed?
I put your script at http://www.dd-wrt.com/wiki/index.php/Useful_Scripts#Web_Server_Wake-Up

s2s2 said...

linked to the wiki page

CB said...

s2s2 ...

Do you see the accepted messages in /var/log/messages ?

How about the scripts output in /tmp/www/wol.log . Do you see the script trying to wake the machine up?

-cb

s2s2 said...

I'll check.

s2s2 said...

Ah, okay. I am using HTTPS !
Since the web traffic is encrypted, does the script need to be modified to look for different connection activity in the log?

I -can- get the desktop webserver to wake up, using the GUI Web interface of DD-WRT, WOL is not a problem.

s2s2 said...

okay, scratch that.

I see the log file just logs basic TCPIP connectivity, nothing higher level. IP from, to, port, etc.

Though, doing as you've said, and having a friend connect from outside the subnet, nothing ends up in the log. When I use the Web GUI, nothing ends up in the Incoming Log. The Outgoing Log is full of activity, though.

I have log level set high, Accept Enabled, and syslogd enabled.

Weird.

s2s2 said...

Got it. I think.

V24RC4, the current version at writing, is also on my router. The logging function is really broken, which is the reason why nothing incoming is going into the Incoming section on the GUI, or /tmp/var/log in the command line.

Other people are having problems with logging. Bugtracker: http://www.dd-wrt.com/dd-wrtv2/bugtracker/view.php?id=2567

What revision of the router firmware are you using?

CB said...

I am using v23sp2.

Dr. Ongo said...

Yuk, never use cat and grep together, it is pointless. See streamlined script here: DD-WRT Wiki. This uses two instead of up to seven(!) processes per line.

Anders said...

Where did you place the script?

PasKa said...

I've enabled syslog from Services->Service. I save settings and go to Administration and there is no tab "Log". Why could that be?

CB said...

@DrOngo

Thanks for the improvements.

@Anders

The script is in the DDWRT useful scripts section currently at
http://www.dd-wrt.com/wiki/index.php/Useful_Scripts#Web_Server_Wake-up

@PasKa

On v24-sp2 I see it on the Security Page, Firewall Tab, Log management. Enable log, and a few more options show up.

-cb

Photocider said...

Thanks for this info - could be really useful for me. I'm trying to figure out if I can serve a simple web page on my router which I can give to my users for my server so they can go to this web page as a 'portal' for the server. This web page will consist of a button of link which they click which will run the WOL command, then wait a few seconds, then redirect them to the server log in page.

I'm pretty sure all of this is possible with DD-WRT and the work you have done here.

Photocider said...

Any ideas for how can do this please do email me: sam.manley@gmail.com

Photocider said...

Just to say I have started a thread over at DD WRT trying to achieve my aim: http://www.dd-wrt.com/phpBB2/viewtopic.php?p=558964&sid=778fd813f177a22099ea1812371611a2#558964

CB said...

@PhotoCider

It might be difficult to install a webserver on the router, and maybe insecure too.

It might be easier to host that startup page elsewhere on one of the free hosting sites, and have the startmyserver button/link access a url, say /startserver. With some javascript you can probably wait and redirect the page.

Then modify the script on the router to check for that url in the log and do a wol only if it sees a "startserver" url.

Vikram Chauhan said...

Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog post.


linksys