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