1#!/bin/bash 2# (using bashism: arrays) 3 4user="root" 5reset_all_netdevs=true 6preferred_default_route_iface="if" 7extif="if" 8ext_open_tcp="22 80 88" # space-separated 9 10# Make ourself one-shot 11svc -o . 12# Debug 13#date '+%Y-%m-%d %H:%M:%S' >>"$0.log" 14 15service=`basename $PWD` 16rundir="/var/run/service/$service" 17 18### filter This is the default table (if no -t option is passed). It contains 19### the built-in chains INPUT (for packets coming into the box itself), 20### FORWARD (for packets being routed through the box), and OUTPUT (for 21### locally-generated packets). 22### 23### nat This table is consulted when a packet that creates a new connection 24### is encountered. It consists of three built-ins: PREROUTING (for 25### altering packets as soon as they come in), OUTPUT (for altering 26### locally-generated packets before routing), and POSTROUTING (for 27### altering packets as they are about to go out). 28### 29### mangle It had two built-in chains: PREROUTING (for altering incoming 30### packets before routing) and OUTPUT (for altering locally-generated 31### packets before routing). Recently three other built-in 32### chains are added: INPUT (for packets coming into the box 33### itself), FORWARD (for altering packets being routed through the 34### box), and POSTROUTING (for altering packets as they are about to go 35### out). 36### 37### ...iface... ...iface... 38### | ^ 39### v | 40### -mangle,NAT- -mangle,filter- -mangle,NAT-- 41### |PREROUTING|-->[Routing]-->|FORWARD |-->|POSTROUTING| 42### ------------ | ^ --------------- ------------- 43### | | ^ 44### | +--if NATed------------+ | 45### v | | 46### -mangle,filter- -mangle,NAT,filter- 47### |INPUT | +->[Routing]->|OUTPUT | 48### --------------- | ------------------- 49### | | 50### v | 51### ... Local Process... 52 53doit() { 54 echo "# $*" 55 "$@" 56} 57 58#exec >/dev/null 59exec >"$0.out" 60exec 2>&1 61exec </dev/null 62 63umask 077 64 65# Make sure rundir/ exists 66mkdir -p "$rundir" 2>/dev/null 67chown -R "$user": "$rundir" 68chmod -R a=rX "$rundir" 69rm -rf rundir 2>/dev/null 70ln -s "$rundir" rundir 71 72# Timestamping 73date '+%Y-%m-%d %H:%M:%S' 74 75echo; echo "* Reading IP config" 76cfg=-1 77# static cfg dhcp,zeroconf etc 78for ipconf in conf/*.ipconf "$rundir"/*.ipconf; do 79 if test -f "$ipconf"; then 80 echo "+ $ipconf" 81 . "$ipconf" 82 fi 83done 84 85echo; echo "* Configuring hardware" 86#doit ethtool -s if autoneg off speed 100 duplex full 87#doit ethtool -K if rx off tx off sg off tso off 88 89echo; echo "* Resetting address and routing info" 90if $reset_all_netdevs; then 91 devs=`sed -n 's/ //g;s/:.*$//p' </proc/net/dev` 92 for iface in $devs; do 93 doit ip a f dev "$iface" 94 doit ip r f dev "$iface" root 0/0 95 done 96else 97 doit ip a f dev lo 98 i=0; while test "${if[$i]}"; do 99 doit ip a f dev "${if[$i]}" 100 doit ip r f dev "${if[$i]}" root 0/0 101 let i++; done 102fi 103 104echo; echo "* Configuring addresses" 105doit ip a a dev lo 127.0.0.1/8 scope host 106doit ip a a dev lo ::1/128 scope host 107i=0; while test "${if[$i]}"; do 108 if test "${ipmask[$i]}"; then 109 doit ip a a dev "${if[$i]}" "${ipmask[$i]}" brd + 110 doit ip l set dev "${if[$i]}" up 111 fi 112let i++; done 113 114echo; echo "* Configuring routes" 115# If several ifaces are configured via DHCP, they often both have 0/0 route. 116# They have no way of knowing that this route is offered on more than one iface. 117# Often, it's desirable to prefer one iface: say, wired eth over wireless. 118# if preferred_default_route_iface is not set, 0/0 route will be assigned randomly. 119if test "$preferred_default_route_iface"; then 120 i=0; while test "${if[$i]}"; do 121 if test "${if[$i]}" = "$preferred_default_route_iface" \ 122 && test "${net[$i]}" = "0/0" \ 123 && test "${gw[$i]}"; then 124 echo "+ default route through ${if[$i]}, ${gw[$i]}:" 125 doit ip r a "${net[$i]}" via "${gw[$i]}" 126 fi 127 let i++; done 128fi 129i=0; while test "${if[$i]}"; do 130 #echo $i:"${if[$i]}" 131 if test "${net[$i]}" && test "${gw[$i]}"; then 132 doit ip r a "${net[$i]}" via "${gw[$i]}" 133 fi 134let i++; done 135 136echo; echo "* Recreating /etc/* files reflecting new network configuration:" 137for i in etc/*; do 138 n=`basename "$i"` 139 echo "+ $n" 140 (. "$i") >"/etc/$n" 141 chmod 644 "/etc/$n" 142done 143 144 145# Usage: new_chain <chain> [<table>] 146new_chain() { 147 local t="" 148 test x"$2" != x"" && t="-t $2" 149 doit iptables $t -N $1 150 ipt="iptables $t -A $1" 151} 152 153echo; echo "* Reset iptables" 154doit iptables --flush 155doit iptables --delete-chain 156doit iptables --zero 157doit iptables -t nat --flush 158doit iptables -t nat --delete-chain 159doit iptables -t nat --zero 160doit iptables -t mangle --flush 161doit iptables -t mangle --delete-chain 162doit iptables -t mangle --zero 163 164echo; echo "* Configure iptables" 165doit modprobe nf_nat_ftp 166doit modprobe nf_nat_tftp 167doit modprobe nf_conntrack_ftp 168doit modprobe nf_conntrack_tftp 169 170# *** nat *** 171# INCOMING TRAFFIC 172ipt="iptables -t nat -A PREROUTING" 173# nothing here 174 175# LOCALLY ORIGINATED TRAFFIC 176ipt="iptables -t nat -A OUTPUT" 177# nothing here 178 179# OUTGOING TRAFFIC 180ipt="iptables -t nat -A POSTROUTING" 181# Masquerade boxes on my private net 182for e in $extif; do 183 doit $ipt -s 192.168.0.0/24 -o $e -j MASQUERADE 184done 185 186# *** mangle *** 187### DEBUG 188### ipt="iptables -t mangle -A PREROUTING" 189### doit $ipt -s 192.168.0.0/24 -j RETURN 190### ipt="iptables -t mangle -A FORWARD" 191### doit $ipt -s 192.168.0.0/24 -j RETURN 192### ipt="iptables -t mangle -A POSTROUTING" 193### doit $ipt -s 192.168.0.0/24 -j RETURN 194# nothing here 195 196# *** filter *** 197# 198new_chain iext filter 199#doit $ipt -s 203.177.104.72 -j DROP # Some idiot probes my ssh 200#doit $ipt -d 203.177.104.72 -j DROP # Some idiot probes my ssh 201doit $ipt -m state --state ESTABLISHED,RELATED -j RETURN # FTP data etc is ok 202if test "$ext_open_tcp"; then 203 portlist="${ext_open_tcp// /,}" 204 doit $ipt -p tcp -m multiport --dports $portlist -j RETURN 205fi 206doit $ipt -p tcp -j REJECT # Anything else isn't ok. REJECT = irc opens faster 207 # (it probes proxy ports, DROP will incur timeout delays) 208ipt="iptables -t filter -A INPUT" 209for e in $extif; do 210 doit $ipt -i $e -j iext 211done 212 213 214echo; echo "* Enabling forwarding" 215echo 1 >/proc/sys/net/ipv4/ip_forward 216echo "/proc/sys/net/ipv4/ip_forward: `cat /proc/sys/net/ipv4/ip_forward`" 217 218 219# Signal everybody that firewall is up 220date '+%Y-%m-%d %H:%M:%S' >"$rundir/up" 221 222# Ok, spew out gobs of info and disable ourself 223echo; echo "* IP:" 224ip a l 225echo; echo "* Routing:" 226ip r l 227echo; echo "* Firewall:" 228{ 229echo '---FILTER--' 230iptables -v -L -x -n 231echo '---NAT-----' 232iptables -t nat -v -L -x -n 233echo '---MANGLE--' 234iptables -t mangle -v -L -x -n 235} \ 236| grep -v '^$' | grep -Fv 'bytes target' 237echo 238 239echo "* End of firewall configuration" 240