35456
Comment: update Basic Networking section
|
35455
rsyslog section update
|
Deletions are marked like this. | Additions are marked like this. |
Line 871: | Line 871: |
= rsyslogd = | = rsyslog = |
I have been working to set up a Soekris net5501 to act as a home router/server. My efforts are documented here to serve as an example for others attempting similar setup scenarios. 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.
Good luck with your challenge! If you notice any error please mail me, leave a ?comment, or fix it.
If you know of a better place in the wiki for this to go, please ?suggest it.
Contents
Requirements
Here is a list of requirements with links to the relevant sections.
- 100% Debian, no external software
- Stock Debian kernel
?dnsmasq server, providing
- DNS, including local DNS
- DHCP server, including static IPs
Support dual-stack network; IPv4 and IPv6 - ?SixXS
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
Carefully controlled log files - ?rsyslogd
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 hostapd /etc/hostapd/hostapd.conf # this starts hostapd 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
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
Note that UPnP has some flaws. Use it only if you understand and accept them. If you choose not to use UPnP, you should remove the applicable parts of the firewall script.
/etc/default/linux-igd:
EXTIFACE=eth0 INTIFACE=br0 ALLOW_MULTICAST=yes
/etc/upnpd.conf:
iptables_location = "/sbin/iptables" debug_mode = 3 create_forward_rules = yes forward_rules_append = no forward_chain_name = UPNP_FORWARD prerouting_chain_name = DNAT_UPNP duration = 86400 # One day from time of addition description_document_name = gatedesc.xml xml_document_path = /etc/linuxigd listenport = 49152 paranoid = 1
hostapd
It seemed to work best to start hostapd from /etc/network/interfaces rather than init.
hostapd.conf:
interface=wlan0 bridge=br0 driver=nl80211 logger_syslog=-1 logger_stdout=-1 logger_syslog_level=2 logger_stdout_level=4 dump_file=/tmp/hostapd.dump ctrl_interface=/var/run/hostapd ssid=private country_code=US ieee80211d=1 hw_mode=g channel=10 beacon_int=100 max_num_sta=255 rts_threshold=2347 fragm_threshold=2346 preamble=1 macaddr_acl=0 accept_mac_file=/etc/hostapd/hostapd.accept deny_mac_file=/etc/hostapd/hostapd.deny ignore_broadcast_ssid=0 ap_max_inactivity=300 ieee8021x=0 eap_server=0 wpa=3 wpa_passphrase=passphrase wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256 wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP wpa_strict_rekey=1 ieee80211w=1 bss=wlan0_0 bssid=02:xx:xx:xx:xx:xx # use your wireless MAC address, just change the first character pair ssid=public wpa=0
Traffic Control
Create /usr/local/sbin/shaping.sh:
#!/bin/sh # What markup will make this line correct? set -e # Default up/down values in kilobytes/s DOWN=50 UP=30 # Tested up/down values in bytes/s if DOWN_TESTED=$( cat /var/local/down-bytes.txt 2> /dev/null ) ; then DOWN=$DOWN_TESTED else DOWN=$( echo "$DOWN * 1024" | bc ) fi if UP_TESTED=$( cat /var/local/up-bytes.txt 2> /dev/null ) ; then UP=$UP_TESTED else UP=$( echo "$UP * 1024" | bc ) fi # Drop to safe percentage of tested bandwidth DOWN=$(( $DOWN * 90 / 100 )) UP=$(( $UP * 90 / 100 )) remove() { for DEV in eth0 sit1 eth1 eth2 eth3 wlan0 wlan0_0 ; do tc qdisc del dev $DEV root 2> /dev/null || true done } case "$1" in start|restart) remove ;; stop) remove exit 0 ;; status) echo "[qdisc]" tc -s qdisc show dev $DEV echo "[class]" tc -s class show dev $DEV echo "[filter]" tc -s filter show dev $DEV exit 0 ;; rates) tc class change dev eth0 parent 0x1:0x0 classid 0x1:0x1 hfsc ls m2 7bps ul m2 ${UP}bps for DEV in eth1 eth2 eth3 wlan0 ; do tc class change dev $DEV parent 0x1:0x1 classid 0x1:0x2 hfsc ls m2 50bps ul m2 $(($DOWN *8/10))bps done tc class change dev wlan0_0 parent 0x1:0x1 classid 0x1:0x3 hfsc ls m2 25bps ul m2 $(($DOWN *4/10))bps exit ;; *) echo "Usage: $0 {start|stop|status|restart|rates}" exit 1 ;; esac # DESCRIPTION CLASSID INTERFACES RT LS UL RATES (bps & s; without commas=m2 only) # root qdisc HFSC 0x1:0x0 all N N N # + root class 0x1:0x1 all N Y N ls=7 # + private 0x1:0x2 eth0,eth1,eth2,eth3,wlan0 N Y Y ls=50; ul(all,-eth0)=$DOWN*8/10 # + prio 1 0x1:0x21 Y Y N rt=3072; ls=6 # + prio 2 0x1:0x22 Y Y N rt=1024; ls=5,20,4 # + prio 3 0x1:0x23 Y Y N rt=1024; ls=4,7,3 # + public 0x1:0x3 eth0,wlan0_0 N Y Y ls=25; ul(wlan0_0)=$DOWN*5/10 # + prio 1 0x1:0x31 Y Y N rt=3072; ls=6 # + prio 2 0x1:0x32 Y Y N rt=1024; ls=5,20,4 # + prio 3 0x1:0x33 Y Y N rt=1024; ls=4,7,3 # + router 0x1:0x4 all N Y N ls=25 # + prio 1 0x1:0x41 Y Y N rt=3072; ls=6 # + prio 2 0x1:0x42 Y Y N rt=1024; ls=5,20,4 # + prio 3 0x1:0x43 Y Y N rt=1024; ls=4,7,3 # + default class 0x1:0x5 all N Y N ls=3 # root HFSC qdisc 0x1:0x0 # default class 0x1:0x5 for DEV in eth0 eth1 eth2 eth3 wlan0 wlan0_0 ; do tc qdisc add dev $DEV handle 0x1:0x0 root hfsc default 0x5 tc class add dev $DEV parent 0x1:0x0 classid 0x1:0x5 hfsc ls m2 3bps done # root class 0x1:0x1 tc class add dev eth0 parent 0x1:0x0 classid 0x1:0x1 hfsc ls m2 7bps ul m2 ${UP}bps for DEV in eth1 eth2 eth3 wlan0 ; do tc class add dev $DEV parent 0x1:0x0 classid 0x1:0x1 hfsc ls m2 7bps done tc class add dev wlan0_0 parent 0x1:0x0 classid 0x1:0x1 hfsc ls m2 7bps # primary classes 0x1:0x2-0x4 (private=2,public=3,router=4) # filters at 0x1:0x0 to drop packets in one of 0x1:0x2-0x4 tc class add dev eth0 parent 0x1:0x1 classid 0x1:0x2 hfsc ls m2 50bps # private tc class add dev eth0 parent 0x1:0x1 classid 0x1:0x3 hfsc ls m2 25bps # public tc class add dev eth0 parent 0x1:0x1 classid 0x1:0x4 hfsc ls m2 25bps # router tc filter add dev eth0 parent 0x1:0x0 protocol ip prio 1 handle 2 fw flowid 0x1:0x2 # private tc filter add dev eth0 parent 0x1:0x0 protocol ip prio 1 handle 3 fw flowid 0x1:0x3 # public tc filter add dev eth0 parent 0x1:0x0 protocol ip prio 1 handle 4 fw flowid 0x1:0x4 # router for DEV in eth1 eth2 eth3 wlan0 ; do tc class add dev $DEV parent 0x1:0x1 classid 0x1:0x2 hfsc ls m2 50bps ul m2 $(($DOWN *8/10))bps # private tc class add dev $DEV parent 0x1:0x1 classid 0x1:0x4 hfsc ls m2 25bps # router tc filter add dev $DEV parent 0x1:0x0 protocol ip prio 1 handle 4 fw flowid 0x1:0x4 # router tc filter add dev $DEV parent 0x1:0x0 protocol ip prio 2 u32 match ip src 0.0.0.0/0 flowid 0x1:0x2 # other done tc class add dev wlan0_0 parent 0x1:0x1 classid 0x1:0x3 hfsc ls m2 25bps ul m2 $(($DOWN *4/10))bps # public tc class add dev wlan0_0 parent 0x1:0x1 classid 0x1:0x4 hfsc ls m2 25bps # router tc filter add dev wlan0_0 parent 0x1:0x0 protocol ip prio 1 handle 4 fw flowid 0x1:0x4 # router tc filter add dev wlan0_0 parent 0x1:0x0 protocol ip prio 2 u32 match ip src 0.0.0.0/0 flowid 0x1:0x3 # other # secondary classes and filters (priority) # classids 0x1:0x21-0x23 (private group); filters at 0x1:0x2 secondary_classes() { tc class add dev $DEV parent 0x1:0x$PARENT classid 0x1:0x${PARENT}1 hfsc ls m2 6bps rt m2 3072bps # 0 interactive tc class add dev $DEV parent 0x1:0x$PARENT classid 0x1:0x${PARENT}2 hfsc ls m1 5bps d 20s m2 4bps rt m2 1024bps # 1 best-effort,int-bulk tc class add dev $DEV parent 0x1:0x$PARENT classid 0x1:0x${PARENT}3 hfsc ls m1 4bps d 7s m2 3bps rt m2 1024bps # 2 filler,bulk tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip protocol 1 0xff flowid 0x1:0x${PARENT}1 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip protocol 58 0xff flowid 0x1:0x${PARENT}1 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x10 0xff flowid 0x1:0x${PARENT}1 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x12 0xff flowid 0x1:0x${PARENT}1 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x14 0xff flowid 0x1:0x${PARENT}1 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x16 0xff flowid 0x1:0x${PARENT}1 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x00 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x04 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x06 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x18 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x1a 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x1c 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 1 u32 match ip tos 0x1e 0xff flowid 0x1:0x${PARENT}2 tc filter add dev $DEV parent 0x1:0x$PARENT protocol ip prio 2 u32 match ip src 0.0.0.0/0 flowid 0x1:0x${PARENT}3 } PARENT=2 # private for DEV in eth0 eth1 eth2 eth3 wlan0 ; do secondary_classes done PARENT=3 # public for DEV in eth0 wlan0_0 ; do secondary_classes done PARENT=4 # router for DEV in eth0 eth1 eth2 eth3 wlan0 wlan0_0 ; do secondary_classes done
For bandwidth testing, you could create /usr/local/sbin/bandwidth-test.sh:
#!/bin/sh # What markup will make this line correct? set -e MAXTIME=30 # get previous limits UP_OLD=$( cat /var/local/up-bytes.txt 2> /dev/null ) || true DOWN_OLD=$( cat /var/local/down-bytes.txt 2> /dev/null ) || true # set limits high for testing echo 2072576 >| /var/local/up-bytes.txt echo 2072576 >| /var/local/down-bytes.txt # set shaping rates shaping.sh rates # start measuring OUTPUT=$( mktemp ) FILTERED=$( mktemp ) bwm-ng -T max -I eth0 -o csv -c 0 >> $OUTPUT & MON_PID=$! # Use the network as much as possible, both up and down, here TMPFILE=$( mktemp /tmp/testfile_rand_5m.XXX ) dd if=/dev/urandom of=$TMPFILE bs=1048576 count=16 2> /dev/null & DD_PID=$! ## DOWN echo "starting DOWN" curl --ipv4 --silent --max-time $MAXTIME "http://linux.mirrors.es.net/fedora/releases/12/Fedora/i386/iso/Fedora-12-i386-disc1.iso" > /dev/null || true & DOWN1_PID=$! curl --ipv4 --silent --max-time $MAXTIME "http://nas1.itc.virginia.edu/fedora/releases/12/Fedora/i386/iso/Fedora-12-i386-DVD.iso" > /dev/null || true & DOWN2_PID=$! wait $DOWN1_PID wait $DOWN2_PID echo "finished DOWN" ## UP sleep 2s wait $DD_PID echo "starting UP" curl --ipv4 --silent --max-time $MAXTIME --form file=@$TMPFILE http://www.senduit.com/ > /dev/null || true & UP1_PID=$! wait $UP1_PID echo "finished UP" rm -f $TMPFILE # stop measuring kill -s INT $MON_PID wait $MON_PID tail -n 2 < $OUTPUT | grep eth0 >> $FILTERED # Write new limits gawk -F ";" '{ print $3 }' < $FILTERED | sed -r 's/\..*$//' >| /var/local/up-bytes.txt gawk -F ";" '{ print $4 }' < $FILTERED | sed -r 's/\..*$//' >| /var/local/down-bytes.txt # Apply new limits shaping.sh rates rm -f $OUTPUT rm -f $FILTERED
rsyslog
Logging everything to rsyslog and then to only a few files helps keep logging simpler and disk usage more easily controlled. To see a particular facility or priority, use grep.
First, create a log rotation script /usr/local/sbin/clogrotate.sh:
#!/bin/sh # What markup will make this line correct? # rotates channel logs; executed by rsyslog (see rsyslog.conf) mv -f $1 ${1}.1 #gzip ${1}.1 # disabled because I'm running on Flash media
Then rsyslog.conf:
# [modules] $ModLoad imuxsock # provides support for local system logging $ModLoad imklog # provides kernel logging support # [templates] $template FullFileFormat,"%timestamp:::date-rfc3339% %syslogfacility-text%.%syslogseverity-text% %syslogtag%%msg%\n" $ActionFileDefaultTemplate FullFileFormat # [log file permissions] $FileOwner root $FileGroup adm $FileCreateMode 0640 $DirCreateMode 0755 $Umask 0022 # [channels] $outchannel systemlog,/var/log/systemlog,104857600,clogrotate.sh /var/log/systemlog $outchannel errlog,/var/log/errlog,26214400,clogrotate.sh /var/log/errlog # [main] $IncludeConfig /etc/rsyslog.d/*.conf *.emerg * *.err $errlog *.notice $systemlog
Finish
Make those scripts executable: chmod u+x /usr/local/sbin/*
Save the firewall scripts: build-firewall.sh save
/etc/rc.local should look like this:
#!/bin/sh # What markup will make this line correct? failed() { /usr/bin/logger -p local0.debug -t "`basename $0`[$$]" "$*" echo "$*" | mail -s "Startup failure" root } iptables-restore /etc/network/iptables || failed "iptables" ip6tables-restore /etc/network/ip6tables || failed "ip6tables" /usr/local/sbin/shaping.sh start || failed "shaping.sh"
Contact/Comments
Feedback is appreciated.
You can contact me at greenfreedom10@gmail.com.
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