This is my first-attempt, a learning experience... limitations are currently: * stateless: it doesn't conditionally enable ports when an outgoing session starts up, and disable them when session stops. ftp, irc require rather permissive filters otherwise.. * UDP ports: this version of ipchains doesn't allow specification of udp ports in filter.. * NAT, and IRC are not working...
probably are many other limitations... do'nt have much time for this with a baby in the house.... Principal areas for improvement would be minimising man-in-the-middle attacks via DNS, DHCP, tcp session hijack.. though I'm not sure how.. Somebody mentioned "iptables', must check this out. Also, a tool called 'mason' is used to log all traffic with ipchains (other tools too?) to build quick-and-dirty rulesets for you to tweak, though I mostly used it to get to grips with the ipchains command syntax. Improvements and suggestions are very welcome. have fun, john --8<-- /sbin/ipchains -F input /sbin/ipchains -F output /sbin/ipchains -F forward /sbin/ipchains -P input DENY /sbin/ipchains -P output DENY /sbin/ipchains -P forward DENY # spoof protect for IF in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $IF done export ALL="0/0" export BROADCAST="255.255.255.255/32" export eth0ADDR="`ifconfig eth0 2>/dev/null | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`/32" export eth1ADDR="10.93.3.1" export HOME_LAN="10.93.3.0/24" # these 2 dns addrs should be taken from /etc/resolv.conf export DNS1="xxx.xxx.xxx.xxx/32" export DNS2="xxx.xxx.xxx.xxx/32" export ISP_DHCP=xxx.xxx.xxx.xxx/32 # POP account A export REMOTE_POP3_A="xxx.xxx.xxx.xxx/32" # POP account B export REMOTE_POP3_B="xxx.xxx.xxx.xxx/32" # ISP SMTP which resolves to two IPs export REMOTE_SMTP="xxx.xxx.xxx.xxx/31" export NTP_SERVER="xxx.xxx.xxx.xxx" export ETH0_IN__=" ipchains -A input -i eth0" export ETH0_IN_L=" ipchains -l -A input -i eth0" export ETH0_OUT__="ipchains -A output -i eth0" export ETH0_OUT_L="ipchains -l -A output -i eth0" export ETH1_IN__=" ipchains -A input -i eth1" export ETH1_IN_L=" ipchains -l -A input -i eth1" export ETH1_OUT__="ipchains -A output -i eth1" export ETH1_OUT_L="ipchains -l -A output -i eth1" # Some evil bastard from the logs. would be nice to script attack-detection # to do this for anyone who starts rattling the dooknobs... ipchains -A input -p all -i eth0 -s 213.132.136.152 -d ${ALL} -j REJECT ipchains -A input -p all -i eth0 -d 213.132.136.152 -s ${ALL} -j REJECT # Possibly overpermissive loopback rules # more finegrained control over loopback traffic would be more secure... ipchains -A input -i lo -j ACCEPT ipchains -A output -i lo -j ACCEPT # DNS lookups # .. external $ETH0_OUT__ -p udp -s ${eth0ADDR} 1024: -d ${DNS1} domain -j ACCEPT $ETH0_IN__ -p udp -s ${DNS1} domain -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_OUT__ -p udp -s ${eth0ADDR} 1024: -d ${DNS2} domain -j ACCEPT $ETH0_IN__ -p udp -s ${DNS2} domain -d ${eth0ADDR} 1024: -j ACCEPT # server needs these for root-server access $ETH0_OUT_L -p udp -s ${eth0ADDR} 1024: -d ${ALL} domain -j ACCEPT $ETH0_IN_L -p udp -s ${ALL} domain -d ${eth0ADDR} 1024: -j ACCEPT # .. internal $ETH1_IN__ -p udp -s ${HOME_LAN} 1024: -d ${eth1ADDR} domain -j ACCEPT $ETH1_OUT__ -p udp -s ${eth1ADDR} domain -d ${HOME_LAN} 1024: -j ACCEPT # want to ping aywhere $ETH0_OUT__ -p icmp -s ${eth0ADDR} 8 -d ${ALL} 0 -j ACCEPT $ETH0_IN__ -p icmp -s ${ALL} 0 -d ${eth0ADDR} 0 -j ACCEPT # .. and traceroute .. $ETH0_OUT__ -p udp -s ${eth0ADDR} 1024: -d ${ALL} 1024: -j ACCEPT $ETH0_IN__ -p udp -s ${ALL} 1024: -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_IN__ -p 1 -s ${ALL} 11 -d ${eth0ADDR} 0 -j ACCEPT # .. ping local lan .. $ETH1_OUT__ -p icmp -s ${eth1ADDR} 8 -d ${HOME_LAN} 0 -j ACCEPT $ETH1_IN__ -p icmp -s ${HOME_LAN} 0 -d ${eth1ADDR} 0 -j ACCEPT $ETH1_IN__ -p icmp -s ${HOME_LAN} 8 -d ${eth1ADDR} 0 -j ACCEPT $ETH1_OUT__ -p icmp -s ${eth1ADDR} 0 -d ${HOME_LAN} 0 -j ACCEPT # .. and traceroute .. $ETH1_OUT__ -p udp -s ${eth1ADDR} 1024: -d ${HOME_LAN} 1024: -j ACCEPT $ETH1_IN__ -p udp -s ${HOME_LAN} 1024: -d ${eth1ADDR} 1024: -j ACCEPT $ETH1_IN__ -p 1 -s ${HOME_LAN} 11 -d ${eth1ADDR} 0 -j ACCEPT # Auth client/server, for ftp,smtp (and others?) $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${ALL} auth -j ACCEPT $ETH0_IN__ -p tcp -s ${ALL} auth -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_IN__ -p tcp -s ${ALL} 1024: -d ${eth0ADDR} auth -j ACCEPT # DHCP bits # .. local -> ISP # note that the b'cast target is only required in startup where # no lease is cached.. could be safely deleted after.. $ETH0_OUT__ -p udp -s ${eth0ADDR} 68 -d ${BROADCAST} 67 -j ACCEPT $ETH0_OUT__ -p udp -s ${eth0ADDR} 68 -d ${ISP_DHCP} 67 -j ACCEPT $ETH0_IN__ -p udp -s ${ISP_DHCP} 67 -d ${eth0ADDR} 68 -j ACCEPT # .. local lan -> firewall $ETH1_IN__ -p udp -s ${ALL} 68 -d ${BROADCAST} 67 -j ACCEPT $ETH1_IN__ -p udp -s ${HOME_LAN} 68 -d ${eth1ADDR} 67 -j ACCEPT $ETH1_OUT__ -p udp -s ${eth1ADDR} 67 -d ${HOME_LAN} 68 -j ACCEPT # FTP Client bits $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${ALL} ftp -j ACCEPT $ETH0_IN__ -p tcp -s ${ALL} ftp -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${ALL} ftp-data -j ACCEPT $ETH0_IN__ -p tcp -s ${ALL} ftp-data -d ${eth0ADDR} 1024: -j ACCEPT # !!! DANGER !!! Change REJECT to ACCEPT for outgoing PASV ftp $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${ALL} 1024: -j REJECT # HTTP client $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${ALL} 80 -j ACCEPT $ETH0_IN__ -p tcp -s ${ALL} 80 -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_OUT_L -p tcp -s ${eth0ADDR} 8000 -d ${ALL} 1024: -j ACCEPT $ETH0_IN_L -p tcp -s ${ALL} 1024: -d ${eth0ADDR} 8000 -j ACCEPT # Mail Client $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${REMOTE_POP3_A} pop3 -j ACCEPT $ETH0_IN__ -p tcp -s ${REMOTE_POP3_A} pop3 -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${REMOTE_POP3_B} pop3 -j ACCEPT $ETH0_IN__ -p tcp -s ${REMOTE_POP3_B} pop3 -d ${eth0ADDR} 1024: -j ACCEPT $ETH0_OUT__ -p tcp -s ${eth0ADDR} 1024: -d ${REMOTE_SMTP} smtp -j ACCEPT $ETH0_IN__ -p tcp -s ${REMOTE_SMTP} smtp -d ${eth0ADDR} 1024: -j ACCEPT # SAMBA on Local LAN (use net as src/dst because of broadcast ..) $ETH1_IN__ -p udp -s ${HOME_LAN} 137 -d ${HOME_LAN} 137 -j ACCEPT $ETH1_OUT__ -p udp -s ${HOME_LAN} 137 -d ${HOME_LAN} 137 -j ACCEPT $ETH1_IN__ -p udp -s ${HOME_LAN} 138 -d ${HOME_LAN} 138 -j ACCEPT $ETH1_OUT__ -p udp -s ${HOME_LAN} 138 -d ${HOME_LAN} 138 -j ACCEPT # self as client $ETH1_IN__ -p tcp -s ${HOME_LAN} netbios-ssn -d ${eth1ADDR} 1024: -j ACCEPT $ETH1_OUT__ -p tcp -s ${eth1ADDR} 1024: -d ${HOME_LAN} netbios-ssn -j ACCEPT $ETH1_OUT__ -p udp -s ${eth1ADDR} 1024: -d ${HOME_LAN} 137 -j ACCEPT # self as server $ETH1_IN__ -p tcp -s ${HOME_LAN} 1024: -d ${eth1ADDR} 139 -j ACCEPT $ETH1_OUT__ -p tcp -s ${eth1ADDR} 139 -d ${HOME_LAN} 1024: -j ACCEPT $ETH1_IN__ -p tcp -s ${HOME_LAN} 1024: -d ${eth1ADDR} 1024: -j ACCEPT $ETH1_OUT__ -p tcp -s ${eth1ADDR} 1024: -d ${HOME_LAN} netbios-ssn -j ACCEPT # block samba i/o external if $ETH0_IN__ -p udp -s ${ALL} 137 -d ${ALL} : -j REJECT $ETH0_OUT__ -p udp -s ${ALL} 137 -d ${ALL} : -j REJECT $ETH0_IN__ -p udp -s ${ALL} 138 -d ${ALL} : -j REJECT $ETH0_OUT__ -p udp -s ${ALL} 138 -d ${ALL} : -j REJECT $ETH0_IN__ -p tcp -s ${ALL} 139 -d ${ALL} : -j REJECT $ETH0_OUT__ -p tcp -s ${ALL} 139 -d ${ALL} : -j REJECT # NTP client stuff $ETH0_OUT__ -p udp -s ${eth0ADDR} 123 -d ${NTP_SERVER} 123 -j ACCEPT $ETH0_IN__ -p udp -d ${eth0ADDR} 123 -s ${NTP_SERVER} 123 -j ACCEPT # IRC client # havn't figured this out yet..... # this (NAT) isn't working yet either... #/sbin/ipchains -l -A forward -s ${HOME_LAN} -j MASQ # log anything else to/from us $ETH0_IN_L -p all -s ${ALL} -d ${eth0ADDR} -j DENY $ETH0_OUT_L -p all -s ${eth0ADDR} -d ${ALL} -j DENY $ETH1_IN_L -p all -s ${ALL} -d ${eth1ADDR} -j DENY $ETH1_OUT_L -p all -s ${eth1ADDR} -d ${ALL} -j DENY # drop everything else "on the floor" ipchains -A input -i eth+ -p all -s ${ALL} -d ${ALL} -j DENY ipchains -A output -i eth+ -p all -s ${ALL} -d ${ALL} -j DENY