#!/bin/bash # # server.fw # # this program is Copyright (C) 2004 Bill Weiss # # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You can find the GPL at http://www.gnu.org/licenses/gpl.txt ## variable definitions # IPT := the location of the iptables binary IPT=/sbin/iptables # IN_TCP_SERVICES := services we provide to the world, TCP # IN_UDP_SERVICES := services we provide to the world, UDP # OUT_TCP_SERVICES := ports our services use to talk to stuff # # current incoming TCP services: # Jabber : 5223 5269 # Fbmuck : 8765 # ssh : 22 # ftp : 21 20 # http : 80 # smtp : 25 # imaps : 993 # dns : 53 # smtp submission : 587 # https : 443 # # current incoming UDP services: # dns : 53 # # outgoing TCP services: # Jabber : 5269 5190 1863 IN_TCP_SERVICES="8765 22 21 20 80 25 993 53 5223 5269 587 443" IN_UDP_SERVICES="53" OUT_TCP_SERVICES="5269 5190 1863" # IN_DEVICE := device which we get traffic on # OUT_DEVICE := device which we send traffic on IN_DEVICE="eth0" OUT_DEVICE="eth0" # UIDS := list of users (by uid) to be monitored UIDS="1000 1001 71 1003 1004 1013 1021" # IPT_IN := ${IPT} -A INPUT -i ${IN_DEVICE} # IPT_OUT := ${IPT} -A OUTPUT -o ${OUT_DEVICE} IPT_IN="${IPT} -A INPUT -i ${IN_DEVICE}" IPT_OUT="${IPT} -A OUTPUT -o ${OUT_DEVICE}" ## function definitions # initchain chainname # after this, the named chain exists and is empty initchain () { ${IPT} -F ${1} 2>&1 > /dev/null if [ "$?" != "0" ] then ${IPT} -N ${1} fi } ## initialization # empty the chains ${IPT} -P INPUT ACCEPT ${IPT} -P OUTPUT ACCEPT ${IPT} -F INPUT ${IPT} -F OUTPUT ${IPT} -t nat -F PREROUTING ${IPT} -Z # bandwidth monitoring ${IPT_IN} ${IPT_OUT} ## block annoyances # set up the annoyance chain initchain annoyance # windows crud ${IPT} -A annoyance -p tcp --dport 445 -j DROP ${IPT} -A annoyance -p tcp --dport 139 -j DROP ${IPT} -A annoyance -p tcp --dport 135 -j DROP # we don't care about auth # REJECT, so that mail/IRC servers don't hang ${IPT} -A annoyance -p tcp --dport 113 -j REJECT # RFC1918-designated private addresses ${IPT} -A annoyance -s 10/8 -j DROP ${IPT} -A annoyance -s 172.16/12 -j DROP ${IPT} -A annoyance -s 192.168/16 -j DROP # crud that shows up on the firewall logs. Don't care ${IPT} -A annoyance -s 217.160.255.249 -d 255.255.255.255 \ -p udp --sport 67 --dport 68 -j DROP # jump to the annoyance chain on input ${IPT_IN} -j annoyance ## per-user monitoring # output only. grr? # set up the user tracking chain initchain usertrack # add the UIDs to be tracked for ID in ${UIDS} do ${IPT} -A usertrack -m owner --uid-owner ${ID} done # all outgoing traffic goes into that chain ${IPT_OUT} -j usertrack ## inbound services # set up chains for: # inbound services # responses from our services initchain services initchain serviceresponse # add our services to the input services chain # add our service responses to the response chain for port in ${IN_TCP_SERVICES} do ${IPT} -A services -p tcp --dport ${port} -j ACCEPT ${IPT} -A serviceresponse -p tcp --sport ${port} -j ACCEPT done for port in ${IN_UDP_SERVICES} do ${IPT} -A services -p udp --dport ${port} -j ACCEPT ${IPT} -A serviceresponse -p udp --sport ${port} -j ACCEPT done # add a jump to inbound services checking to the INPUT chain ${IPT_IN} -j services ${IPT_OUT} -j serviceresponse ## outgoing services # these are special cases, where an external machine needs to be able to # connect in to us on a undefined port. blame Jabber for port in ${OUT_TCP_SERVICES} do ${IPT_IN} -p tcp --sport ${port} -j ACCEPT ${IPT_OUT} -p tcp --dport ${port} -j ACCEPT done # external machines don't need to connect to us on arbitrary UDP ports, yet # commented until I need it #for port in ${OUT_UDP_SERVICES} #do # ${IPT_IN} -p udp --sport ${port} -j ACCEPT # ${IPT_OUT} -p udp --dport ${port} -j ACCEPT #done ## port forwarding # make SMTP submission port work, in a crappy way # forward incoming 587 traffic to 25 (postfix) ${IPT} -t nat -A PREROUTING -i ${IN_DEVICE} -p tcp --dport 587 \ -j REDIRECT --to-port 25 ## ICMP # for now, just allow ICMP. It's (mostly) harmless ${IPT_IN} -p icmp -j ACCEPT ${IPT_OUT} -p icmp -j ACCEPT ## make sure we don't break stuff our users are doing # we have already accepted anything incoming that's known # incoming stuff related to something we're doing, OK # reject other incoming # outgoing connections that can be tracked are ok # other outgoing, reject ${IPT_IN} -m state --state ESTABLISHED,RELATED -j ACCEPT ${IPT_IN} -j LOG --log-prefix="INPUT rejection " ${IPT_IN} -j REJECT ${IPT_OUT} -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT ${IPT_OUT} -j LOG --log-prefix="OUTPUT rejection " ${IPT_OUT} -j REJECT