copyright 1998-2018 by Mark Verboom
ipv6 ready RSS Feed Schakel naar Nederlands

Go back to What's new

Cheap remote server control

To blog index

Thursday, 15 April, 2010

Cheap remote server control

There have been multiple occasions that something happened to my server at home (usually to the internet connectivity) and I couldn't do anything remote anymore. An extra phoneline just to get to the console is a bit expensive for a home situation. Although my current solution is not good as a remote console, it does give you the option to run commands remotely through sms.

To start with, I bought a Huawei USB (E160G) stick through Ebay. Doesn't cost much, especially when they come from China. Keep in mind some of them can be simlocked. Not a real big problem, you can get them unlocked yourself, but it will cost extra.

Next I bought a cheap prepaid SIM from Vodafone. They're usually pretty cheap, a few euro's. Sending sms's is something like 9ct's per SMS, and you usually get some extra credits when registering the card on the Vodafone website :). Of course any other provider will do.

When inserting the dongle into the computer you get 3 devices:

[801842.408535] usb 1-1: new high speed USB device using ehci_hcd and address 28
[801842.555117] usb 1-1: New USB device found, idVendor=12d1, idProduct=1001
[801842.555143] usb 1-1: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[801842.555174] usb 1-1: Product: HUAWEI Mobile
[801842.555192] usb 1-1: Manufacturer: HUAWEI Technology
[801842.560261] option 1-1:1.0: GSM modem (1-port) converter detected
[801842.560530] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB1
[801842.564105] option 1-1:1.1: GSM modem (1-port) converter detected
[801842.564320] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB2
[801842.565194] option 1-1:1.2: GSM modem (1-port) converter detected
[801842.565403] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB3

Depending on which other USB tty's are present, the numbering can change. So I added rules to udev to make sure I can reference the Huawei on the same devices names. I added the following lines to /etc/udev/rules.d/local.rules:

SUBSYSTEM=="tty", SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="00", NAME="huawei0"
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="01", NAME="huawei1"
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="02", NAME="huawei2"

Next, I installed smstools on my server.

apt-get install smstools

Configuration is done through /etc/smsd.conf. After some testing, this setup seems to work nicely with my Huawei USB stick.

devices = huawei
outgoing = /var/spool/sms/outgoing
checked = /var/spool/sms/checked
incoming = /var/spool/sms/incoming
logfile = /var/log/smsd.log
infofile = /var/run/smstools/smsd.working
pidfile = /var/run/smstools/smsd.pid
sent = /var/spool/sms/sent
stats = /var/log/smstools/smsd_stats
loglevel = 5
receive_before_send = no
autosplit = 3

[huawei]
init = AT+CPMS="MT","MT","MT"
device = /dev/huawei0
incoming = yes
pin = < pincode >
baudrate = 19200
eventhandler = /usr/local/bin/sms.sh
memory_start = 0
mode = new

The important bit in the configuration is the eventhandler. This hook gives you the option to process events from smsd. When an SMS is received, it can be processed by a script. I made a first initial version of the script to be able to run commands remotely. Currently authentication is a bit too open, but can easily be improved by adding an extra password or using a token. The current script looks like this.

#!/bin/bash
#
# Process sms events from sms tools
#
# 20100408 MV: Initial version migrating everyting into 1 script

AUTHGSM=< authorized GSM number, eg. 3112345678 >
EMAIL=< email address >
TMPFILE=/tmp/sms.$$
TMPSCRIPT=/tmp/sms.sh

action=$1
filename=$2
messageid=$3

source /etc/profile

case $action in
"RECEIVED")
if test "`grep \"^From: $AUTHGSM$\" $filename`" != ""
then
eval `cat $filename | awk 'BEGIN { found=0 }
{ if (found == 2 ) { printf("ARGUMENTS=\"%s\"\n",tolower($0)); found++ }
if (found == 1 ) { printf("CATEGORY=\"%s\"\n", tolower($0)); found++ } }
/^$/ { found=1; }'`

case $CATEGORY in
"cmd")
echo "To: $AUTHGSM" > $TMPFILE
echo >> $TMPFILE
echo "$ARGUMENTS" >> $TMPFILE
echo "#!/bin/bash" > $TMPSCRIPT
echo "source /etc/profile" >> $TMPSCRIPT
echo "$ARGUMENTS" >> $TMPSCRIPT
chmod 755 $TMPSCRIPT
sudo $TMPSCRIPT >> $TMPFILE 2>&1
rm -f $TMPSCRIPT
#( eval "source /etc/profile ; $ARGUMENTS" ) >> $TMPFILE 2>&1
mv $TMPFILE /var/spool/sms/outgoing
;;
esac
fi
mail -s "Incoming sms" $EMAIL < $filename
;;
"SENT")
mail -s "Outgoing sms" $EMAIL < $filename
;;
"FAILED")
mail -s "Failed sms" $EMAIL < $filename
;;
"REPORT")
mail -s "Report sms" $EMAIL < $filename
;;
esac

For all events an email is sent to the defined email address, so when something happens you automatically get an email.

When an SMS is received from the mobile number defined in AUTHGSM, the message is inspected for a command. If the first line of the message is the word "cmd", the next line is interpreted as the command that needs to be run. The command is put in a shellscript and exectued as root through sudo. If you don't feel comfortable doing this, or it isn't nessacary you can remove the sudo part. Adding a password or other authentication is relativly simple, just add an extra option to the case.

So a practical example looks like this. Send the following sms:

The SMS is recieved and processed:

2010-04-08 10:41:04,5, huawei: SMS received, From: 316xxxxxxxx
2010-04-08 10:41:06,5, smsd: Moved file /var/spool/sms/outgoing/sms.10607 to /var/spool/sms/checked
2010-04-08 10:41:13,5, huawei: SMS sent, Message_id: 28, To: 31xxxxxxxx, sendin

As you can see a reply SMS is sent back to the same number. And the content looks like:

As you can see the first line of the SMS had the executed command repeated. This takes op some room in the SMS, so it can also be removed.

For added robustness I added smstools the my monit configuration. A usefull way to check if smstools is still functioning seems to be to check the file:

/var/log/smstools/smsd_stats/status

It is continuously updated by smstools. I added the following to my monit configuration:

check file status with path /var/log/smstools/smsd_stats/status
if timestamp > 2 minutes then exec "/etc/init.d/smstools force-reload"

So if there have been no updates for 2 minutes, smstools gets restarted.