If your planning on using Linux in a hostile environment, i.e. the Internet! then its worth thinking about some simple little tweaks to the TCP/IP stack in conjunction with some funky firewall madness to keep your box your own, and not end up “owned” too quickly!
Lets start with the TCP/IP stack. There are a number of quick easy wins here that can help defend against attacks through making the default behaviours of the stack more in-line with what we would like:
Now, that little lot above needs some caveats. Firstly, use at your own risk! Secondly, As per usual, you often get a small performance hit when you start getting more secure, so test each tweak fully before you go into production. Once your happy with the ones you like, add then to your /etc/rc.local or other start up file of your choice.
The next step is to use iptables to help deal with dodgy looking traffic.
Step 1, set-up a bunch of new chains:
echo "1" > /proc/sys/net/ipv4/conf/eth0/rp_filter echo "0" > /proc/sys/net/ipv4/conf/lo/rp_filter echo "1" > /proc/sys/net/ipv4/conf/all/log_martians echo "0" > /proc/sys/net/ipv4/conf/lo/log_martians echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects echo "0" > /proc/sys/net/ipv4/conf/all/secure_redirects echo "1" > /proc/sys/net/ipv4/ip_dynaddr echo "10" > /proc/sys/net/ipv4/tcp_fin_timeout echo "1800" > /proc/sys/net/ipv4/tcp_keepalive_time echo "15" > /proc/sys/net/ipv4/ipfrag_time echo "2048" > /proc/sys/net/ipv4/tcp_max_syn_backlog echo "32768 61000" > /proc/sys/net/ipv4/ip_local_port_range echo "2" > /proc/sys/net/ipv4/tcp_synack_retries
Step 2, now lets get those chains to do something useful:
$IPTABLES -N CHECK_FLAGS $IPTABLES -N ALLOW_ICMP $IPTABLES -N SRC_EGRESS $IPTABLES -N DST_EGRESS
Step 3, Apply the prior two steps to your input, forward and output chains as needed:
$IPTABLES -A CHECK_FLAGS -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "NMAP-XMAS:" $IPTABLES -A CHECK_FLAGS -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPTABLES -A CHECK_FLAGS -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "SYN/RST:" $IPTABLES -A CHECK_FLAGS -p tcp --tcp-flags SYN,RST SYN,RST -j DROP $IPTABLES -A CHECK_FLAGS -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "SYN/FIN:" $IPTABLES -A CHECK_FLAGS -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP $IPTABLES -A ALLOW_ICMP -p icmp --icmp-type echo-reply -j ACCEPT $IPTABLES -A ALLOW_ICMP -p icmp --icmp-type destination-unreachable -j ACCEPT $IPTABLES -A ALLOW_ICMP -p icmp --icmp-type echo-request -j ACCEPT $IPTABLES -A ALLOW_ICMP -p icmp --icmp-type time-exceeded -j ACCEPT for SRCNET in $EGRESS_NETS; do $IPTABLES -A SRC_EGRESS -s $SRCNET -j DROP done for DSTNET in $EGRESS_NETS; do $IPTABLES -A DST_EGRESS -d $DSTNET -j DROP done
Variables. In all of the above, variables are used to save typing!, here are some of the important variables, the rest are fairly self explanatory:
$IPTABLES -A $CHAIN -i $EXT_INT -j SRC_EGRESS $IPTABLES -A $CHAIN -i $EXT_INT -j DST_EGRESS $IPTABLES -A $CHAIN -i $EXT_INT -p icmp -j ALLOW_ICMP $IPTABLES -A $CHAIN -i $EXT_INT -p tcp -j CHECK_FLAGS
What we have just done is setup some new chains, apply some filters that can identify dodgy looking traffic and do something useful with it (limit it rather than drop it, as we don’t want to arouse suspicion with our attackers). Then apply all that nice Packet Mangling to each of our primary chains.
I provide all of this advice for free, with no guarantees, any use of the above code should be with full testing prior to its use in a production environment. Enjoy!