OpenWrt is a Linux distribution for embedded devices. That means OpenWRT runs fine on machines with low CPU, RAM and ROM. OpenWRT can be configured to run anything you want on your embedded device, but its mostly used in router projects. I first tried OpenWRT on a NSLU2, but I changed to a more powerful machine, since the NSLU2 was too slow. In the following, I’ll describe the steps how to setup OpenWRT for a RouterStation Pro running OpenVPN, CUPS, Asterisk, UPNP, and DynDNS.
The NSLU2 has 8MB ROM and 32MB RAM inside. The CPU is an Intel IXP420, which is based on a ARM and runs at 266MHz.
The first step is to get the OpenWRT firmware for it here. Then follow these steps
1. Power off NSLU2.
1. Hold the reset button (the button is behind the small hole in the back of the case.)
1. Press and release the power button to turn the slug on (while still holding the reset button on.)
1. Wait about 10 seconds until the ready/status LED turns from amber to red, immediately release the reset button.
Then plug your LAN cable into the port and upload the image. Make sure both devices are on layer 2. Type the command upslug2 -i openwrt-nslu2-squashfs.bin as root. This should flash your device. The next thing I wanted to do was to add a MCS7830 USB Ethernet
adapter. In order to do so, additional kernel modules need to be installed with opkg:
This brought up a second interface. However, this link was highly unstable and I lost half of the ping packets. Since I also had issues with USB disk storage recently, I’m not using NSLU2 anymore. Besides, the CPU is too slow to access disk at full 100Mbs rate. The best I got was around 5MB/s for NFS, while the maximum should be at around 10MB/s (NSLU2 performance).
This device has more RAM (128MB RAM) and more ROM space (16MB Flash) than NSLU2 and it has a much better CPU (ARM 720MHz). This makes it more suitable for running other/more services than with the NSLU2.
The firmware for the RouterStation can be downloaded here. There are two choices, an image based on squashfs and an image based on jffs2. The advantage of jffs2 is that you can remove packets that you don’t use, since its a read-write filesystem. You cannot do this with squashfs, since this is a read-only filesystem. However, the package selection of squashfs is very good and most likely you’ll need most of them, so go for the the squashfs, unless you want to remove many packages.
To flash you have to boot the system in recovery mode by holding the reset button for a few seconds while powering on the device. If you have a serial cable, you’ll see:
RESET button pressed, starting rescue mode...
TFTPD initialized on 192.168.1.20/255.255.255.0 port: 69 (Memory: [0x8006e000-0x87fe1000])
TFTPD: waiting for connection...
Next, upload the firmware using the WAN port with TFTP.
tftp 192.168.1.20
tftp> binary
tftp> put openwrt-ar71xx-ubnt-rspro-squashfs-factory.bin
If you are interested in a bleeding edge version, you can download a snapshot or compiling your own OpenWRT. If you compile your own version, it is recommended to attach a serial cable to see the console output. Connect the cable, type minicom -D /dev/ttyUSB0 (or picocom -b 115200 /dev/ttyUSB0) with settings 115200 8N1 and you see what happens during booting.
To install a HP printer/scanner on OpenWRT, install hplip, sane-backends, sane-frontends, xinetd, libv4l. Do not install kmod-usb-printer, as hplip has its own drivers and hplip wont work if its installed. Find your product ID of your printer as explained in /etc/hotplug.d/usb/20-hplip to make sure the device has the right permissions. If you have an sdcard in your slot you may want to keep the history of printed documents. Change the lines in /etc/cups/cupsd.conf to:
set PreserveJobHistory Yes
PreserveJobFiles Yes
AutoPurgeJobs No
RequestRoot /mnt/sdcard/cups-spool
TempDir /mnt/sdcard/cups-tmp
I also removed RIPCache (memory cache used by Raster Image Processor) since the default 8MB seems reasonable for the RouterStation.
To finish the installation, add your printer in the CUPS Administration site, set a PPD (I have a HP3020).
The scanning part was a bit more difficult, but I have it up and running (it was easier than I tried back in 2010, since my patches have been applied). To run the scanning service as a daemon, you have to create a file /etc/xinit.d/saned with the content:
service sane-port
{
socket_type = stream
server = /usr/sbin/saned
protocol = tcp
user = root
group = root
wait = no
disable = no
}
Then, allow clients from the network to access this service, add in /etc/sane.d/saned.conf the line 192.168.1.0/24. Don’t forget on your clients to add the IP (192.168.1.1) of your router in /etc/sane.d/net.conf. Since hplip does not create the file /etc/sane.d/dll.d/hplip (see report), you have to create in manually:
mkdir /etc/sane.d/dll.d
cd /etc/sane.d/dll.d
echo "hpaio" > hplip
You also need to add saned 6566/tcp to /etc/services. If you see this error “getaddrinfo for local hostname failed: Name or service not known”, you have to add to /etc/hosts your hostname as it appears on your command line @root@OpenWrt:/#@ -> hostname is OpenWrt. Since sane uses quite some space, you may want to remove unneeded backends in /usr/lib/sane. I removed everything except libsane-dll and libsane-hpaio.
The RouterStation Pro is capable of running Asterisk with a couple of users. I was looking at different alternatives such as FreeSwitch, but I decided to go with Asterisk, since a recent version 1.8.4 is in the repositories. I also tried siproxd which ran fine, but I wanted to connect more (soft)phones that should be able to make outbound calls to my SIP provider (sipcall.ch). After installing with opkg install asterisk18 I had to install asterisk18-func-channel as well, since I saw a warning in the log files (ERROR[7182]: pbx.c:3572 ast_func_write: Function MASTER_CHANNEL not registered). Furthermore I added add [ -d /var/lib/asterisk ] || mkdir -p /var/lib/asterisk to the file /etc/init.d/asterisk, since asterisk was complaining about it.
To make it work, I had to change sip.conf, extensions.conf, and rtp.conf. In rtp.conf I just narrowed the ports to 7070-7089 and added a firewall rule to allow incoming data on these ports. In sip.conf I added
register => ##username##:##password##@free2.voipgateway.org/sipcall
...
useragent=My PBX ; is requiered since sipcall blocks Asterisk user agent
...
[snom320]
type=friend
context=default
secret=##password##
callerid="##your-name-here##"
host=dynamic
username=##username##
dtmf=info
disallow=all
allow=g722,g726,ulaw,alaw
...
[sipcall-out]
type=friend
username=##username##
fromuser=##username##
host=free2.voipgateway.org
secret=##password##
insecure=invite
context=default
disallow=all
allow=g722,g726,ulaw,alaw
If you are not sure about the codes, go to Wikipedia. A nice to have feature is call recording. Unfortunately, app_mixmontior was not in the repositories, so recording calls is not possible. The dialplan looks as follows:
[general]
static=yes
[default]
include => incoming
include => outgoing
exten => i,1,Hangup
exten => t,1,Hangup
[incoming]
;exten => sipcall,1,Set(DYNAMIC_FEATURES=automon) ;; enable monitoring
exten => sipcall,1,Dial(SIP/snom320&SIP/android,40,Ttw)
exten => sipcall,2,Hangup
exten => 1,1,Dial(SIP/snom320,40,TtwW)
exten => 1,2,Hangup
exten => 3,1,Dial(SIP/android,40,Tt)
exten => 3,2,Hangup
[outgoing]
;exten => _[+0-9].,1,Set(DYNAMIC_FEATURES=automon) ;; enable monitoring ()
exten => _[+0-9].,1,Dial(SIP/${EXTEN}@sipcall-out,40,W)
exten => _[+0-9].,2,Hangup
A fun thing to do is to have your own ringtone. For the SNOM 320, the ringtone has to be in a special format and size. The n is important to specify the right size, since the wav may not be larger than 250KB. The following command converts an mp3 to a SNOM 320 compatible ringtone.
mpg123 -m -r 8000 -w - -n 600 -q Desktop/input.mp3 > output.wav
This is very easy and you just type opkg install luci-app-ddns and opkg install luci-app-upnp. Create and account with DynDNS and the setup is finished. The statistics can be installed with luci-app-statistics and will create an item in your OpenWRT web interface.
First, install opkg install luci-app-openvpn, which downloads all the necessary packages. This will create a new tab “OpenVPN” in “Services” containing three sample configurations. I removed them in /etc/config/openvpn and create two new ones. One UDP-based listening on the default port 1194 and one TCP-based fallback configuration listening on port 443, because some networks block everything that is not 80, 443, or 8080. This description provides a good starting point for making OpenVPN work without configuring iptables.
config 'openvpn' 'home_server'
option 'port' '1194'
option 'proto' 'udp'
option 'dev' 'tun'
option 'ca' '/etc/openvpn/ca.crt'
option 'cert' '/etc/openvpn/server.crt'
option 'key' '/etc/openvpn/server.key'
option 'dh' '/etc/openvpn/dh1024.pem'
option 'server' '10.77.0.0 255.255.255.0'
option 'ifconfig_pool_persist' '/tmp/ipp.txt'
option 'keepalive' '10 120'
option 'comp_lzo' '0'
option 'persist_key' '1'
option 'persist_tun' '1'
option 'status' '/tmp/openvpn-status.log'
option 'verb' '3'
option 'enable' '1'
option 'cipher' 'BF-CBC'
option 'auth' 'MD5'
list 'push' 'route 192.168.1.0 255.255.255.0'
list 'push' 'dhcp-option DNS 10.77.0.1'
config 'openvpn' 'home_server_failsafe'
option 'port' '443'
option 'proto' 'tcp'
option 'dev' 'tun'
option 'ca' '/etc/openvpn/ca.crt'
option 'cert' '/etc/openvpn/server.crt'
option 'key' '/etc/openvpn/server.key'
option 'dh' '/etc/openvpn/dh1024.pem'
option 'server' '10.78.0.0 255.255.255.0'
option 'ifconfig_pool_persist' '/tmp/ipp.txt'
option 'keepalive' '10 120'
option 'comp_lzo' '0'
option 'persist_key' '1'
option 'persist_tun' '1'
option 'status' '/tmp/openvpn-status.log'
option 'verb' '3'
option 'enable' '1'
option 'cipher' 'BF-CBC'
option 'auth' 'MD5'
list 'push' 'route 192.168.1.0 255.255.255.0'
list 'push' 'dhcp-option DNS 10.78.0.1'
The certificates are created with easy-rsa (opkg install openvpn-easy-rsa):
build-cabuild-dhbuild-key-server serverTo create the client certificates execute build-key-pkcs12 *putnamehere*. The only problem I had that the resulting .p12 files were not password protected. Just issue this command to password protect it: rm *putnamehere*.p12 and openssl pkcs12 -export -in *putnamehere*.crt -inkey *putnamehere*.key -certfile ca.crt -name "*putnamehere*" -out *putnamehere*.p12
Make sure you create two interface tun0 and tun1. Don’t bridge it and make sure you create a firewall zone. I named the zone tun0 and tun1 as well.
In the firewall setting, set tun0 and tun1 to accept Input, Output, and Forward. The zone forwarding from wan to tun0 and tun1 needs also be configured. Once setup restart OpenVPN /etc/init.d/openvpn restart. Allow port 443 and 1194 for incoming traffic on your WAN device. The next step is to configure the clients:
client
remote 192.168.1.1
pkcs12 client1.p12
cipher BF-CBC
auth MD5
dev tun
proto udp
nobind
auth-nocache
script-security 2
persist-key
persist-tun
user openvpn
group openvpn
This second configuration is for the fallback mode that uses TCP on port 443:
client
remote 192.168.1.1 443
pkcs12 client1.p12
cipher BF-CBC
auth MD5
dev tun
proto tcp
nobind
auth-nocache
script-security 2
persist-key
persist-tun
user openvpn
group openvpn
Encryption is CPU expensive and I did some (not scientific!) measurements to see how many VPN connection the RouterStation Pro can handle. Without VPN, I can saturate my complete bandwidth, that is 2.25MB/s. Using OpenVPN with default settings, the rate drops to max. ~1.7 MB/s and my CPU running nearly at 100%. To make this faster, you can change to a fastest cipher and auth. Use openssl speed to test various cipher and auth methods. I picked blowfish-128bit (BF-CBC, which is the default) and MD5, since they were faster than SHA1. I also disabled lzo compression and i got a maximum speed of 2.0-2.1MB/s. This means that my link is still faster than my OpenVPN encryption. The RouterStation Pro supports overclocking, and I decided to overclock it. Compile overclock_routerstation.c to overclock_routerstation-mips-rspro using the OpenWrt toolchain:
make menuconfig
make -j4 (depends on your number of processors)
cd staging_dir/toolchain-mips_r2_gcc-4.3.3+cs_uClibc-0.9.30.1/usr/bin
mips-openwrt-linux-gcc -o overclock_routerstation-mips-rspro overclock_routerstation.c
After overclocking with overclock_routerstation-mips-rspro 800, I get around 530 BogoMIPS instead 480 BogoMIPS with 720Mhz. With this speed I can saturate my link with 2.25MB/s, however, the CPU usage for OpenVPN is around 94-97%.
While installing OpenVPN, I was looking into the logfiles (logread -f) a lot. Many times, SSH brute-force attacks would also appear in the logfiles, making the logfiles difficult to read. So I decided to use something similar as sshguard to block those attacks. While sshguard reads the logfiles and detects many different kinds of attacks on services such as ssh, dovecot, UWimap, proftpd) and blocks the IPs if too many failed attempts were logged. However, I needed something more lightweight to block SSH brute force attacks on my router. I came across this site that uses iptables with ipt_recent to block SSH attacks. To use this install opkg install kmod-ipt-conntrack-extra. Put the following configuration as described here in /etc/firewall.user or using the Luci interface, go to Network -> Firewall -> Custom Rules.
This will block the attacker, if withing 300 seconds 4 ssh connection attempts have been made. After these 300 the attacker may connect again. The main difference between sshguard and ipt_recent is that ipt_recent does not distinguish between successful and failed logins. This means if you login and logout 4 times within 300 seconds. You will be blocked too:
WAN=eth0
iptables -t nat -A prerouting_rule -i $WAN -p tcp -m state --state NEW --dport 22 -m recent --set --name SSH_ATTACKER --rsource
iptables -A input_rule -i $WAN -p tcp -m state --state NEW --dport 22 -m recent --update --seconds 300 --hitcount 4 --name SSH_ATTACKER --rsource -j DROP
--Thomas Bocek