Return to RAMBOOT

RAMBOOT-Home-Router-HOWTO

This HOWTO provides an example of using RAMBOOT for a home router on an inexpensive Intel Atom setup.  The RAMBOOT project was actually started specifically for this system.


Components Used

Total cost at the time of purchase (March 2012): $326.36 (including shipping).

Some notes on the hardware configuration:

See Photos at the bottom of this page.

This setup makes use of 4GB RAM, with a 1GB ramdisk and 3GB remaining for the OS.


Installing

Install the latest RAMBOOT release to the USB flash using the instructions on the RAMBOOT website (RAMBOOT-1.0.0-beta1 was used for this HOWTO).

Modify the SYSLINUX.CFG file on the USB flash (in the SYSLINUX directory) to set the correct boot device and ramdisk size:

DISPLAY README.TXT
TIMEOUT 50
TOTALTIMEOUT 9000
ONTIMEOUT core

LABEL memtest
	KERNEL memtest

LABEL core
	KERNEL vmlinuz-3.8.0-34-generic
	INITRD initrd.img-3.8.0-34-generic
	APPEND root=/dev/sda1 boot=ramboot ramdisk_size=1048576K elevator=deadline

Upon first boot, the absence of a config.tar.gz archive will result in the root account being enabled. Login as root (no password is set).

Using apt-get, update packages and install the software desired for your system.

At a minimum:

apt-get update
apt-get dist-upgrade
apt-get install nano
apt-get install sudo
apt-get install ssh
apt-get install iptables
apt-get install vlan
apt-get install bridge-utils
apt-get install iputils-ping
apt-get install ntpdate

You will want to add a non-root user (useradd) and add the user to /etc/sudoers, then disable the root user. You may also want to install a DHCP server and other network services depending on your goals for the OS.

Note that some common packages may not be found by apt-get. If this is the case you may need to edit your APT sources.list and include additional repositories.

You should avoid creating specific configuration files at this stage, since we will be using the state of the OS as a new base image for your RAMBOOT system.

You may want to use a default password for user accounts in this stage as well, as they will be replaced by the configuration package later on.

Next mount the bootflash and run the rebuild_rootfs script from the INSTALL folder.

After this, you should be able to reboot and have a system with the packages you've installed.

Place your system configuration in /etc/rc.local

Here is an example configuration:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

modprobe nf_conntrack
modprobe ip_conntrack

# OUTSIDE inteface
ip addr add 203.0.113.9/24 dev eth0
ip link set up dev eth0
ip route add default via 203.0.113.1 dev eth0 metric 254
echo "nameserver 203.0.113.2" > /etc/resolv.conf

# INSIDE interface
ip addr add 192.168.0.1/24 dev eth1
ip link set up dev eth1

ntpdate 203.0.113.1
hwclock --systohc

echo 1025 65535 > /proc/sys/net/ipv4/ip_local_port_range
echo 1 > /proc/sys/net/ipv4/ip_forward                                  # Enable IP forwarding
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects                   # Don't accept ICMP redirect
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects                     # Don't send ICMP redirect either
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route                # Don't accept source routed packets
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians                       # Log packets dropped by rp_filter
echo 2 > /proc/sys/net/ipv4/ip_dynaddr                                  # Permit and log dynamic source rewriting (required for FW)
echo 0 > /proc/sys/net/ipv4/tcp_ecn                                     # Disable Explicit Congestion Notification
echo 1 > /proc/sys/net/ipv4/conf/all/arp_announce                       # Prefer local subnet IP to respond for ARP source
echo 2 > /proc/sys/net/ipv4/conf/all/arp_ignore                         # Ignore ARP unless its on and from the local subnet
echo 4096 > /proc/sys/net/netfilter/nf_conntrack_expect_max             # Increases the default conntrack expect from 256 to 4096
echo 1 > /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal            # Don't use TCP window scale as a determinant for packet validity
echo 2048  > /proc/sys/net/ipv4/neigh/default/gc_thresh1                # ARP table minimum before GC
echo 8192  > /proc/sys/net/ipv4/neigh/default/gc_thresh2                # ARP table soft maxium
echo 16384 > /proc/sys/net/ipv4/neigh/default/gc_thresh3                # ARP table hard maxium
echo 300   > /proc/sys/net/ipv4/neigh/default/base_reachable_time       # ARP cache valid minimum of between 150 and 450 seconds (random)
echo 128 > /proc/sys/net/ipv4/igmp_max_memberships                      # IGMP max member groups
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding                         # Enable IPv6 forwarding
echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra                          # Don't accept IPv6 RA from other hosts (rogue IPv6 routers)

# System Firewall Policy:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p icmp -f -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name DEFAULT --rsource -j DROP
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -i eth1 -m state --state NEW -p udp -m udp --sport 68 --dport 67 -j ACCEPT
iptables -A INPUT -i eth1 -m state --state NEW -p udp -m udp --dport 53 -j ACCEPT
iptables -A INPUT -i eth1 -m state --state NEW -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -i eth1 -m state --state NEW -p udp -m udp --dport 123 -j ACCEPT
iptables -A INPUT -j DROP

iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state NEW -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -m state --state NEW -m owner --gid-owner root -j ACCEPT
iptables -A OUTPUT -m state --state NEW -p udp -m udp --dport 53 -j ACCEPT
iptables -A OUTPUT -m state --state NEW -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -j DROP

iptables -t raw -A PREROUTING -i lo -j NOTRACK

# NAT rules:

iptables -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
iptables -A POSTROUTING -s 192.168.0.0/24 -d 192.168.0.0/24 -o eth1 -j MASQUERADE # NAT reflection rule

# Network Firewall Policy:

iptables -A FORWARD -p tcp -m tcp --tcp-flags ALL ALL -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags ALL NONE -j DROP
iptables -A FORWARD -p icmp -f -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Rules to block or allow internal traffic here.

iptables -A FORWARD -i eth1 -m state --state NEW -j ACCEPT
iptables -A FORWARD -j DROP

exit 0

After you have configured your system the way you want, you can save the configuration using the example save script provided in /scripts/config-save

You should then have a functional in-memory router OS.

Any changes should be made to rc.local and the config-save script should be run again for the configuration to persist through a reboot.

Note that this is a very basic example and doesn't include a DHCP client for the outside interface, or DNS and DHCP services for the internal network.


Photos

Here are some photos of the assembled unit:


The USB storage was painted for an artistic touch (Note to self: nail polish isn't a good idea for this ... very long dry time).


The unit powered up and running.


Top view of the system.


Close-up of the USB flash in the system board.


Copyright © 2013, Ray Patrick Soucy
Code examples are licensed under the GNU General Public License version 2 or later. Verbatim copying and distribution of this page is permitted provided this notice is preserved.