OpenWRT
From Ggl's wiki
Contents
|
Why using OpenWRT?
Because it's free (as in free speech), fun and open. I can implement quite everything I want with it. I have two Linksys WRT54GL routers. I have also a Fonera. I don't want to mess my home network with the WAN port of the Fonera because I don't entirely trust Fon (who does ??). Consequently with OpenWRT, I can break the default bridge that is configured on the ethernet swith and separate the ports in VLANs. The Fonera will be in a kind of own DMZ.
When I use a hotspot I want to be able to connect through a secure connection. I can install OpenVPN or another VPN server on my wrt and connect to it remotely. For mobile device, when I can't install VPN client I an provide a HTTPS proxy to access to sites that don't provide HTTPS access (yes there are some webmails and other services...).
OpenWRT Configuration with Kamikaze
Short Introductinon
Main WhiteRussian/Kamikaze differences
OpenWRT Configuration with WhiteRussian
WARNING! At the time I got my first WRT54GL, OpenWRT provided WhiteRussian as the stable release. The current release is a Kamikaze one, based on buildroot-ng. /etc/ is now writable and the configuration is not done anymore with nvram. I'll upgrade my routers very soon, so I'll write an up-to-date part of the OpenWRT configuration ;).
Introduction
This article doesn't aim to copy the very helpful documentation on OpenWRT Wiki but to share the configuration of my wrt.
I bought a Linksys WRT54GL which is a WRT54Gv4 with a linux based OS (v5 is VxWorks based). As I am a opensource enthousiast who believe in knowledge sharing and openness I decided to install openwrt on it. As the time I wrote this article the current release was White Russian RC5.
Installing OpenWRT firmware
So I take a SquashFS .bin file because I use the Linksys firmware upgrade procedure in the web interface. After the end of the upgrade, I have an OpenWRT router !
I plug a crossover (because it's a switch to switch link) rj45 on a lan port of the wrt and on my home switch. I telnet the default management IP :
$ telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
=== IMPORTANT ============================
Use 'passwd' to set your login password
this will disable telnet and enable SSH
------------------------------------------
BusyBox v1.00 (2006.03.27-00:00+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
WHITE RUSSIAN (RC5) -------------------------------
* 2 oz Vodka Mix the Vodka and Kahlua together
* 1 oz Kahlua over ice, then float the cream or
* 1/2oz cream milk on the top.
---------------------------------------------------
root@OpenWrt:/#
Change the root password to activate ssh access :
root@OpenWrt:/# passwd Changing password for root Enter the new password (minimum of 5 characters) Please use a combination of upper and lower case letters and numbers. Enter new password: Re-enter new password: Password changed. root@OpenWrt:/#
Like most of standard linux distro, configuration files are in /etc . But with the SquashFS image :
banner -> /rom/etc/banner dnsmasq.conf -> /rom/etc/dnsmasq.conf firewall.user -> /rom/etc/firewall.user unctions.sh -> /rom/etc/functions.sh group -> /rom/etc/group hosts -> /rom/etc/hosts inittab -> /rom/etc/inittab ipkg.conf -> /rom/etc/ipkg.conf modules -> /rom/etc/modules preinit -> /rom/etc/preinit profile -> /rom/etc/profile protocols -> /rom/etc/protocols resolv.conf -> /tmp/resolv.conf shells -> /rom/etc/shells sysctl.conf -> /rom/etc/sysctl.conf
Important files are symlinks to the /rom/ directory which is read-only as shows the mount command (it is also fully documented in the OpenWRT Wiki):
root@OpenWrt:/# mount /dev/root on /rom type squashfs (ro) none on /dev type devfs (rw) none on /rom/mnt type tmpfs (ro) none on /rom/mnt/proc type proc (rw) none on /tmp type tmpfs (rw,nosuid,nodev) none on /dev/pts type devpts (rw) /dev/mtdblock/4 on / type jffs2 (rw) none on /proc type proc (rw) root@OpenWrt:/#
When you need to edit a file, just remove it and copy the corresponding symlink instead.
/# cd /etc /etc# rm resolv.conf /etc# cp /rom/resolv.conf .
Network configuration
I don't want to have the wireless and the lan interfaces bridged. So I need to unset br0 interface. The OpenWRT wifi explains how the interfaces are set on a WRT54Gv4.
Thus :
- eth1 is the 802.11 interface
- vlan0 is the lan
- vlan1 is the wan
I wanted to isolate my FON routeur from the LAN. For this purpose I create a vlan2 interface :
- vlan2 is the fon
VLANs
The default configuration :
root@OpenWrt:~# nvram show | grep vlan size: 1624 bytes (31144 left) wan_device=vlan1 vlan0ports=3 2 1 0 5* lan_ifnames=vlan0 eth1 eth2 vlan1hwname=et0 vlan1ports=4 5 lan_ifname=vlan0 vlan0hwname=et0
The changes I made to have a dmz for fon :
root@OpenWrt:~# nvram set vlan0ports="2 1 0 5*" root@OpenWrt:~# nvram set vlan2ports="3 5" root@OpenWrt:~# nvram set vlan2hwname=et0
LAN Interface
By default eth1 (802.11 interface) and vlan0 are bridge in br0. I don't want to keep this bridge, thus i configure the vlan0 interface and removoe br0.
root@OpenWrt:~# nvram set lan_ifname=vlan0 root@OpenWrt:~# nvram set lan_ipaddr=192.168.1.1 root@OpenWrt:~# nvram set lan_netmask=255.255.255.0 root@OpenWrt:~# nvram set lan_proto=static root@OpenWrt:~# ifup lan
WAN Interface
If you use pppoe :
root@OpenWrt:~# nvram set wan_ifname=ppp0 root@OpenWrt:~# nvram set wan_proto=pppoe root@OpenWrt:~# nvram set ppp_idletime=10 root@OpenWrt:~# nvram set ppp_mtu=1492 root@OpenWrt:~# nvram set ppp_redialperiod=15 root@OpenWrt:~# nvram set ppp_username=<your_isp_account_login> root@OpenWrt:~# nvram set ppp_passwd=<your_isp_account_password> root@OpenWrt:~# nvram pppoe_ifname=vlan1
Don't forget to commit the changes in nvram :
root@OpenWrt:~# nvram commit root@OpenWrt:~# ifdown wan root@OpenWrt:~# ifup wan
FON Interface
Configure IP settings:
root@OpenWrt:~# nvram set fon_ifname=vlan2 root@OpenWrt:~# nvram set fon_proto=static root@OpenWrt:~# nvram set fon_ipaddr=192.168.3.1 root@OpenWrt:~# nvram set fon_netmask=255.255.255.0
Edit the /etc//init.d/S40network to enable the fon interface a startup:
root@OpenWrt:~# rm /etc/init.d/S40network root@OpenWrt:~# cp /rom/etc/init.d/S40network /etc/init.d/ root@OpenWrt:~# vim /etc/init.d/S40network root@OpenWrt:~# ifup fon
#!/bin/sh
case "$1" in
start|restart)
ifup lan
ifup fon
ifup wan
ifup wifi
wifi up
for route in $(nvram get static_route); do {
eval "set $(echo $route | sed 's/:/ /g')"
$DEBUG route add -net $1 netmask $2 gw $3 metric $4 dev $5
} done
;;
esac
Now the vlan2 interface is created and up:
root@OpenWrt:~# ifconfig vlan2
vlan2 Link encap:Ethernet HWaddr 00:16:B6:D9:9E:56
inet addr:192.168.3.1 Bcast:192.168.3.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Management Services
Removing useless services
What services are started by default?
root@OpenWrt:/# netstat -lut Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:80 *:* LISTEN tcp 0 0 *:53 *:* LISTEN tcp 0 0 *:22 *:* LISTEN tcp 0 0 *:23 *:* LISTEN netstat: no support for `AF INET6 (tcp)' on this system. udp 0 0 *:53 *:* udp 0 0 *:67 *:* netstat: no support for `AF INET6 (udp)' on this system.
hum, don't need http and telnet admin, neither dhcpd. Stop these services:
root@OpenWrt:/# killall httpd telnetd dnsmasq udhcpc
note: if udhcpc doesn'5 stop use killall -9 udhcpc
Ok, so let's check:
root@OpenWrt:/etc/init.d# netstat -lut Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:22 *:* LISTEN netstat: no support for `AF INET6 (tcp)' on this system. netstat: no support for `AF INET6 (udp)' on this system.
Well, that's fine only ssh server started.
I need to remove other services from init config files.
Disable dhcp server at startup. There are only dhcp related options in dnsmasq.conf, so just remove it (if you need it later the file is in /rom/etc/) :
root@OpenWrt:/etc# rm dnsmasq.conf
Start dnsmasq:
root@OpenWrt:~# /etc/init.d/S50dnsmasq start
Remove httpd and telnetd from init :
root@OpenWrt:/etc/init.d# rm S50httpd root@OpenWrt:/etc/init.d# rm S50telnet
I remove useless packages:
root@OpenWrt:/etc/init.d# ipkg remove webif haserl
Now only ssh and dns services are listening:
root@OpenWrt:~# netstat -lut Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:53 *:* LISTEN tcp 0 0 *:22 *:* LISTEN netstat: no support for `AF INET6 (tcp)' on this system. udp 0 0 *:53 *:* netstat: no support for `AF INET6 (udp)' on this system.
But they are binded on all ('*') IP addresses. No problem for dns, this could be the wanted behaviour. For ssh I want it to listen only on the lan interface IP. With OpenSSH I would add ListenAddress directive into /etc/ssh/sshd_config file, but actually the default ssh server is dropbear.
MaraDNS
I replace dnsmasq by a true dns server: maradns. So let's remove dnsmasq and install maradns:
root@OpenWrt:~# ipkg remove dnsmasq Removing package dnsmasq from root... Successfully terminated. root@OpenWrt:~# ipkg install maradns Installing maradns (1.0.26-1) to root... Downloading http://downloads.openwrt.org/whiterussian/packages/maradns_1.0.26-1_mipsel.ipk Installing libpthread (0.9.27-1) to root... Downloading http://downloads.openwrt.org/whiterussian/packages/libpthread_0.9.27-1_mipsel.ipk Configuring libpthread Configuring maradns Successfully terminated.
The default configuration looks like this:
root@OpenWrt:~# cat /etc/mararc
hide_disclaimer="YES"
chroot_dir="/etc/maradns"
bind_address="192.168.1.1"
maradns_uid=65534
maxprocs=10
random_seed_file="/dev/urandom"
recursive_acl="192.168.1.0/24"
root_servers={}
root_servers["."]="198.41.0.4,128.9.0.107,192.33.4.12,128.8.10.90,192.203.230.10,192.5.5.241,192.112.36.4,128.63.2.53,192.36.148.17,192.58.128.30,193.0.14.129,198.32.64.12,202.12.27.33"
I only add the line:
no_fingerprint=1
That's ok, start maradns:
root@OpenWrt:/etc# /etc/init.d/S60maradns root@OpenWrt:/etc# netstat -lu Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State udp 0 0 192.168.1.1:53 *:*
Well, maradns is listening on port 53/udp. Let's test dns resolving:
$ host -t A -v www.openwrt.org 192.168.1.1 Trying "www.openwrt.org" Using domain server: Name: 192.168.1.1 Address: 192.168.1.1#53 Aliases: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25497 ;; flags: qr; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.openwrt.org. IN A ;; ANSWER SECTION: www.openwrt.org. 604800 IN A 195.56.146.238 Received 49 bytes from 192.168.1.1#53 in 324 ms
note: 324 ms seems long (for example the same resolving takes about 40 ms on my local dns server) but the router is not yet directly connected to the Internet. I'll re-test later to see how much time it takes in better conditions.
It works. The recursive request was achieved successfully. Does the cache work ?
$ host -t A -v www.openwrt.org 192.168.1.1 Trying "www.openwrt.org" Using domain server: Name: 192.168.1.1 Address: 192.168.1.1#53 Aliases: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63309 ;; flags: qr; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.openwrt.org. IN A ;; ANSWER SECTION: www.openwrt.org. 604800 IN A 195.56.146.238 Received 49 bytes from 192.168.1.1#53 in 2 ms
maradns used its cached entry for the host which was resolved in 2 ms.
I re-wrote the init script that starts maradns as following:
#!/bin/sh
RUN_D=/var/run
PID_F=$RUN_D/maradns.pid
case $1 in
start)
[ -d $RUN_D ] || mkdir -p $RUN_D
[ -d /etc/maradns ] || mkdir -p /etc/maradns
/usr/sbin/maradns >/dev/null 2>&1 &
pidof maradns > $PID_F
;;
stop)
[ -f $PID_F ] && kill $(cat $PID_F) && rm $PID_F
;;
*)
echo "Usage: $0 (start|stop)"
exit 1
esac
exit $?
Using xinetd
xinetd installation
Install xinetd:
root@OpenWrt:/etc/init.d# ipkg install xinetd Installing xinetd (2.3.13-2) to root... Downloading http://downloads.openwrt.org/whiterussian/packages/xinetd_2.3.13-2_mipsel.ipk Configuring xinetd Successfully terminated.
By default the package installs an xinetd script in /etc/init.d . Rename it to /etc/init.d/S50xinetd and edit it:
#!/bin/sh DEFAULT=/etc/default/xinetd LOG_D=/var/log LOG_F=$LOG_D/xinetd.log RUN_D=/var/run PID_F=$RUN_D/xinetd.pid [ -f $DEFAULT ] && . $DEFAULT case $1 in start) [ -d $RUN_D ] || mkdir -p $RUN_D [ -d $LOG_D ] || mkdir -p $LOG_D xinetd $OPTIONS pidof xinetd > $PID_F ;; stop) [ -f $PID_F ] && kill $(cat $PID_F) && rm $PID_F ;; *) echo "usage: $0 (start|stop)" exit 1 esac exit $?
Acutally I just add theses lines, define the path where xinetd.log file is:
LOG_D=/var/log LOG_F=$LOG_D/xinetd.log
To be sure to have created the file:
[ -d $LOG_D ] || mkdir -p $LOG_D
Create pid file:
pidof xinetd > $PID_F
Add this line to /etc/default/xinetd (create the file if it's not present):
OPTIONS="-filelog /var/log/xinetd.log"
Dropbear with xinetd
So now I gonna create the file for dropbear. I create and edit /etc/xinetd.d/ssh:
service ssh
{
type = UNLISTED
socket_type = stream
bind = 192.168.1.1
port = 2222
only_from = <allowed_ips>
user = root
wait = no
instances = 5
per_source = 4
protocol = tcp
server =/usr/sbin/dropbear
server_args = -i
disable = no
log_type = FILE /var/log/xinetd.log
log_on_success = PID USERID HOST DURATION
log_on_failure = HOST
}
I choose to be restrictive to prevent configuration error, for example in my iptables rules. ssh access is on of the most exposed services. To continue, I create user keys to enable key authentication.
Maradns with xinetd
I'd like to try maradns with xinetd. I wrote the following /etc/xinetd.d/dns config file:
service dns
{
type = UNLISTED
id = dns
socket_type = dgram
bind = 192.168.1.1
port = 53
user = 65534
wait = no
instances = 20
per_source = 10
protocol = udp
server =/usr/sbin/maradns
disable = no
log_type = FILE /var/log/xinetd.log
log_on_success = PID USERID HOST DURATION
log_on_failure = HOST
}
Unfortunately, it doesn't work :( :
root@OpenWrt:~# cat /var/log/xinetd.log 00/1/2@06:14:56: START: dns pid=26073 from=192.168.1.10 00/1/2@06:14:56 xinetd[25867]: ERROR: file descriptor of service dns has been closed 00/1/2@06:14:56 xinetd[25867]: NOTICE: select reported EBADF but no bad file descriptors were found 00/1/2@06:14:57: EXIT: dns pid=26073 duration=1(sec)
After reading the documentation on Maradns official website, it appears that I should use version 1.2. What is my version ?
root@OpenWrt:~# maradns --version This is MaraDNS version 1.0.26 Compiled on a Linux system at Sun Mar 26 19:50:57 CEST 2006 For usage information, 'man maradns'
hmmmm, 1.0.26 ...
Probably the problem can be solved in version 1.0 but since this version is no longer supported as maradns main developer said: "Note: If you are using MaraDNS 1.0, and have a question about how to configure MaraDNS, please upgrade to MaraDNS 1.2.". I decided to take the opportunity to build a maradns v1.2.
Before I checked on ipkg.be to be sure that is no already available (MaraDNS) 1.2 package.
Building Maradns 1.2 package
Documentation on how to build package for OpenWRT is available on the wiki section OpenWrt building packages howto.
802.11 Configuration
I need to connect devices like PDA (windows mobile 2005), laptop (mainly linux ones, but from time to time Windows XP) and maybe ubiquitous devices (wireless video player, etc ...).
The main goal is security.
I believe the best choice is to follow 802.11i standard :
- 802.11x with EAP-TLS
- AES-CCMP encryption
This is also called WPA2 Entreprise.
To implement it I need :
- A radius server (freeradius will be fine)
- A basic PKI to issue AP and clients certs (openssl's CA scripts are ok)
- Supplicant on each client device
root@OpenWrt:~# nvram set wl0_mode=ap root@OpenWrt:~# nvram set wl0_ssid=SSID root@OpenWrt:~# nvram set wl0_infra=1 root@OpenWrt:~# nvram set wl0_closed=1 root@OpenWrt:~# nvram set wl0_channel=13 root@OpenWrt:~# nvram set wl0_macmode=allow root@OpenWrt:~# nvram set wl0_maclist="MAC1 ... MACn" root@OpenWrt:~# nvram set wl0_akm=psk root@OpenWrt:~# nvram set wl0_crypto=aes+tkip root@OpenWrt:~# nvram commit
Firewall configuration
Default configuration
Network and management services are done. Now I need to check the firewall rules.
First, let's check the /proc/sys/net options values:
root@OpenWrt:~# cat /etc/sysctl.conf kernel.panic=3 net.ipv4.conf.default.arp_ignore=1 net.ipv4.conf.all.arp_ignore=1 net.ipv4.ip_forward=1 net.ipv4.icmp_echo_ignore_broadcasts=1 net.ipv4.icmp_ignore_bogus_error_responses=1 net.ipv4.tcp_fin_timeout=30 net.ipv4.tcp_keepalive_time=120 net.ipv4.tcp_syncookies=1 net.ipv4.tcp_timestamps=0
hum, don't see other option like rp_filter=1 etc ... Let's check:
root@OpenWrt:~# for f in /proc/sys/net/ipv4/conf/all/*; do echo "$f = `cat $f`"; done /proc/sys/net/ipv4/conf/all/accept_redirects = 0 /proc/sys/net/ipv4/conf/all/accept_source_route = 0 /proc/sys/net/ipv4/conf/all/arp_announce = 0 /proc/sys/net/ipv4/conf/all/arp_filter = 0 /proc/sys/net/ipv4/conf/all/arp_ignore = 1 /proc/sys/net/ipv4/conf/all/bootp_relay = 0 /proc/sys/net/ipv4/conf/all/force_igmp_version = 0 /proc/sys/net/ipv4/conf/all/forwarding = 1 /proc/sys/net/ipv4/conf/all/log_martians = 0 /proc/sys/net/ipv4/conf/all/mc_forwarding = 0 /proc/sys/net/ipv4/conf/all/medium_id = 0 /proc/sys/net/ipv4/conf/all/proxy_arp = 0 /proc/sys/net/ipv4/conf/all/rp_filter = 0 /proc/sys/net/ipv4/conf/all/secure_redirects = 1 /proc/sys/net/ipv4/conf/all/send_redirects = 1 /proc/sys/net/ipv4/conf/all/shared_media = 1 /proc/sys/net/ipv4/conf/all/tag = 0
vlan0:
root@OpenWrt:~# for f in /proc/sys/net/ipv4/conf/vlan0/*; do echo "$f = `cat $f`"; done /proc/sys/net/ipv4/conf/vlan0/accept_redirects = 1 /proc/sys/net/ipv4/conf/vlan0/accept_source_route = 1 /proc/sys/net/ipv4/conf/vlan0/arp_announce = 0 /proc/sys/net/ipv4/conf/vlan0/arp_filter = 0 /proc/sys/net/ipv4/conf/vlan0/arp_ignore = 0 /proc/sys/net/ipv4/conf/vlan0/bootp_relay = 0 /proc/sys/net/ipv4/conf/vlan0/force_igmp_version = 0 /proc/sys/net/ipv4/conf/vlan0/forwarding = 1 /proc/sys/net/ipv4/conf/vlan0/log_martians = 0 /proc/sys/net/ipv4/conf/vlan0/mc_forwarding = 0 /proc/sys/net/ipv4/conf/vlan0/medium_id = 0 /proc/sys/net/ipv4/conf/vlan0/proxy_arp = 0 /proc/sys/net/ipv4/conf/vlan0/rp_filter = 0 /proc/sys/net/ipv4/conf/vlan0/secure_redirects = 1 /proc/sys/net/ipv4/conf/vlan0/send_redirects = 1 /proc/sys/net/ipv4/conf/vlan0/shared_media = 1 /proc/sys/net/ipv4/conf/vlan0/tag = 0
eth0:
root@OpenWrt:~# for f in /proc/sys/net/ipv4/conf/eth0/*; do echo "$f = `cat $f`"; done /proc/sys/net/ipv4/conf/eth0/accept_redirects = 1 /proc/sys/net/ipv4/conf/eth0/accept_source_route = 1 /proc/sys/net/ipv4/conf/eth0/arp_announce = 0 /proc/sys/net/ipv4/conf/eth0/arp_filter = 0 /proc/sys/net/ipv4/conf/eth0/arp_ignore = 0 /proc/sys/net/ipv4/conf/eth0/bootp_relay = 0 /proc/sys/net/ipv4/conf/eth0/force_igmp_version = 0 /proc/sys/net/ipv4/conf/eth0/forwarding = 1 /proc/sys/net/ipv4/conf/eth0/log_martians = 0 /proc/sys/net/ipv4/conf/eth0/mc_forwarding = 0 /proc/sys/net/ipv4/conf/eth0/medium_id = 0 /proc/sys/net/ipv4/conf/eth0/proxy_arp = 0 /proc/sys/net/ipv4/conf/eth0/rp_filter = 0 /proc/sys/net/ipv4/conf/eth0/secure_redirects = 1 /proc/sys/net/ipv4/conf/eth0/send_redirects = 1 /proc/sys/net/ipv4/conf/eth0/shared_media = 1 /proc/sys/net/ipv4/conf/eth0/tag = 0
iptables rules:
root@OpenWrt:/etc/init.d# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any any anywhere anywhere state INVALID
4350 292K ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
0 0 DROP tcp -- any any anywhere anywhere tcp option=!2 flags:SYN/SYN
49 9824 input_rule all -- any any anywhere anywhere
49 9824 ACCEPT all -- !ppp0 any anywhere anywhere
0 0 ACCEPT icmp -- any any anywhere anywhere
0 0 ACCEPT gre -- any any anywhere anywhere
0 0 REJECT tcp -- any any anywhere anywhere reject-with tcp-reset
0 0 REJECT all -- any any anywhere anywhere reject-with icmp-port-unreachable
Why having REJECT target ?? Probably to make port scanners job easier ;). hmmm, icmp and gre accepted are bad. Don't need icmp or at least icmp echo-request but not all the messages. I don't want to make xprobe2 or other icmp fingerprinters job easier.
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any any anywhere anywhere state INVALID
0 0 TCPMSS tcp -- any any anywhere anywhere tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
0 0 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
0 0 forwarding_rule all -- any any anywhere anywhere
0 0 ACCEPT all -- br0 br0 anywhere anywhere
0 0 ACCEPT all -- vlan0 ppp0 anywhere anywhere
Everyone from the lan (vlan0) can access everything on the Internet (ppp0). Not cool.
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any any anywhere anywhere state INVALID
3579 910K ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
0 0 output_rule all -- any any anywhere anywhere
0 0 ACCEPT all -- any any anywhere anywhere
0 0 REJECT tcp -- any any anywhere anywhere reject-with tcp-reset
0 0 REJECT all -- any any anywhere anywhere reject-with icmp-port-unreachable
hmmm, I dislike the 'ACCEPT all -- any any anywhere' rule. Why can the router send packet everywhere ? Same comment for REJECT target rules, they are useless and even harmful.
The next tables are defined to be customized in /etc/firewall.user. Another to had custom firewall rules is /etc/config/firewall. This one is parsed by /usr/lib/firewall.awk script.
Chain forward_ppp0 (1 references)
pkts bytes target prot opt in out source destination
Chain forwarding_rule (1 references)
pkts bytes target prot opt in out source destination
0 0 forward_ppp0 all -- ppp0 any anywhere anywhere
Chain input_ppp0 (1 references)
pkts bytes target prot opt in out source destination
Chain input_rule (1 references)
pkts bytes target prot opt in out source destination
0 0 input_ppp0 all -- ppp0 any anywhere anywhere
Chain output_rule (1 references)
pkts bytes target prot opt in out source destination
What need to be patched
The router doesn't need to access everything on the Internet (OUTPUT chain). The needed services are:
iptables -A OUTPUT -o $WAN -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -o $WAN -p tcp --dport 53 -j ACCEPT iptables -A OUTPUT -o $WAN -dst 195.56.146.238 -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -o $WAN -dst 195.220.94.163 -p udp --dport 123 -j ACCEPT iptables -A OUTPUT -o $WAN -dst 195.220.94.163 -p tcp --dport 123 -j ACCEPT
I think these rules should be in /etc/firewall.user .
Patch for /etc/init.d/S45firewall:
38,43d37 < iptables -A INPUT -p icmp -j ACCEPT # allow ICMP < iptables -A INPUT -p gre -j ACCEPT # allow GRE < < # reject (what to do with anything not allowed earlier) < iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset < iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable 58,64d51 < # allow < iptables -A OUTPUT -j ACCEPT #allow everything out < < # reject (what to do with anything not allowed earlier) < iptables -A OUTPUT -p tcp -j REJECT --reject-with tcp-reset < iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable < 79,82d65 < # allow < iptables -A FORWARD -i br0 -o br0 -j ACCEPT < iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT
Authorized services
To anywhere:
- http and https
- dns udp and tcp
To defined hosts:
- smtp to an smtp relaies to send mail
- pop3 or imap to pop3/imap servers to retrieve mails.
- ntp client to some choosen ntp servers
- msn main server e.g. messenger.hotmail.com
- jabber servers.
- irc or ircs to irc servers.
- silc to silcservers.
OpenVPN Configuration
If things go wrong
The reset button on the rear panel, next to the wan port, put the router in the failsafe mode. The failsafe mode can be enabled during the pre-init phase (see /etc/preinit):
ifconfig $ifname 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 up
netmsg 192.168.1.0 "(dummy message)" # b44 eats the first packet
netmsg 192.168.1.255 "Press reset now, to enter Failsafe!"
sleep 2
if [ $(cat /proc/sys/reset) = 1 -o "$(nvram get failsafe)" = 1 ]; then
while :; do { echo $(((X=(X+1)%8)%2)) > /proc/sys/diag; sleep $((X==0));
export FAILSAFE=true
[ "$(nvram get boot_wait)" != "on" ] && {
nvram set boot_wait=on
nvram commit
}
netmsg 192.168.1.255 "Entering Failsafe!"
telnetd -l /bin/login <> /dev/null 2>&1
else
ifconfig $ifname 0.0.0.0
# revert to the boot loader's vlan config
# required for at least WRT54G v1.1
[ -d /proc/switch/eth0 ] && {
echo "$v0p" > /proc/switch/eth0/vlan/0/ports
echo "$v1p" > /proc/switch/eth0/vlan/1/ports
echo "$v2p" > /proc/switch/eth0/vlan/2/ports
}
fi
mount_root ${FAILSAFE:+failsafe}
exec /sbin/init
By default the wait time is 2 seconds, if you want more, just edit the line "sleep 2".
To see this you can launch a listening utiliy on udp port 4919 (e.g. 0x1337). nbd provides a tiny utility which bind a listening socket on the port (recvudp.c or recvudp).
You can start a netcat listening on the udp port too:
$ nc -u -l -p 4919
Wait for :
Msg from 192.168.1.1: Press reset now, to enter Failsafe!
Push the reset button. If you successfully push the button in the short range of time you will see:
Msg from 192.168.1.1: Entering Failsafe!
When you are in failsafe mode, the router is in default configuration with filesystems mounted read-only. You can mount the filesystem somewhere and make a backup if you forgot to make one before ;) :
root@(none):~# mkdir /tmp/wrt root@(none):~# mount -o rw /dev/mtdblock/4 /tmp/wrt root@(none):~# tar zcvf wrt-backup.tar.gz wrt/*
To transfer the tarball to another host, use netcat. Start a listening netcat en port 4444 on 192.168.1.10 for example:
$ netcat -l -p 4444 > wrt-backup.tar.gz
root@(none):~# dd if=/tmp/wrt-backup.tar.gz | nc 192.168.1.10 4444
You can also mount the actual root filesystem read-write:
root@(none):~# mount_root
Now, /dev/mtdblock/4 is mounted on / (rw).
To come back to default configuration, use the following command:
root@(none):~# firstboot
And reboot:
root@(none):~# reboot
More info on Troubleshooting section of the OpenWRT wiki.
TODO
I'd like to improve the security level of my wrt router. I will probably switch to kamikaze for some features I want.
- chroot services with unprivileged user
- harden kernel and memory management
- compile with buffer overflow protection

