#!/bin/sh # Arg 1: outgoing "gateway" interface, could be eth2 or eth0 or so # Arg 2: "tun" interface to klh10, typically tun0 # Arg 3: (optional) (local) DNS server to redirect outgoing queries to # OR # Arg 1: the klh10.ini file to parse the info from. # Arg 2: (optional) (local) DNS server to redirect outgoing queries to # Note: although the iptables stuff is persistent (until cleared or reboot), # the $TUNIF doesn't exist until kn10-ks creates the interface, # and it goes away when it stop, so the contents ("1") of the file # /proc/sys/net/ipv4/conf/$TUNIF/forwarding needs to be reinitialised. # Allow new outgoing connections (except SMTP) from ITS ITS_OUT=no # Allow outgoing DNS queries ITS_DNS=yes # Allow incoming Telnet connections (in addition to Supdup) ITS_Telnet=no # Allow outgoing Supdup connections (in addition to incoming) ITS_Supdup=yes # Allow incoming/outgoing Finger connections (in addition to other) ITS_Finger=yes # Allow incoming HTTP connections (in addition...) ITS_HTTP=yes # Allow *local* FTP to work ITS_FTP_Data=yes # Allow ITS to connect out to this host with SMTP ITS_SMTP_local=yes # Valid source addresses for CHUDP # Localhost, local net, home net, cc.cosmic.com, its.svensson.org CHUDP_sources="127.0.0.1/32 130.238.0.0/16 81.232.0.0/16 64.19.172.210/24" GWIF=$1 TUNIF=$2 nameserver=$3 chudpport= ITSGWADDR= if [ "$1" = "stop" -o "$2" = "stop" -o "$3" = "stop" ]; then STOPPING=true elif [ "X$1" != "X" -a -r "$1" ]; then # Parse config file, find devices and ITS "Gateway" TUNIF= nameserver=$2 DEVDEF=`grep '^devdef imp' $1` if [ `echo $DEVDEF | wc -l` -eq 1 ]; then KSIP=`echo $DEVDEF | sed -r -e 's/^.* ipaddr=([0-9.]+).*$/\1/'` ITSGWADDR=`echo $DEVDEF | sed -r -e 's/^.* tunaddr=([0-9.]+).*$/\1/'` TUNIF=`ip -o addr | grep 'inet ' | grep "peer $KSIP" | awk '{ print $2 }'` # X=`ip -o addr | grep 'inet ' | grep "inet $ITSGWADDR" | awk '{ print $2 }'` X=`netstat -r -n | grep -m 1 '^0.0.0.0' | awk '{ print $8 }'` if [ "X$X" != "X" ]; then GWIF=$X else GWIF= fi fi DEVDEF=`grep '^devdef chaos' $1` if [ `echo $DEVDEF | wc -l` -eq 1 ]; then chudpport=`echo $DEVDEF | grep chudpport | sed -r -e 's/^.* chudpport=([0-9]+).*$/\1/'` if [ "X$chudpport" = "X" ]; then chudpport=42042 fi fi fi if [ "$TUNIF" = "" -o "$TUNIF" = "stop" ]; then TUNIF=tun0 fi if [ "$GWIF" = "" -o "$GWIF" = "stop" ]; then GWIF=`ip -o addr | grep 'inet ' | grep -v ': lo ' | grep -v ": $TUNIF " | awk '{ print $2 }'` fi if [ "$GWIF" = "" -o `echo $GWIF | wc -w` -gt 1 ]; then echo "Can't find gateway interface" echo "usage: $0 GWIF [ TUNIF ]" echo " or" echo " $0 klh10-config-file" exit 1 fi if [ "$STOPPING" != "" ]; then echo "Stopping iptables and forwarding for KLH10" iptables -D FORWARD -j KLH10-Firewall-FORWARD iptables -F KLH10-Firewall-FORWARD iptables -X KLH10-Firewall-FORWARD # we don't know the chudpport here # if [ "$chudpport" != "" ]; then iptables -D INPUT -j KLH10-Firewall-INPUT iptables -F KLH10-Firewall-INPUT iptables -X KLH10-Firewall-INPUT # fi # hmm, this flushes ALL nat'ing? iptables -t nat -F echo 0 > /proc/sys/net/ipv4/conf/$TUNIF/forwarding echo 0 > /proc/sys/net/ipv4/conf/$GWIF/forwarding exit fi GWIP=`ifconfig $GWIF | grep 'inet addr' | sed -r -e 's/^.*inet addr:([0-9.]+) .*$/\1/'` KSIP=`ifconfig $TUNIF | grep 'inet addr' | sed -r -e 's/^.*P-t-P:([0-9.]+) .*$/\1/'` KLIP=`ifconfig $TUNIF | grep 'inet addr' | sed -r -e 's/^.*inet addr:([0-9.]+) .*$/\1/'` if [ "$GWIP" = "" -o "$KSIP" = "" -o "$KLIP" = "" ]; then echo "At least one IP address cannot be found: GW: $GWIP, KS: $KSIP, KL: $KLIP" exit 1 fi if [ "$ITS_DNS" = "yes" ]; then if [ "$nameserver" = "" ]; then nameserver=`grep '^nameserver ' /etc/resolv.conf | head -1 | sed -e 's/nameserver //'` fi fi echo "Setting up iptables for" echo " GW $GWIF ($GWIP)," echo " TUN $TUNIF ($KSIP - $KLIP)" if [ "$ITSGWADDR" != "" -a "$ITSGWADDR" != "$KLIP" ]; then echo " ITS gw $ITSGWADDR" fi if [ "$chudpport" != "" ]; then echo " CHUDP port $chudpport" fi if [ "$ITS_DNS" = "yes" -a "$nameserver" != "" ]; then echo " Nameserver $nameserver" fi # Based on http://www.netfilter.org/documentation/HOWTO/NAT-HOWTO-4.html # you simply want to tell your box that all packets coming from your # tun network should be made to look like they are coming from # the klh10 host machine # In the NAT table (-t nat), Append a rule (-A) after routing # (POSTROUTING) for all packets coming from TUNIF (-i $TUNIF) going # out GWIF (-o $GWIF) which says to MASQUERADE the connection (-j MASQUERADE). iptables -t nat -A POSTROUTING -o $GWIF -j MASQUERADE iptables -N KLH10-Firewall-FORWARD iptables -I FORWARD -j KLH10-Firewall-FORWARD iptables -N KLH10-Firewall-INPUT iptables -I INPUT -j KLH10-Firewall-INPUT # debug fragments iptables -A KLH10-Firewall-INPUT -f -j LOG --log-prefix "[Fragment]" iptables -A KLH10-Firewall-FORWARD -p icmp -j LOG --log-prefix "[ICMP]" if [ "$chudpport" != "" ]; then # Open up for Chaos-over-UDP # #### Open only to hosts we know! # iptables -A KLH10-Firewall-INPUT -p udp -m udp --dport $chudpport -j ACCEPT for src in $CHUDP_sources; do iptables -A KLH10-Firewall-INPUT -s $src -p udp -m udp --dport $chudpport -j ACCEPT done iptables -A KLH10-Firewall-INPUT -p udp -m udp --dport $chudpport -j LOG --log-prefix [Unknown_CHUDP] iptables -A KLH10-Firewall-INPUT -p udp -m udp --dport $chudpport -j DROP fi if [ "$ITS_SMTP_local" = "yes" ]; then iptables -A KLH10-Firewall-INPUT -m state --state NEW -p tcp -m tcp --source $KSIP --dport 25 -j LOG --log-prefix [ITS_local_SMTP] iptables -A KLH10-Firewall-INPUT -p tcp -m tcp --source $KSIP --dport 25 -j ACCEPT fi # and let forwarding pass the firewall # (0) set up a separate target, to make it easier to remove # **** should not accept source routed traffic # **** should check for spoofing # (1) let ITS connect out if [ "$ITS_DNS" = "yes" ]; then # Allow DNS queries #iptables -A KLH10-Firewall-FORWARD -s $KSIP -p udp --dport 53 -j LOG --log-prefix [ITS_DNS] iptables -A KLH10-Firewall-FORWARD -s $KSIP -p udp --dport 53 -j ACCEPT if [ "$nameserver" != "" ]; then # but redirect them to our nameserver (would like to enforce recursive queries) iptables -A PREROUTING -t nat -s $KSIP -p udp --dport 53 -j DNAT --to-destination $nameserver fi fi if [ "$ITS_OUT" = "yes" ]; then # but disallow SMTP until configured! iptables -A KLH10-Firewall-FORWARD -s $KSIP -p tcp --dport 25 -j LOG --log-prefix [ITS_SMTP_in] iptables -A KLH10-Firewall-FORWARD -s $KSIP -p tcp --dport 25 -j REJECT # allow others iptables -A KLH10-Firewall-FORWARD -m state --state NEW -i $TUNIF -o $GWIF -j LOG --log-prefix [ITS_new_out] iptables -A KLH10-Firewall-FORWARD -m state --state NEW -i $TUNIF -o $GWIF -j ACCEPT else if [ "$ITS_Finger" = "yes" ]; then #iptables -A KLH10-Firewall-FORWARD -s $KSIP -p tcp --dport 79 -j LOG --log-prefix [ITS_finger_out] iptables -A KLH10-Firewall-FORWARD -s $KSIP -p tcp --dport 79 -j ACCEPT fi if [ "$ITS_Supdup" = "yes" ]; then iptables -A KLH10-Firewall-FORWARD -s $KSIP -p tcp --dport 95 -j LOG --log-prefix [ITS_supdup_out] iptables -A KLH10-Firewall-FORWARD -s $KSIP -p tcp --dport 95 -j ACCEPT fi # let return packets go through! iptables -A KLH10-Firewall-FORWARD -m state --state ESTABLISHED,RELATED -i $TUNIF -o $GWIF -j ACCEPT # but not others (new) iptables -A KLH10-Firewall-FORWARD -i $TUNIF -o $GWIF -j LOG --log-prefix [ITS_out_drop] iptables -A KLH10-Firewall-FORWARD -i $TUNIF -o $GWIF -j DROP # REJECT --reject-with icmp-host-unreachable fi # (2) let others connect to ITS? # no, it's a local interface. #iptables -A KLH10-Firewall-FORWARD -m state --state ESTABLISHED,RELATED -i $GWIF -o $TUNIF -j ACCEPT # Append a rule before routing (-A PREROUTING) to the NAT table (-t nat) that # TCP packets (-p tcp) going to $GWIP (-d $GWIP) port 95 (--dport 95) # have their destination mapped (-j DNAT) to $KSIP, port 95 # (--to $KSIP:95). inports="95" # Allow incoming Supdup if [ "$ITS_Telnet" = "yes" ]; then inports="$inports 23"; fi if [ "$ITS_Finger" = "yes" ]; then inports="$inports 79"; fi if [ "$ITS_HTTP" = "yes" ]; then inports="$inports 80"; fi for port in $inports; do iptables -A PREROUTING -t nat -p tcp -d $GWIP --dport $port \ -j DNAT --to-destination $KSIP:$port # this is for locally generated packets(?) iptables -A OUTPUT -t nat -p tcp -d $GWIP --dport $port \ -j DNAT --to-destination $KSIP:$port # and let it pass the firewall # if [ $port != 80 ]; then iptables -A KLH10-Firewall-FORWARD -d $KSIP -m state --state NEW -m tcp -p tcp --dport $port -j LOG --log-prefix [ITS_KS_new_$port] # fi iptables -A KLH10-Firewall-FORWARD -d $KSIP -m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT done if [ "$ITS_FTP_Data" = "yes" ]; then iptables -A KLH10-Firewall-INPUT -s $KSIP -d $KLIP -m state --state NEW -p tcp -m tcp --sport 20 -j LOG --log-prefix [ITS_KS_ftpdata] iptables -A KLH10-Firewall-INPUT -s $KSIP -d $KLIP -p tcp -m tcp --sport 20 -j ACCEPT fi # Let ITSGWADDR be an alias for KLIP if [ "$ITSGWADDR" != "" -a "$ITSGWADDR" != "$KLIP" ]; then iptables -A PREROUTING -t nat -d $ITSGWADDR -j DNAT --to $KLIP fi # **** check later if FORWARD need to be involved? # Turn on IP forwarding #echo 1 > /proc/sys/net/ipv4/ip_forward # Only forward these interfaces, not all other interfaces echo 1 > /proc/sys/net/ipv4/conf/$TUNIF/forwarding echo 1 > /proc/sys/net/ipv4/conf/$GWIF/forwarding