Differences between revisions 1 and 25 (spanning 24 versions)
Revision 1 as of 2010-02-21 00:45:18
Size: 263
Editor: ?green
Comment: Initial commit
Revision 25 as of 2010-07-02 21:41:37
Size: 22733
Editor: ?green
Comment: update SixXS section and add aiccu to Document Conventions
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
= Debian home router/server =
I have been working to set up a [[http://www.soekris.com/net5501.htm|Soekris net5501]] to act as a home router/server. I will document my efforts here. If you know of a better place in the wiki for this to go, please suggest it.
#language en

I have been working to set up a [[http://www.soekris.com/net5501.htm|Soekris net5501]] to act as a home router/server. My efforts are documented here an an example for others attempting similar tasks. Note that this guide is only intended to cover post-installation software setup and so should be applicable to nearly any hardware.

'''Under construction. I hope to get this finished eventually.'''

''If you notice any errors please mail me, leave a [[#Comments|comment]], or fix them.''

''If you know of a better place in the wiki for this to go, please [[#Comments|suggest]] it.''

<<TableOfContents(2)>>


= Requirements =
Here is a list of requirements with links to the relevant sections.

 * 100% Debian, no external software unless absolutely necessary
 * Stock Debian kernel
 * [[#dnsmasq|dnsmasq]] server, providing
  * DNS, including local DNS
  * DHCP server, including static IPs
 * Support IPv4 and IPv6 - [[#Firewall|Firewall]]
 * [[#IPv6|IPv6]] address
  * [[#Teredo|Teredo]]
  * [[#6to4|6to4]]
 * Provide local private network bridge - [[#Basic Networking|Networking]]
  * Ethernet ports + private secured wireless ([[#hostapd|hostap]])
 * Provide public network
  * Unsecured wireless ([[#hostapd|hostap]])
 * Simple and robust [[#Firewall|firewall]]
  * Reasonable security for the router
  * Port forwarding (single, range, or all)
  * With [[#UPnP|UPnP]] support
  * Modify TOS packet header bits
 * [[#Traffic Control|Traffic control]] to provide a better internet experience for multiple users/connections
  * Use TOS packet header bits


= Document Conventions =
 * eth0 is WAN ethernet port
 * aiccu is the interface of the SixXS ipv6 tunnel
 * eth1-eth3 are LAN ethernet (private)
 * wlan0 is private wireless ([[#hostapd|hostap]])
 * wlan0_0 is public wireless ([[#hostapd|hostap]])
 * br0 bridges eth1-eth3 and wlan0
 * private local ipv4 network: 192.0.2.0/24 (choose your own, probably 192.168.x.0/24)
 * private local ipv6 network: 2001:db8::/32 (? from SixXS)
 * public local ipv4 network: 192.0.3.0/24 (choose your own, probably 192.168.x+1.0/24)
 * public local ipv6 network: 2001:db8::1/32 (? from SixXS)


= SixXS =
Register with SixXS and request an tunnel and subnet. Choose your tunnel type carefully. I chose the less efficient AYIYA type because it will work behind masquerading.

Use aiccu to bring up the tunnel.

OPTIONAL: To avoid using your SixXS password in plaintext in the aiccu configuration file, add a '''TIC Password''' for the tunnel, then use "$HANDLE/$TUNNELID" as your username and the password you chose in the configuration.

aiccu.conf:
{{{
username $HANDLE
password $PASSWORD
protocol tic
server tic.sixxs.net
ipv6_interface aiccu
tunnel_id $TUNNELID
automatic true
requiretls false
}}}

Now you should have an interface named "aiccu" and ipv6 connectivity. Test with:
{{{
ping6 -c 2 www.kame.net
}}}


= Basic Networking =
/etc/network/interfaces:
{{{
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface (WAN)
auto eth0
#allow-hotplug eth0 # hotplugging does not seem to work reliably
iface eth0 inet dhcp

# Network bridge (LAN)
auto br0
iface br0 inet static
  address 192.0.2.1
  netmask 255.255.255.0
  network 192.0.2.0
  broadcast 192.0.2.255
  bridge_ports eth1 eth2 eth3 wlan0
iface br0 inet6 static
  address (from sixxs)
  netmask 64

# Public wireless network
auto wlan0_0
iface wlan0_0 inet static
  address 192.0.3.1
  netmask 255.255.255.0
  network 192.0.3.0
  broadcast 192.0.3.255
iface wlan0_0 inet6 static
  address (from sixxs)
  netmask 64
}}}

----
Set up /etc/hosts to make local DNS work correctly:

Change this line:
{{{
127.0.1.1 hostname.example.org hostname
}}}

To:
{{{
192.168.68.1 hostname.example.org hostname2.example2.org hostname
}}}

Test: make sure both ''hostname -s'' and ''hostname -f'' work correctly now.


= dnsmasq =
Fill dnsmasq.conf:
{{{
interface=br0
dhcp-range=private,192.0.2.51,192.0.2.250,48h

interface=wlan0_0
dhcp-range=public,192.0.3.51,192.0.3.250,48h

domain-needed
bogus-priv

# Set the NTP time server address to be the same machine as
# is running dnsmasq
dhcp-option=42,0.0.0.0

# Send microsoft-specific option to tell windows to release the DHCP lease
# when it shuts down.
dhcp-option=vendor:MSFT,2,1i

# Set the limit on DHCP leases, the default is 150
## here, raised to the maximum number of hosts on networks
dhcp-lease-max=506

# Set the DHCP server to authoritative mode. In this mode it will barge in
# and take over the lease for any client which broadcasts on the network,
# whether it has a record of the lease or not. This avoids long timeouts
# when a machine wakes up on a new network. DO NOT enable this if there's
# the slighest chance that you might end up accidentally configuring a DHCP
# server for your campus/company accidentally. The ISC server uses
# the same option, and this URL provides more information:
# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php
#dhcp-authoritative
}}}

----
OPTIONAL: For static host configuration, create /etc/dnsmasq.d/static-hosts.conf:
{{{
# static DHCP hosts
# Optionally, use IPs from 2 to 50 (outside of DHCP range).

# example for private network
#dhcp-host=xx:xx:xx:xx:xx:xx,192.0.2.10

# example for public network
#dhcp-host=xx:xx:xx:xx:xx:xx,192.0.3.16
}}}

----
OPTIONAL: To use custom nameservers, create /etc/alt.dns:
{{{
# Google Public DNS
nameserver 8.8.8.8
nameserver 8.8.4.4
}}}

And uncomment line in /etc/default/dnsmasq:
{{{
IGNORE_RESOLVCONF=yes
}}}

And add line to /etc/dnsmasq.conf:
{{{
resolv-file=/etc/alt.dns
}}}


= Firewall =
Firewall shell scripts are slow (see [[this|http://www.faqs.org/docs/iptables/saveandrestore.html]]), and scripts for iptables-restore/ip6tables-restore must be maintained individually. In order to keep performance, use a single script, and gain readability to easy maintenance, I built a script that uses iptables-restore and family.

Create /usr/local/sbin/build-firewall.sh:
{{{
 #!/bin/sh # What markup will make this line correct?
set -e

case "$1" in
 apply)
  ;;
 restore)
  ;;
 build)
  ;;
 save)
  ;;
 *)
  echo "Usage: $0 {apply|build|restore|save}"
  echo
  echo "apply: iptables-apply (includes connection check)"
  echo "build: just write iptables and ip6tables scripts"
  echo "restore: iptables-restore (apply immediately without check)"
  echo "save: restore, then save iptables and ip6tables scripts to /etc/network/"
  exit 1
  ;;
esac

policies() {
ipboth RAW :PREROUTING ACCEPT
ipboth RAW :OUTPUT ACCEPT
ipboth MANGLE :PREROUTING ACCEPT
ipboth MANGLE :INPUT ACCEPT
ipboth MANGLE :FORWARD ACCEPT
ipboth MANGLE :OUTPUT ACCEPT
ipboth MANGLE :POSTROUTING ACCEPT
ip4 NAT :PREROUTING ACCEPT
ip4 NAT :OUTPUT ACCEPT
ip4 NAT :POSTROUTING ACCEPT
ipboth FILTER :INPUT DROP
ipboth FILTER :FORWARD DROP
ipboth FILTER :OUTPUT DROP
}

rules() { # Use no "double quotes" in rules!
# DNAT
 # modify DNAT
 ip4 NAT :DNAT_MOD -
 ip4 NAT -A PREROUTING -j DNAT_MOD

 # do not change destination IP/port for these packets
 ip4 NAT -A DNAT_MOD -i eth0 -p icmp -j RETURN
 ip4 NAT :DNAT_SKIP -
 ip4 NAT -A DNAT_MOD -i eth0 -g DNAT_SKIP

 # manual port forwarding
 ip4 NAT :MANUAL_DNAT -
 ip4 NAT -A DNAT_MOD -i eth0 -j MANUAL_DNAT
 ## example: to specific host (modify static-hosts.conf if necessary)
 #ip4 NAT -A MANUAL_DNAT -p tcp -m tcp --dport 33333 -j DNAT --to-destination 192.0.2.10
 ## example: to specific host and different destination port (modify static-hosts.conf if necessary)
 #ip4 NAT -A MANUAL_DNAT -p tcp -m tcp --dport 81 -j DNAT --to-destination 192.0.3.11:80
 ## example: to different destination port on router
 #ip4 NAT -A MANUAL_DNAT -p tcp -m tcp --dport 81 -j DNAT --to-destination :80

 # upnp
 ip4 NAT :DNAT_UPNP -
 ip4 NAT -A DNAT_MOD -i eth0 -j DNAT_UPNP
 ## example, from linux-igd upnpd
 ##ip4 NAT -A DNAT_UPNP -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.0.2.96:80

 # forward all remaining ports
 ip4 NAT :DNAT_ALLPORTS -
 ip4 NAT -A DNAT_MOD -i eth0 -j DNAT_ALLPORTS
 #ip4 NAT -A DNAT_ALLPORTS -j DNAT --to-destination 192.0.2.10
# END DNAT

# masquerading
ip4 NAT -A POSTROUTING -s 192.0.2.0/24 ! -d 192.0.2.0/24 -o eth0 -j MASQUERADE
ip4 NAT -A POSTROUTING -s 192.0.3.0/24 ! -d 192.0.3.0/24 -o eth0 -j MASQUERADE

# IPv6
ip4 FILTER -A INPUT -p ipv6 -j ACCEPT
ip4 FILTER -A FORWARD -p ipv6 -j ACCEPT
ip4 FILTER -A OUTPUT -p ipv6 -j ACCEPT

# loopback
ipboth FILTER -A INPUT -i lo -j ACCEPT
ipboth FILTER -A OUTPUT -o lo -j ACCEPT

# BLOCKING
 # drop RH0
 ip6tables -A INPUT -m rt --rt-type 0 -j DROP
 ip6tables -A FORWARD -m rt --rt-type 0 -j DROP
 ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP
  
 # host block
 ipboth FILTER :HOST_BLOCK -
 ipboth FILTER -A INPUT -j HOST_BLOCK
 ipboth FILTER -A FORWARD -j HOST_BLOCK
 ipboth FILTER -A OUTPUT -j HOST_BLOCK
 ## examples
 # ipboth FILTER -A HOST_BLOCK --source 75.0.1.25 -j HOST_BLOCK_EXEC
 # ipboth FILTER -A HOST_BLOCK --destination 75.0.1.25 -j HOST_BLOCK_EXEC
 ipboth FILTER :HOST_BLOCK_EXEC -
 ipboth FILTER -A HOST_BLOCK_EXEC -m limit --limit 1/min --limit-burst 1 -j LOG --log-prefix Blocked-host_ --log-level notice
 ipboth FILTER -A HOST_BLOCK_EXEC -j DROP
  
 # invalid
 ipboth FILTER :VALIDITY_CHECK -
 ipboth FILTER :INVALID -
 ipboth FILTER -A INPUT -j VALIDITY_CHECK
 ipboth FILTER -A FORWARD -j VALIDITY_CHECK
 ipboth FILTER -A VALIDITY_CHECK -m state --state INVALID -j INVALID
 ipboth FILTER -A INVALID -m limit --limit 6/min --limit-burst 2 -j LOG --log-prefix Invalid-packet_ --log-level info
 ipboth FILTER -A INVALID -j DROP
 ## more validity checks here, like previous line

 # fragmented
 ipboth FILTER :FRAGMENT_CHECK -
 ipboth FILTER -A INPUT -j FRAGMENT_CHECK
 ipboth FILTER -A FORWARD -j FRAGMENT_CHECK
 ipboth FILTER :FRAGMENTED -
 ip4 FILTER -A FRAGMENT_CHECK -f -j FRAGMENTED
 ip6 FILTER -A FRAGMENT_CHECK -m frag --fragmore -m length --length 0:1279 -j FRAGMENTED
 ipboth FILTER -A FRAGMENTED -m limit --limit 3/min --limit-burst 1 -j LOG --log-prefix Fragmented-packet_ --log-level info
 ipboth FILTER -A FRAGMENTED -j DROP
# END BLOCKING

# local dhcp
ipboth FILTER -A INPUT -p udp -i br0 --sport 67:68 --dport 67:68 -j ACCEPT
ipboth FILTER -A INPUT -p udp -i wlan0_0 --sport 67:68 --dport 67:68 -j ACCEPT
# out
ipboth FILTER -A OUTPUT -p udp -o br0 --sport 67:68 --dport 67:68 -j ACCEPT
ipboth FILTER -A OUTPUT -p udp -o wlan0_0 --sport 67:68 --dport 67:68 -j ACCEPT

# spoofed
ipboth FILTER :SPOOFED -
ip4 FILTER -A INPUT -j SPOOFED # TODO: add ip6 here
ip4 FILTER -A FORWARD -j SPOOFED # TODO: add ip6 here
ipboth FILTER -A SPOOFED -i eth0 -j RETURN
ip6 FILTER -A SPOOFED -i aiccu -j RETURN
ip4 FILTER -A SPOOFED -i br0 -s 192.0.2.0/24 -j RETURN
#ip6 FILTER -A SPOOFED -i br0 -s :: -j RETURN # TODO: fix with correct ipv6 addresses
ip4 FILTER -A SPOOFED -i wlan0_0 -s 192.0.3.0/24 -j RETURN
#ip6 FILTER -A SPOOFED -i wlan0_0 -s :: -j RETURN # TODO: fix with correct ipv6 addresses
ipboth FILTER -A SPOOFED -m limit --limit 6/min -j LOG --log-prefix Spoofed-packet_ --log-level notice
ip4 FILTER -A SPOOFED -j REJECT --reject-with icmp-net-unreachable
ip6 FILTER -A SPOOFED -j REJECT --reject-with icmp6-adm-prohibited

# ICMP
ip4 FILTER -A OUTPUT -p icmp -j ACCEPT
ip6 FILTER -A OUTPUT -p ipv6-icmp -j ACCEPT
ipboth FILTER :ICMP -
ip4 FILTER -A INPUT -p icmp -j ICMP
ip6 FILTER -A INPUT -p ipv6-icmp -j ICMP
ip4 FILTER -A FORWARD -p icmp -j ICMP
ip6 FILTER -A FORWARD -p ipv6-icmp -j ICMP
ipboth FILTER -A ICMP -m limit --limit 20/sec --limit-burst 100 -j ACCEPT
ip4 FILTER -A ICMP -p icmp -m icmp --icmp-type echo-request -j DROP
ip6 FILTER -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j DROP
ipboth FILTER -A ICMP -m limit --limit 20/sec -j ACCEPT
ipboth FILTER -A ICMP -j DROP

# established connections
ipboth FILTER -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ipboth FILTER -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
ipboth FILTER -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SPECIFIC SERVICES
 # ssh
 ip4 NAT -A DNAT_SKIP -p tcp --dport ssh -j RETURN
 ipboth FILTER -A INPUT -p tcp --dport ssh -j ACCEPT
 ipboth FILTER -A OUTPUT -p tcp --dport ssh -j ACCEPT

 # upstream dhcp
 ip4 NAT -A DNAT_SKIP -p tcp --dport 67:68 -j RETURN
 ipboth FILTER -A INPUT -p udp -i eth0 --sport 67:68 --dport 67:68 -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o eth0 --sport 67:68 --dport 67:68 -j ACCEPT

 # ddns
 ipboth FILTER -A OUTPUT -p tcp -o eth0 --dport 5000 -j ACCEPT #*check*# port 5000?
 ipboth FILTER -A OUTPUT -p tcp -o aiccu --dport 5000 -j ACCEPT #*check*# port 5000?

 # SixXS
 ip4 NAT -A DNAT_SKIP -p tcp --dport 3874 -j RETURN
 ip4 NAT -A DNAT_SKIP -p udp -m multiport --dport 3740,5072 -j RETURN
 ip4 FILTER -A OUTPUT -p tcp -o eth0 --dport 3874 -j ACCEPT
 ip4 FILTER -A OUTPUT -p udp -o eth0 -m multiport --dport 3740,5072 -j ACCEPT

 # dns
 ip4 NAT -A DNAT_SKIP -p tcp -m multiport --dport domain,mdns -j RETURN
 ip4 NAT -A DNAT_SKIP -p udp -m multiport --dport domain,mdns -j RETURN
 ipboth FILTER -A INPUT -p tcp -i br0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A INPUT -p udp -i br0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A INPUT -p tcp -i wlan0_0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A INPUT -p udp -i wlan0_0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o br0 --dport mdns -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o wlan0_0 --dport mdns -j ACCEPT
 ipboth FILTER -A OUTPUT -p tcp -o eth0 --dport domain -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o eth0 --dport domain -j ACCEPT
 ip6 FILTER -A OUTPUT -p tcp -o aiccu --dport domain -j ACCEPT
 ip6 FILTER -A OUTPUT -p udp -o aiccu --dport domain -j ACCEPT

 # ntp
 ip4 NAT -A DNAT_SKIP -p udp --dport ntp -j RETURN
 ipboth FILTER -A INPUT -p udp --dport ntp -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp --sport ntp -j ACCEPT

 # www/https
 ip4 NAT -A DNAT_SKIP -p tcp --dport www -j RETURN
 ipboth FILTER -A INPUT -p tcp --dport www -j ACCEPT
 ipboth FILTER -A OUTPUT -p tcp -o eth0 -m multiport --dports www,https -j ACCEPT
 ip6 FILTER -A OUTPUT -p tcp -o aiccu -m multiport --dports www,https -j ACCEPT

 # upnp
 ip4 NAT -A DNAT_SKIP -p tcp -m multiport --dports 5000,49152 -j RETURN
 ip4 NAT -A DNAT_SKIP -p udp --dport 1900 -j RETURN
 ip4 FILTER :UPNP_FORWARD -
 ip4 FILTER -A INPUT -i br0 -p udp -m multiport --ports 1900 -j ACCEPT
 ip4 FILTER -A INPUT -i br0 -p tcp -m multiport --ports 2869,5000,49152 -j ACCEPT
 ip4 FILTER -A INPUT -i br0 -p igmp -j ACCEPT
 ip4 FILTER -A OUTPUT -o br0 -p udp -m multiport --ports 1900 -j ACCEPT
 ip4 FILTER -A OUTPUT -o br0 -p tcp -m multiport --ports 2869,5000,49152 -j ACCEPT
 ip4 FILTER -A OUTPUT -o br0 -p igmp -j ACCEPT
 ip4 FILTER -A FORWARD -i eth0 -o br0 -j UPNP_FORWARD
 ## example, from linux-igd upnpd
 ##ip4 FILTER -A UPNP_FORWARD -d 192.0.2.10/24 -p tcp -m tcp --dport 80 -j ACCEPT
# END SPECIFIC SERVICES

# from private
ipboth FILTER :FROM_PRIVATE -
ipboth FILTER -A FORWARD -i br0 -j FROM_PRIVATE
ipboth FILTER -A FROM_PRIVATE -o br0 -j ACCEPT
ipboth FILTER -A FROM_PRIVATE -o eth0 -j ACCEPT
ipboth FILTER -A FROM_PRIVATE -o aiccu -j ACCEPT
ipboth FILTER -A FROM_PRIVATE -o wlan0_0 -m limit --limit 3/min -j LOG --log-prefix Rejected-private-to-public_ --log-level info
ip4 FILTER -A FROM_PRIVATE -o wlan0_0 -j REJECT --reject-with icmp-net-prohibited
ip6 FILTER -A FROM_PRIVATE -o wlan0_0 -j REJECT --reject-with icmp6-adm-prohibited

# from public
ipboth FILTER :FROM_PUBLIC -
ipboth FILTER -A FORWARD -i wlan0_0 -j FROM_PUBLIC
ipboth FILTER -A FROM_PUBLIC -o eth0 -j ACCEPT
ipboth FILTER -A FROM_PUBLIC -o aiccu -j ACCEPT
ipboth FILTER -A FROM_PUBLIC -o br0 -m limit --limit 3/min -j LOG --log-prefix Rejected-public-to-private_ --log-level info
ip4 FILTER -A FROM_PUBLIC -o br0 -j REJECT --reject-with icmp-net-prohibited
ip6 FILTER -A FROM_PUBLIC -o br0 -j REJECT --reject-with icmp6-adm-prohibited
ipboth FILTER -A FROM_PUBLIC -o wlan0_0 -m limit --limit 3/min -j LOG --log-prefix Rejected-public-to-public_ --log-level info
ip4 FILTER -A FROM_PUBLIC -o wlan0_0 -j REJECT --reject-with icmp-host-prohibited
ip6 FILTER -A FROM_PUBLIC -o wlan0_0 -j REJECT --reject-with icmp6-adm-prohibited

# DROP/REJECT
 # unmatched packets
 ip4 FILTER -A INPUT -m limit --limit 20/min -j LOG --log-prefix Unmatched-INPUT_ --log-level debug
 ip6 FILTER -A INPUT -m limit --limit 20/min -j LOG --log-prefix Unmatched-v6-INPUT_ --log-level debug
 ip4 FILTER -A FORWARD -m limit --limit 20/min -j LOG --log-prefix Unmatched-FORWARD_ --log-level debug
 ip6 FILTER -A FORWARD -m limit --limit 20/min -j LOG --log-prefix Unmatched-v6-FORWARD_ --log-level debug
 ip4 FILTER -A OUTPUT -j LOG --log-prefix Unmatched-OUTPUT_ --log-level debug
 ip6 FILTER -A OUTPUT -j LOG --log-prefix Unmatched-v6-OUTPUT_ --log-level debug
# end DROP/REJECT

# TOS
 ipboth MANGLE :TOS_CHAIN -
 ipboth MANGLE -A PREROUTING -j TOS_CHAIN

 # Correcting TOS for incorrectly marked packets
 ipboth MANGLE :FIX_TOS -
 ipboth MANGLE -A TOS_CHAIN -m tos ! --tos Normal-Service -j FIX_TOS
  # Large packets with Minimize-Delay TOS
  ipboth MANGLE -A FIX_TOS -m tos ! --tos Minimize-Delay -j RETURN
  ipboth MANGLE -A FIX_TOS -p tcp -m length --length 0:512 -j RETURN
  ipboth MANGLE -A FIX_TOS -p udp -m length --length 0:1024 -j RETURN
  ipboth MANGLE -A FIX_TOS -j TOS --set-tos Maximize-Throughput

 # Add TOS for unmarked packets
 ipboth MANGLE :ADD_TOS -
 ipboth MANGLE -A TOS_CHAIN -m tos --tos Normal-Service -j ADD_TOS
  # TCP control packets (from www.docum.org / Stef Coene)
  ipboth MANGLE :ACK_TOS -
  ipboth MANGLE -A ADD_TOS -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j ACK_TOS
  ipboth MANGLE -A ACK_TOS -m length --length 0:256 -j TOS --set-tos Minimize-Delay
  ipboth MANGLE -A ACK_TOS -m length --length 256: -j TOS --set-tos Maximize-Throughput
  ipboth MANGLE -A ADD_TOS -p tcp --tcp-flags SYN,RST,ACK ACK -j RETURN
  # Specify general TOS settings here for protocol/port
  ipboth MANGLE -A ADD_TOS -p icmp -j TOS --set-tos Minimize-Delay
  ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports smtp -j TOS --set-tos Minimize-Cost
  #ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports 000 -j TOS --set-tos Maximize-Reliability
  ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports www,https -j TOS --set-tos Maximize-Throughput
  ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports domain,mdns,auth,5154,3389,5900 -j TOS --set-tos Minimize-Delay
  #ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports 000 -j TOS --set-tos Minimize-Cost
  #ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports 000 -j TOS --set-tos Maximize-Reliability
  #ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports 000 -j TOS --set-tos Maximize-Throughput
  ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports domain,67:68,ntp,5154,5060:5064,iax,1720,1731 -j TOS --set-tos Minimize-Delay
# END TOS

# SHAPING
 # add shaping assist fwmarks
 ipboth MANGLE :MARKING_IN -
 ipboth MANGLE -A PREROUTING -j MARKING_IN
  ipboth MANGLE -A MARKING_IN -i eth0 -j RETURN
  ipboth MANGLE -A MARKING_IN -i aiccu -j RETURN
  ipboth MANGLE -A MARKING_IN -i br0 -j MARK --set-mark 0x2/0xf
  ipboth MANGLE -A MARKING_IN -i br0 -j RETURN
  ipboth MANGLE -A MARKING_IN -i wlan0_0 -j MARK --set-mark 0x3/0xf
 ip4 MANGLE -A OUTPUT -j MARK --set-mark 0x4/0xf #*check* breaks radvd on ipv6 side
# END SHAPING

# TCPMSS clamp
ipboth MANGLE -A POSTROUTING -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ipboth MANGLE -A POSTROUTING -o aiccu -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
}


# build
IPTABLES=$( mktemp /tmp/iptables.XXX )
IP6TABLES=$( mktemp /tmp/ip6tables.XXX )
RAW_IP4=$( mktemp )
MANGLE_IP4=$( mktemp )
NAT_IP4=$( mktemp )
FILTER_IP4=$( mktemp )
RAW_IP6=$( mktemp )
MANGLE_IP6=$( mktemp )
FILTER_IP6=$( mktemp )
ip4() {
 TABLE=$( eval "echo \$${1}_IP4" )
 shift 1
 echo $* >> $TABLE
}
ip6() {
 TABLE=$( eval "echo \$${1}_IP6" )
 shift 1
 echo $* >> $TABLE
}
ipboth() {
 ip4 $@
 ip6 $@
}
ipboth RAW "*raw"
ipboth MANGLE "*mangle"
ip4 NAT "*nat"
ipboth FILTER "*filter"
policies
rules
for TABLE in RAW_IP4 MANGLE_IP4 NAT_IP4 FILTER_IP4 RAW_IP6 MANGLE_IP6 FILTER_IP6 ; do
 eval "echo COMMIT >> \$${TABLE}"
done
echo "# iptables firewall for owenhs" >> $IPTABLES
echo "# ip6tables firewall for owenhs" >> $IP6TABLES
cat $RAW_IP4 $MANGLE_IP4 $NAT_IP4 $FILTER_IP4 >> $IPTABLES
cat $RAW_IP6 $MANGLE_IP6 $FILTER_IP6 >> $IP6TABLES
rm -f $RAW_IP4 $MANGLE_IP4 $NAT_IP4 $FILTER_IP4 $RAW_IP6 $MANGLE_IP6 $FILTER_IP6
case "$1" in
 apply)
  iptables-apply -t 30 $IPTABLES
  ip6tables-apply -t 30 $IP6TABLES
  echo "iptables and ip6tables applied successfully"
  rm -f $IPTABLES $IP6TABLES
  ;;
 restore)
  iptables-restore $IPTABLES
  ip6tables-restore $IP6TABLES
  echo "iptables and ip6tables restored successfully"
  rm -f $IPTABLES $IP6TABLES
  ;;
 build)
  echo "new: $IPTABLES"
  echo "new: $IP6TABLES"
  ;;
 save)
  iptables-restore $IPTABLES
  ip6tables-restore $IP6TABLES
  mv /etc/network/iptables /tmp/iptables.bak0
  mv /etc/network/ip6tables /tmp/ip6tables.bak0
  mv $IPTABLES /etc/network/iptables
  mv $IP6TABLES /etc/network/ip6tables
  mv /tmp/iptables.bak0 $IPTABLES
  mv /tmp/ip6tables.bak0 $IP6TABLES
  echo "old: $IPTABLES"
  echo "old: $IP6TABLES"
  ;;
esac
}}}


== UPnP ==
upnpd.conf... TODO


= hostap =
hostapd.conf... TODO


= IPv6 =
IPv6... TODO


= Traffic Control =
script... TODO


= Comments =
''Feedback is appreciated.''
 * I'd suggest recording the installation parts in the InstallingDebianOn namespace -- PaulWise <<DateTime(2010-02-21T09:01:02+0800)>>
  * Thanks Paul, but I do not plan to include any hardware-specific installation information. I added a note above. -- [[green]] <<DateTime(2010-02-20T21:08:07-0600)>>
   * Contributing to InstallingDebianOn would still be appreciated, as would the hardware info that the InstallingDebianOn templates suggest to add -- PaulWise <<DateTime(2010-02-21T20:37:45+0800)>>
    * [[InstallingDebianOn/Soekris/net5501|Done]], though it probably needs further work. -- [[green]] <<DateTime(2010-02-21T21:38:53-0600)>>

I have been working to set up a Soekris net5501 to act as a home router/server. My efforts are documented here an an example for others attempting similar tasks. Note that this guide is only intended to cover post-installation software setup and so should be applicable to nearly any hardware.

Under construction. I hope to get this finished eventually.

If you notice any errors please mail me, leave a ?comment, or fix them.

If you know of a better place in the wiki for this to go, please ?suggest it.

Requirements

Here is a list of requirements with links to the relevant sections.

  • 100% Debian, no external software unless absolutely necessary
  • Stock Debian kernel
  • ?dnsmasq server, providing

    • DNS, including local DNS
    • DHCP server, including static IPs
  • Support IPv4 and IPv6 - ?Firewall

  • ?IPv6 address

    • ?Teredo

    • ?6to4

  • Provide local private network bridge - ?Networking

    • Ethernet ports + private secured wireless (?hostap)

  • Provide public network
    • Unsecured wireless (?hostap)

  • Simple and robust ?firewall

    • Reasonable security for the router
    • Port forwarding (single, range, or all)
    • With ?UPnP support

    • Modify TOS packet header bits
  • ?Traffic control to provide a better internet experience for multiple users/connections

    • Use TOS packet header bits

Document Conventions

  • eth0 is WAN ethernet port
  • aiccu is the interface of the SixXS ipv6 tunnel
  • eth1-eth3 are LAN ethernet (private)
  • wlan0 is private wireless (?hostap)

  • wlan0_0 is public wireless (?hostap)

  • br0 bridges eth1-eth3 and wlan0
  • private local ipv4 network: 192.0.2.0/24 (choose your own, probably 192.168.x.0/24)
  • private local ipv6 network: 2001:db8::/32 (? from SixXS)
  • public local ipv4 network: 192.0.3.0/24 (choose your own, probably 192.168.x+1.0/24)
  • public local ipv6 network: 2001:db8::1/32 (? from SixXS)

SixXS

Register with SixXS and request an tunnel and subnet. Choose your tunnel type carefully. I chose the less efficient AYIYA type because it will work behind masquerading.

Use aiccu to bring up the tunnel.

OPTIONAL: To avoid using your SixXS password in plaintext in the aiccu configuration file, add a TIC Password for the tunnel, then use "$HANDLE/$TUNNELID" as your username and the password you chose in the configuration.

aiccu.conf:

username $HANDLE
password $PASSWORD
protocol tic
server tic.sixxs.net
ipv6_interface aiccu
tunnel_id $TUNNELID
automatic true
requiretls false

Now you should have an interface named "aiccu" and ipv6 connectivity. Test with:

ping6 -c 2 www.kame.net

Basic Networking

/etc/network/interfaces:

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface (WAN)
auto eth0
#allow-hotplug eth0 # hotplugging does not seem to work reliably
iface eth0 inet dhcp

# Network bridge (LAN)
auto br0
iface br0 inet static
  address 192.0.2.1
  netmask 255.255.255.0
  network 192.0.2.0
  broadcast 192.0.2.255
  bridge_ports eth1 eth2 eth3 wlan0
iface br0 inet6 static
  address (from sixxs)
  netmask 64

# Public wireless network
auto wlan0_0
iface wlan0_0 inet static
  address 192.0.3.1
  netmask 255.255.255.0
  network 192.0.3.0
  broadcast 192.0.3.255
iface wlan0_0 inet6 static
  address (from sixxs)
  netmask 64


Set up /etc/hosts to make local DNS work correctly:

Change this line:

127.0.1.1      hostname.example.org hostname

To:

192.168.68.1    hostname.example.org hostname2.example2.org hostname

Test: make sure both hostname -s and hostname -f work correctly now.

dnsmasq

Fill dnsmasq.conf:

interface=br0
dhcp-range=private,192.0.2.51,192.0.2.250,48h

interface=wlan0_0
dhcp-range=public,192.0.3.51,192.0.3.250,48h

domain-needed
bogus-priv

# Set the NTP time server address to be the same machine as
# is running dnsmasq
dhcp-option=42,0.0.0.0

# Send microsoft-specific option to tell windows to release the DHCP lease
# when it shuts down. 
dhcp-option=vendor:MSFT,2,1i

# Set the limit on DHCP leases, the default is 150
## here, raised to the maximum number of hosts on networks
dhcp-lease-max=506

# Set the DHCP server to authoritative mode. In this mode it will barge in
# and take over the lease for any client which broadcasts on the network,
# whether it has a record of the lease or not. This avoids long timeouts
# when a machine wakes up on a new network. DO NOT enable this if there's
# the slighest chance that you might end up accidentally configuring a DHCP
# server for your campus/company accidentally. The ISC server uses
# the same option, and this URL provides more information:
# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php
#dhcp-authoritative


OPTIONAL: For static host configuration, create /etc/dnsmasq.d/static-hosts.conf:

# static DHCP hosts
# Optionally, use IPs from 2 to 50 (outside of DHCP range).

# example for private network
#dhcp-host=xx:xx:xx:xx:xx:xx,192.0.2.10

# example for public network
#dhcp-host=xx:xx:xx:xx:xx:xx,192.0.3.16


OPTIONAL: To use custom nameservers, create /etc/alt.dns:

# Google Public DNS
nameserver      8.8.8.8
nameserver      8.8.4.4

And uncomment line in /etc/default/dnsmasq:

IGNORE_RESOLVCONF=yes

And add line to /etc/dnsmasq.conf:

resolv-file=/etc/alt.dns

Firewall

Firewall shell scripts are slow (see ?http://www.faqs.org/docs/iptables/saveandrestore.html), and scripts for iptables-restore/ip6tables-restore must be maintained individually. In order to keep performance, use a single script, and gain readability to easy maintenance, I built a script that uses iptables-restore and family.

Create /usr/local/sbin/build-firewall.sh:

 #!/bin/sh  # What markup will make this line correct?
set -e

case "$1" in
 apply)
  ;;
 restore)
  ;;
 build)
  ;;
 save)
  ;;
 *)
  echo "Usage: $0 {apply|build|restore|save}"
  echo
  echo "apply: iptables-apply (includes connection check)"
  echo "build: just write iptables and ip6tables scripts"
  echo "restore: iptables-restore (apply immediately without check)"
  echo "save: restore, then save iptables and ip6tables scripts to /etc/network/"
  exit 1
  ;;
esac

policies() {
ipboth RAW :PREROUTING ACCEPT
ipboth RAW :OUTPUT ACCEPT
ipboth MANGLE :PREROUTING ACCEPT
ipboth MANGLE :INPUT ACCEPT
ipboth MANGLE :FORWARD ACCEPT
ipboth MANGLE :OUTPUT ACCEPT
ipboth MANGLE :POSTROUTING ACCEPT
ip4 NAT :PREROUTING ACCEPT
ip4 NAT :OUTPUT ACCEPT
ip4 NAT :POSTROUTING ACCEPT
ipboth FILTER :INPUT DROP
ipboth FILTER :FORWARD DROP
ipboth FILTER :OUTPUT DROP
}

rules() { # Use no "double quotes" in rules!
# DNAT
 # modify DNAT
 ip4 NAT :DNAT_MOD -
 ip4 NAT -A PREROUTING -j DNAT_MOD

 # do not change destination IP/port for these packets
 ip4 NAT -A DNAT_MOD -i eth0 -p icmp -j RETURN
 ip4 NAT :DNAT_SKIP -
 ip4 NAT -A DNAT_MOD -i eth0 -g DNAT_SKIP

 # manual port forwarding
 ip4 NAT :MANUAL_DNAT -
 ip4 NAT -A DNAT_MOD -i eth0 -j MANUAL_DNAT
 ## example: to specific host (modify static-hosts.conf if necessary)
 #ip4 NAT -A MANUAL_DNAT -p tcp -m tcp --dport 33333 -j DNAT --to-destination 192.0.2.10
 ## example: to specific host and different destination port (modify static-hosts.conf if necessary)
 #ip4 NAT -A MANUAL_DNAT -p tcp -m tcp --dport 81 -j DNAT --to-destination 192.0.3.11:80
 ## example: to different destination port on router
 #ip4 NAT -A MANUAL_DNAT -p tcp -m tcp --dport 81 -j DNAT --to-destination :80

 # upnp
 ip4 NAT :DNAT_UPNP -
 ip4 NAT -A DNAT_MOD -i eth0 -j DNAT_UPNP
 ## example, from linux-igd upnpd
 ##ip4 NAT -A DNAT_UPNP -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.0.2.96:80

 # forward all remaining ports
 ip4 NAT :DNAT_ALLPORTS -
 ip4 NAT -A DNAT_MOD -i eth0 -j DNAT_ALLPORTS
 #ip4 NAT -A DNAT_ALLPORTS -j DNAT --to-destination 192.0.2.10
# END DNAT

# masquerading
ip4 NAT -A POSTROUTING -s 192.0.2.0/24 ! -d 192.0.2.0/24 -o eth0 -j MASQUERADE
ip4 NAT -A POSTROUTING -s 192.0.3.0/24 ! -d 192.0.3.0/24 -o eth0 -j MASQUERADE

# IPv6
ip4 FILTER -A INPUT -p ipv6 -j ACCEPT
ip4 FILTER -A FORWARD -p ipv6 -j ACCEPT
ip4 FILTER -A OUTPUT -p ipv6 -j ACCEPT

# loopback
ipboth FILTER -A INPUT -i lo -j ACCEPT
ipboth FILTER -A OUTPUT -o lo -j ACCEPT

# BLOCKING
 # drop RH0
 ip6tables -A INPUT -m rt --rt-type 0 -j DROP
 ip6tables -A FORWARD -m rt --rt-type 0 -j DROP
 ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP
  
 # host block
 ipboth FILTER :HOST_BLOCK -
 ipboth FILTER -A INPUT -j HOST_BLOCK
 ipboth FILTER -A FORWARD -j HOST_BLOCK
 ipboth FILTER -A OUTPUT -j HOST_BLOCK
 ## examples
 # ipboth FILTER -A HOST_BLOCK --source 75.0.1.25 -j HOST_BLOCK_EXEC
 # ipboth FILTER -A HOST_BLOCK --destination 75.0.1.25 -j HOST_BLOCK_EXEC
 ipboth FILTER :HOST_BLOCK_EXEC -
 ipboth FILTER -A HOST_BLOCK_EXEC -m limit --limit 1/min --limit-burst 1 -j LOG --log-prefix Blocked-host_ --log-level notice
 ipboth FILTER -A HOST_BLOCK_EXEC -j DROP
  
 # invalid
 ipboth FILTER :VALIDITY_CHECK -
 ipboth FILTER :INVALID -
 ipboth FILTER -A INPUT -j VALIDITY_CHECK
 ipboth FILTER -A FORWARD -j VALIDITY_CHECK  
 ipboth FILTER -A VALIDITY_CHECK -m state --state INVALID -j INVALID
 ipboth FILTER -A INVALID -m limit --limit 6/min --limit-burst 2 -j LOG --log-prefix Invalid-packet_ --log-level info
 ipboth FILTER -A INVALID -j DROP
 ## more validity checks here, like previous line

 # fragmented
 ipboth FILTER :FRAGMENT_CHECK -
 ipboth FILTER -A INPUT -j FRAGMENT_CHECK
 ipboth FILTER -A FORWARD -j FRAGMENT_CHECK
 ipboth FILTER :FRAGMENTED -
 ip4 FILTER -A FRAGMENT_CHECK -f -j FRAGMENTED
 ip6 FILTER -A FRAGMENT_CHECK -m frag --fragmore -m length --length 0:1279 -j FRAGMENTED
 ipboth FILTER -A FRAGMENTED -m limit --limit 3/min --limit-burst 1 -j LOG --log-prefix Fragmented-packet_ --log-level info
 ipboth FILTER -A FRAGMENTED -j DROP  
# END BLOCKING

# local dhcp
ipboth FILTER -A INPUT -p udp -i br0 --sport 67:68 --dport 67:68 -j ACCEPT
ipboth FILTER -A INPUT -p udp -i wlan0_0 --sport 67:68 --dport 67:68 -j ACCEPT
# out
ipboth FILTER -A OUTPUT -p udp -o br0 --sport 67:68 --dport 67:68 -j ACCEPT
ipboth FILTER -A OUTPUT -p udp -o wlan0_0 --sport 67:68 --dport 67:68 -j ACCEPT

# spoofed
ipboth FILTER :SPOOFED -
ip4 FILTER -A INPUT -j SPOOFED # TODO: add ip6 here
ip4 FILTER -A FORWARD -j SPOOFED # TODO: add ip6 here
ipboth FILTER -A SPOOFED -i eth0 -j RETURN
ip6 FILTER -A SPOOFED -i aiccu -j RETURN
ip4 FILTER -A SPOOFED -i br0 -s 192.0.2.0/24 -j RETURN
#ip6 FILTER -A SPOOFED -i br0 -s :: -j RETURN # TODO: fix with correct ipv6 addresses
ip4 FILTER -A SPOOFED -i wlan0_0 -s 192.0.3.0/24 -j RETURN
#ip6 FILTER -A SPOOFED -i wlan0_0 -s :: -j RETURN # TODO: fix with correct ipv6 addresses
ipboth FILTER -A SPOOFED -m limit --limit 6/min -j LOG --log-prefix Spoofed-packet_ --log-level notice
ip4 FILTER -A SPOOFED -j REJECT --reject-with icmp-net-unreachable
ip6 FILTER -A SPOOFED -j REJECT --reject-with icmp6-adm-prohibited

# ICMP
ip4 FILTER -A OUTPUT -p icmp -j ACCEPT
ip6 FILTER -A OUTPUT -p ipv6-icmp -j ACCEPT
ipboth FILTER :ICMP -
ip4 FILTER -A INPUT -p icmp -j ICMP
ip6 FILTER -A INPUT -p ipv6-icmp -j ICMP
ip4 FILTER -A FORWARD -p icmp -j ICMP
ip6 FILTER -A FORWARD -p ipv6-icmp -j ICMP
ipboth FILTER -A ICMP -m limit --limit 20/sec --limit-burst 100 -j ACCEPT
ip4 FILTER -A ICMP -p icmp -m icmp --icmp-type echo-request -j DROP
ip6 FILTER -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j DROP
ipboth FILTER -A ICMP -m limit --limit 20/sec -j ACCEPT
ipboth FILTER -A ICMP -j DROP

# established connections
ipboth FILTER -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ipboth FILTER -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
ipboth FILTER -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SPECIFIC SERVICES
 # ssh
 ip4 NAT -A DNAT_SKIP -p tcp --dport ssh -j RETURN
 ipboth FILTER -A INPUT -p tcp --dport ssh -j ACCEPT
 ipboth FILTER -A OUTPUT -p tcp --dport ssh -j ACCEPT

 # upstream dhcp
 ip4 NAT -A DNAT_SKIP -p tcp --dport 67:68 -j RETURN
 ipboth FILTER -A INPUT -p udp -i eth0 --sport 67:68 --dport 67:68 -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o eth0 --sport 67:68 --dport 67:68 -j ACCEPT

 # ddns
 ipboth FILTER -A OUTPUT -p tcp -o eth0 --dport 5000 -j ACCEPT #*check*# port 5000?
 ipboth FILTER -A OUTPUT -p tcp -o aiccu --dport 5000 -j ACCEPT #*check*# port 5000?   

 # SixXS
 ip4 NAT -A DNAT_SKIP -p tcp --dport 3874 -j RETURN
 ip4 NAT -A DNAT_SKIP -p udp -m multiport --dport 3740,5072 -j RETURN
 ip4 FILTER -A OUTPUT -p tcp -o eth0 --dport 3874 -j ACCEPT
 ip4 FILTER -A OUTPUT -p udp -o eth0 -m multiport --dport 3740,5072 -j ACCEPT

 # dns
 ip4 NAT -A DNAT_SKIP -p tcp -m multiport --dport domain,mdns -j RETURN
 ip4 NAT -A DNAT_SKIP -p udp -m multiport --dport domain,mdns -j RETURN
 ipboth FILTER -A INPUT -p tcp -i br0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A INPUT -p udp -i br0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A INPUT -p tcp -i wlan0_0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A INPUT -p udp -i wlan0_0 -m multiport --dport domain,mdns -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o br0 --dport mdns -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o wlan0_0 --dport mdns -j ACCEPT  
 ipboth FILTER -A OUTPUT -p tcp -o eth0 --dport domain -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp -o eth0 --dport domain -j ACCEPT
 ip6 FILTER -A OUTPUT -p tcp -o aiccu --dport domain -j ACCEPT
 ip6 FILTER -A OUTPUT -p udp -o aiccu --dport domain -j ACCEPT

 # ntp
 ip4 NAT -A DNAT_SKIP -p udp --dport ntp -j RETURN
 ipboth FILTER -A INPUT -p udp --dport ntp -j ACCEPT
 ipboth FILTER -A OUTPUT -p udp --sport ntp -j ACCEPT

 # www/https
 ip4 NAT -A DNAT_SKIP -p tcp --dport www -j RETURN
 ipboth FILTER -A INPUT -p tcp --dport www -j ACCEPT
 ipboth FILTER -A OUTPUT -p tcp -o eth0 -m multiport --dports www,https -j ACCEPT      
 ip6 FILTER -A OUTPUT -p tcp -o aiccu -m multiport --dports www,https -j ACCEPT

 # upnp
 ip4 NAT -A DNAT_SKIP -p tcp -m multiport --dports 5000,49152 -j RETURN
 ip4 NAT -A DNAT_SKIP -p udp --dport 1900 -j RETURN
 ip4 FILTER :UPNP_FORWARD -
 ip4 FILTER -A INPUT -i br0 -p udp -m multiport --ports 1900 -j ACCEPT
 ip4 FILTER -A INPUT -i br0 -p tcp -m multiport --ports 2869,5000,49152 -j ACCEPT
 ip4 FILTER -A INPUT -i br0 -p igmp -j ACCEPT
 ip4 FILTER -A OUTPUT -o br0 -p udp -m multiport --ports 1900 -j ACCEPT
 ip4 FILTER -A OUTPUT -o br0 -p tcp -m multiport --ports 2869,5000,49152 -j ACCEPT
 ip4 FILTER -A OUTPUT -o br0 -p igmp -j ACCEPT
 ip4 FILTER -A FORWARD -i eth0 -o br0 -j UPNP_FORWARD
 ## example, from linux-igd upnpd
 ##ip4 FILTER -A UPNP_FORWARD -d 192.0.2.10/24 -p tcp -m tcp --dport 80 -j ACCEPT
# END SPECIFIC SERVICES

# from private
ipboth FILTER :FROM_PRIVATE -
ipboth FILTER -A FORWARD -i br0 -j FROM_PRIVATE
ipboth FILTER -A FROM_PRIVATE -o br0 -j ACCEPT
ipboth FILTER -A FROM_PRIVATE -o eth0 -j ACCEPT
ipboth FILTER -A FROM_PRIVATE -o aiccu -j ACCEPT
ipboth FILTER -A FROM_PRIVATE -o wlan0_0 -m limit --limit 3/min -j LOG --log-prefix Rejected-private-to-public_ --log-level info
ip4 FILTER -A FROM_PRIVATE -o wlan0_0 -j REJECT --reject-with icmp-net-prohibited
ip6 FILTER -A FROM_PRIVATE -o wlan0_0 -j REJECT --reject-with icmp6-adm-prohibited

# from public
ipboth FILTER :FROM_PUBLIC -
ipboth FILTER -A FORWARD -i wlan0_0 -j FROM_PUBLIC
ipboth FILTER -A FROM_PUBLIC -o eth0 -j ACCEPT
ipboth FILTER -A FROM_PUBLIC -o aiccu -j ACCEPT
ipboth FILTER -A FROM_PUBLIC -o br0 -m limit --limit 3/min -j LOG --log-prefix Rejected-public-to-private_ --log-level info
ip4 FILTER -A FROM_PUBLIC -o br0 -j REJECT --reject-with icmp-net-prohibited
ip6 FILTER -A FROM_PUBLIC -o br0 -j REJECT --reject-with icmp6-adm-prohibited
ipboth FILTER -A FROM_PUBLIC -o wlan0_0 -m limit --limit 3/min -j LOG --log-prefix Rejected-public-to-public_ --log-level info
ip4 FILTER -A FROM_PUBLIC -o wlan0_0 -j REJECT --reject-with icmp-host-prohibited
ip6 FILTER -A FROM_PUBLIC -o wlan0_0 -j REJECT --reject-with icmp6-adm-prohibited

# DROP/REJECT
 # unmatched packets
 ip4 FILTER -A INPUT -m limit --limit 20/min -j LOG --log-prefix Unmatched-INPUT_ --log-level debug
 ip6 FILTER -A INPUT -m limit --limit 20/min -j LOG --log-prefix Unmatched-v6-INPUT_ --log-level debug
 ip4 FILTER -A FORWARD -m limit --limit 20/min -j LOG --log-prefix Unmatched-FORWARD_ --log-level debug
 ip6 FILTER -A FORWARD -m limit --limit 20/min -j LOG --log-prefix Unmatched-v6-FORWARD_ --log-level debug
 ip4 FILTER -A OUTPUT -j LOG --log-prefix Unmatched-OUTPUT_ --log-level debug
 ip6 FILTER -A OUTPUT -j LOG --log-prefix Unmatched-v6-OUTPUT_ --log-level debug
# end DROP/REJECT

# TOS
 ipboth MANGLE :TOS_CHAIN -
 ipboth MANGLE -A PREROUTING -j TOS_CHAIN

 # Correcting TOS for incorrectly marked packets
 ipboth MANGLE :FIX_TOS -
 ipboth MANGLE -A TOS_CHAIN -m tos ! --tos Normal-Service -j FIX_TOS
  # Large packets with Minimize-Delay TOS
  ipboth MANGLE -A FIX_TOS -m tos ! --tos Minimize-Delay -j RETURN
  ipboth MANGLE -A FIX_TOS -p tcp -m length --length 0:512  -j RETURN
  ipboth MANGLE -A FIX_TOS -p udp -m length --length 0:1024 -j RETURN
  ipboth MANGLE -A FIX_TOS -j TOS --set-tos Maximize-Throughput

 # Add TOS for unmarked packets
 ipboth MANGLE :ADD_TOS -
 ipboth MANGLE -A TOS_CHAIN -m tos --tos Normal-Service -j ADD_TOS
  # TCP control packets (from www.docum.org / Stef Coene)
  ipboth MANGLE :ACK_TOS -
  ipboth MANGLE -A ADD_TOS -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j ACK_TOS
  ipboth MANGLE -A ACK_TOS -m length --length 0:256 -j TOS --set-tos Minimize-Delay
  ipboth MANGLE -A ACK_TOS -m length --length 256: -j TOS --set-tos Maximize-Throughput
  ipboth MANGLE -A ADD_TOS -p tcp --tcp-flags SYN,RST,ACK ACK -j RETURN
  # Specify general TOS settings here for protocol/port
  ipboth MANGLE -A ADD_TOS -p icmp -j TOS --set-tos Minimize-Delay
  ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports smtp -j TOS --set-tos Minimize-Cost
  #ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports 000 -j TOS --set-tos Maximize-Reliability
  ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports www,https -j TOS --set-tos Maximize-Throughput
  ipboth MANGLE -A ADD_TOS -p tcp -m multiport --ports domain,mdns,auth,5154,3389,5900 -j TOS --set-tos Minimize-Delay
  #ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports 000 -j TOS --set-tos Minimize-Cost
  #ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports 000 -j TOS --set-tos Maximize-Reliability
  #ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports 000 -j TOS --set-tos Maximize-Throughput
  ipboth MANGLE -A ADD_TOS -p udp -m multiport --ports domain,67:68,ntp,5154,5060:5064,iax,1720,1731 -j TOS --set-tos Minimize-Delay
# END TOS

# SHAPING
 # add shaping assist fwmarks
 ipboth MANGLE :MARKING_IN -
 ipboth MANGLE -A PREROUTING -j MARKING_IN
  ipboth MANGLE -A MARKING_IN -i eth0 -j RETURN
  ipboth MANGLE -A MARKING_IN -i aiccu -j RETURN
  ipboth MANGLE -A MARKING_IN -i br0 -j MARK --set-mark 0x2/0xf
  ipboth MANGLE -A MARKING_IN -i br0 -j RETURN
  ipboth MANGLE -A MARKING_IN -i wlan0_0 -j MARK --set-mark 0x3/0xf
 ip4 MANGLE -A OUTPUT -j MARK --set-mark 0x4/0xf #*check* breaks radvd on ipv6 side
# END SHAPING

# TCPMSS clamp
ipboth MANGLE -A POSTROUTING -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ipboth MANGLE -A POSTROUTING -o aiccu -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
}


# build
IPTABLES=$( mktemp /tmp/iptables.XXX )
IP6TABLES=$( mktemp /tmp/ip6tables.XXX )
RAW_IP4=$( mktemp )
MANGLE_IP4=$( mktemp )
NAT_IP4=$( mktemp )
FILTER_IP4=$( mktemp )
RAW_IP6=$( mktemp )
MANGLE_IP6=$( mktemp )
FILTER_IP6=$( mktemp )
ip4() {
 TABLE=$( eval "echo \$${1}_IP4" )
 shift 1
 echo $* >> $TABLE
}
ip6() {
 TABLE=$( eval "echo \$${1}_IP6" )
 shift 1
 echo $* >> $TABLE
}
ipboth() {
 ip4 $@  
 ip6 $@
}
ipboth RAW "*raw"
ipboth MANGLE "*mangle"
ip4 NAT "*nat"
ipboth FILTER "*filter"
policies
rules
for TABLE in RAW_IP4 MANGLE_IP4 NAT_IP4 FILTER_IP4 RAW_IP6 MANGLE_IP6 FILTER_IP6 ; do
 eval "echo COMMIT >> \$${TABLE}"
done
echo "# iptables firewall for owenhs" >> $IPTABLES
echo "# ip6tables firewall for owenhs" >> $IP6TABLES
cat $RAW_IP4 $MANGLE_IP4 $NAT_IP4 $FILTER_IP4 >> $IPTABLES
cat $RAW_IP6 $MANGLE_IP6 $FILTER_IP6 >> $IP6TABLES
rm -f $RAW_IP4 $MANGLE_IP4 $NAT_IP4 $FILTER_IP4 $RAW_IP6 $MANGLE_IP6 $FILTER_IP6
case "$1" in
 apply)
  iptables-apply -t 30 $IPTABLES
  ip6tables-apply -t 30 $IP6TABLES
  echo "iptables and ip6tables applied successfully"
  rm -f $IPTABLES $IP6TABLES
  ;;
 restore)
  iptables-restore $IPTABLES
  ip6tables-restore $IP6TABLES
  echo "iptables and ip6tables restored successfully"
  rm -f $IPTABLES $IP6TABLES
  ;;
 build) 
  echo "new: $IPTABLES"
  echo "new: $IP6TABLES"
  ;;   
 save)
  iptables-restore $IPTABLES
  ip6tables-restore $IP6TABLES
  mv /etc/network/iptables /tmp/iptables.bak0
  mv /etc/network/ip6tables /tmp/ip6tables.bak0
  mv $IPTABLES /etc/network/iptables
  mv $IP6TABLES /etc/network/ip6tables
  mv /tmp/iptables.bak0 $IPTABLES
  mv /tmp/ip6tables.bak0 $IP6TABLES
  echo "old: $IPTABLES"
  echo "old: $IP6TABLES"
  ;;
esac

UPnP

upnpd.conf... TODO

hostap

hostapd.conf... TODO

IPv6

IPv6... TODO

Traffic Control

script... TODO

Comments

Feedback is appreciated.

  • I'd suggest recording the installation parts in the InstallingDebianOn namespace -- PaulWise 2010-02-21 01:01:02

    • Thanks Paul, but I do not plan to include any hardware-specific installation information. I added a note above. -- ?green 2010-02-21 03:08:07

      • Contributing to InstallingDebianOn would still be appreciated, as would the hardware info that the InstallingDebianOn templates suggest to add -- PaulWise 2010-02-21 12:37:45

        • Done, though it probably needs further work. -- ?green 2010-02-22 03:38:53