iptables accepts commands to set up firewall rules. To view rules:
iptables -L iptables-save
redirect the latter to save a backup of the rules
iptables-save > iptables-backup iptables-restore < iptables-backup
Scripts are set up to instantiate rules. This script will also log dropped packes
#!/bin/sh # Written by Brad Tilley <brad.tilley@vt.edu> # Change this to your computer's IP address. MY_IP='192.168.1.10' path_to_iptables=`which iptables` # Flush cahins and zero counters. $path_to_iptables -t filter -F $path_to_iptables -t filter -Z # Drop all packets by Default. $path_to_iptables -t filter -P INPUT DROP $path_to_iptables -t filter -P OUTPUT DROP $path_to_iptables -t filter -P FORWARD DROP # Allow Pings. #$path_to_iptables -t filter -A INPUT -p ICMP -j ACCEPT # Allow loopback. $path_to_iptables -t filter -A INPUT -i lo -j ACCEPT $path_to_iptables -t filter -A OUTPUT -o lo -j ACCEPT # Allow traffic initiated from the computer (these are all desktop computers need). $path_to_iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $path_to_iptables -t filter -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $path_to_iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Additional Server Examples (outside world needs access to server on this machine). $path_to_iptables -t filter -A INPUT -p tcp -s 0/0 -d $MY_IP --dport 22 -j ACCEPT $path_to_iptables -t filter -A INPUT -p tcp -s 128.173.0.0/16 -d $MY_IP --dport 8080 -j ACCEPT $path_to_iptables -t filter -A INPUT -p tcp -s 192.168.1.0/24 -d $MY_IP --dport 8080 -j ACCEPT $path_to_iptables -t filter -A INPUT -p tcp -s 192.168.1.0/24 -d $MY_IP --dport 443 -j ACCEPT # Log *NEW* incoming packets that do not come from $MY_IP. # Use ULOG /var/log/ulog/syslogemu.log #$path_to_iptables -t filter -I INPUT -m state --state NEW -p tcp -s ! $MY_IP -d $MY_IP -j ULOG #$path_to_iptables -t filter -I INPUT -m state --state NEW -p udp -s ! $MY_IP -d $MY_IP -j ULOG # Or use LOG /var/log/messages $path_to_iptables -t filter -I INPUT -m state --state NEW -p tcp -s ! $MY_IP -d $MY_IP -j LOG --log-prefix " New_tcp " --log-level debug $path_to_iptables -t filter -I INPUT -m state --state NEW -p udp -s ! $MY_IP -d $MY_IP -j LOG --log-prefix " New_udp " --log-level debug $path_to_iptables -N LOGDROP $path_to_iptables -A LOGDROP -j LOG --log-prefix " Drop_tcp " --log-level debug $path_to_iptables -A LOGDROP -j DROP $path_to_iptables -A OUTPUT -j LOGDROP $path_to_iptables -A INPUT -j LOGDROP $path_to_iptables -A FORWARD -j LOGDROP
The latter part with the LOGDROP chain came from:
http://www.brandonhutchinson.com/iptables_fw.html
more good stuff here:
Presentation:
http://filebox.vt.edu/users/rtilley/public/iptables/iptables.pdf
itso_fw_off.sh
#!/bin/sh # Written by Brad Tilley <brad.tilley@vt.edu> # Accept all Packets, do not filter anything. # Flush all cahins (delete any existing rules) path_to_iptables=`which iptables` $path_to_iptables -t filter -F # Zero packet and byte counters $path_to_iptables -t filter -Z # Policies $path_to_iptables -t filter -P INPUT ACCEPT $path_to_iptables -t filter -P OUTPUT ACCEPT $path_to_iptables -t filter -P FORWARD ACCEPT
itso_fw_on.sh
#!/bin/sh # Written by Brad Tilley <brad.tilley@vt.edu> # Change this to your computer's IP address. MY_IP='128.173.54.137' path_to_iptables=`which iptables` # Flush cahins and zero counters. $path_to_iptables -t filter -F $path_to_iptables -t filter -Z # Drop all packets by Default. $path_to_iptables -t filter -P INPUT DROP $path_to_iptables -t filter -P OUTPUT DROP $path_to_iptables -t filter -P FORWARD DROP # Allow Pings. $path_to_iptables -t filter -A INPUT -p ICMP -j ACCEPT # Allow loopback. $path_to_iptables -t filter -A INPUT -i lo -j ACCEPT $path_to_iptables -t filter -A OUTPUT -o lo -j ACCEPT # Allow traffic initiated from the computer (these are all desktop computers need). $path_to_iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $path_to_iptables -t filter -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $path_to_iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Additional Server Examples (outside world needs access to server on this machine). #$path_to_iptables -t filter -A INPUT -p tcp -s 0/0 -d $MY_IP --dport 22 -j ACCEPT #$path_to_iptables -t filter -A INPUT -p tcp -s 128.173.0.0/16 -d $MY_IP --dport 80 -j ACCEPT #$path_to_iptables -t filter -A INPUT -p tcp -s 128.173.54.0/24 -d $MY_IP --dport 443 -j ACCEPT # Log *NEW* incoming packets that do not come from $MY_IP. # Use ULOG /var/log/ulog/syslogemu.log #$path_to_iptables -t filter -I INPUT -m state --state NEW -p tcp -s ! $MY_IP -d $MY_IP -j ULOG #$path_to_iptables -t filter -I INPUT -m state --state NEW -p udp -s ! $MY_IP -d $MY_IP -j ULOG # Or use LOG /var/log/messages #$path_to_iptables -t filter -I INPUT -m state --state NEW -p tcp -s ! $MY_IP -d $MY_IP -j LOG --log-prefix=" New_tcp " #$path_to_iptables -t filter -I INPUT -m state --state NEW -p udp -s ! $MY_IP -d $MY_IP -j LOG --log-prefix=" New_udp "
this error in logs:
artemis kernel: ip_conntrack: table full, dropping packet.
means the computer can't keep up. Increasing ip_conntrack_max seems to help:
echo 16384 > /proc/sys/net/ipv4/netfilter/ip_conntrack_max cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max echo 24576 > /proc/sys/net/ipv4/netfilter/ip_conntrack_max watch cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count
Lots of other links in this article as well..
http://www.debian-administration.org/articles/268
Using just standard tools:
'telnet target.host 100' 'telnet target.host 200' 'telnet target.host 300' 'ssh target.host'
If you're ambitious, hping2/hping3 can be used to make it even easier.
-Valdis
standard Windows telnet allows other ports. run cmd, then telnet server.org 1234
like C:\>telnet ancient.anguish.org 2222
if you want to telnet to that MUD
Pris
I would like to add a couple of things.
Instead of using the default “DROP” target set w/ -P, append the following catch-all's to your INPUT chain:
# send tcp-reset for rejected tcp packets
iptables -A INPUT -p tcp -m state --state NEW -j REJECT \
--reject-with tcp-reset
# send icmp-port-unreachable for rejected udp packets
iptables -A INPUT -p udp -m state --state NEW -j REJECT \
--reject-with icmp-port-unreachable
# send icmp-host-prohibited for all other rejected traffic
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
The firewall will reject unwanted traffic with the correct response (TCP RST for tcp connections, icmp port unreachable for udp, and icmp host prohibited for anything else), and it also makes it a little more difficult for folks to figure out holes in your firewall.
In your “off” script, I would recommend setting the default targets (-P ACCEPT) before flushing your rules. This is a safety valve in case you're turning it off remotely and the script gets interrupted after it flushed your rules but before it sets the default targets - you'd end up w/o network access. I admit, this is really unlikely to happen, but better safe than sorry.
-Vince
# send tcp-reset for rejected tcp packets
iptables -A INPUT -p tcp -m state –state NEW -j REJECT \
–reject-with tcp-reset
This is a matter of taste and preference - there are good and valid reasons to use DROP rather than REJECT, which basically boil down to “DROP makes it harder for an off-site attacker to identify your box because it produces less responses”. You send back a TCP RST packet, the attacker now knows your box is alive, and can use the RST for fingerprinting the OS. You do a DROP, and the attacker can't tell as easily that the host exists.
What I do:
[0:0] -A tcp-in -p tcp -s 128.173.0.0/16 --syn -j REJECT --reject-with tcp-reset [0:0] -A tcp-in -p tcp -s 198.82.0.0/16 --syn -j REJECT --reject-with tcp-reset [0:0] -A tcp-in -j DROP
(Basically, be polite to on-campus hosts, and silently ignore the riff-raff off campus).
-Valdis
January 18, 2007, - Linux meeting. I'll post this info to the ITKnowHow site: https://hokiespw.ais.vt.edu/itknowhowwiki/doku.php?id=itknowhow:linux
Download Brad's pdf and scripts @ http://filebox.vt.edu/users/rtilley/public/iptables
My notes are very short. - Make sure you don't forget about ip6tables. You may have ipv6 running! - use ifconfig to determine your IP to substitute in Brad's script. - using ulog separates your logs from system logs - If you use log, attach a prefix, so you can easily pull the target data back out. - using iptables-save > myfile.txt will help you easily see the order your chains are in. - using iptables /L will let you see the current rule set. - Adding verbose iptables /L /v will let you see how often your rule is being used.
-Denton
If you have a service that only listens on IP, do not DROP the IPv6 traffic to the port. Most clients will fall back to IP if they receive a REJECT, but they will have to timeout and fall back to IP if you just use DROP.
Phil
For those of us that use dhcp via wireless or wired connections, can we
automate the My_IP value in the script somehow?
IMO, there is no easy answer to this… someone please correct me if I'm wrong. There are lot of variables at play (perhaps too many). You have number of interfaces, which ones are active, inactive, etc. Which IP would you use as MY_IP if you had two or more active Ethernet connections?
If you know that you only have one active interface you may do something like this with Python or some other scripting (this example is written in Python):
– START EXAMPLE
import socket as s
ip = s.gethostbyname(s.gethostname()) print ip
– END EXAMPLE
That's not 100%, on one of my boxes, it does the right thing, on the other it returns 127.0.0.1.
Again, assuming you know that only one interface will be in use, you might also use ifconfig and parse its output to determine your dymanic IP. This would require using arcane Unix tools and regular expressions, etc. Not very appealing to me.
I wonder why the kernel does not (or perhaps cannot) store this info in /proc? Valdis, is this possible? Also, what about the dhclient program, can it somehow return the currently assigned IP?
You ask hard questions Ron :)
Here's the command I use to get the ip for eth0 on my machine.
ip=`/sbin/ifconfig eth0|/bin/grep “inet addr”|/bin/sed 's/ \+inet addr:\([^]\+\).*/\1/'`
-Richard Quintin
Note that this doesn't work right if you have aliases bound to the interface, as they're eth0.1, eth0.2, etc.
This will catch the IP address you have *at that time* - which means it won't do what you want if you get re-DHCP'ed or your address otherwise changes, unless you find a way to re-drive the load of your iptables config at the time of change (which does *NOT* happen by default on most distros, and is its own can of worms for some configs…)
-Valdis
What about the following:
$IPTABLES -t filter -A INPUT -i $ETH0 -p tcp -s 0/0–dport 22 -j ACCEPT
You're filtering what's going into your interface instead of worrying about your current IP address.
Marvin Addison
… it requires (currently) a patch to your kernel, and a patch to your iptables userspace. Once it's done, you can replace all the “-d $MYIP” with '-m ipisforif –dstip eth0'…
Some discussion (with followups): http://lists.netfilter.org/pipermail/netfilter-devel/2006-May/024610.html http://lists.netfilter.org/pipermail/netfilter-devel/2006-May/024613.html
The original kernel patch: http://lists.netfilter.org/pipermail/netfilter-devel/2006-May/024611.html
The original iptables patch: http://lists.netfilter.org/pipermail/netfilter-devel/2006-May/024612.html
If anybody is actually interested, I can probably get this stuff updated for the current kernel/iptables code fairly easily.
-Valdis
Well, *that* was easy. :)
Attached are patches against current trees (the kernel is against 2.6.20-rc4-mm1, but shouild be OK against any 2.6.19 or later - at worst, you'll get a reject against a Makefile or Kconfig file that you can easily hand-fix). You'll need to patch/build the kernel first, then do the moral equivalent of:
cp /usr/src/linux-2.6.foo/include/linux/netfilter/xt_ipisforif.h /usr/include/linux/netfilter/ cp /usr/src/linux-2.6.foo/include/linux/netfilter_ipv4/ipt_ipisforif.h /usr/include/linux/netfilter_ipv4/
and then do the iptables patch (is against 1.3.7).
Then you should be able to do stuff like:
iptables -A chain-name-here -m ipisforif –dstip eth0 -j LOG –log-prefix “Saw traffic for eth0”
(Somehow, I can just see a bunch of people asking about kernel hacking/patching, so should I volunteer to talk about this sometime? ;)
–Valdis
http://kevin.vanzonneveld.net/techblog/article/block_brute_force_attacks_with_iptables/
start /etc/network/if-up.d/bfa_protection
#!/bin/bash
[ "${METHOD}" != loopback ] || exit 0
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
stop /etc/network/if-down.d/bfa_protection
#!/bin/bash
[ "${METHOD}" != loopback ] || exit 0
/sbin/iptables -D INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
/sbin/iptables -D INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
remove all
iptables -F
http://www.thegeekstuff.com/2011/01/iptables-fundamentals/
Four tables
Target Values
Following are the possible special values that you can specify in the target.
List rules
iptables -t filter --list
same as:
iptables --list
iptables -t mangle --list iptables -t nat --list iptables -t raw --list
The rules in the iptables –list command output contains the following fields:
http://www.thegeekstuff.com/2011/01/redhat-iptables-flush/
Temporarily delete all the firewall rules
iptables --flush
Permanently remove all the default firewall rules
service iptables save (saves to /etc/sysconfig/iptables)
# Allow SSH with a rate limit iptables -A INPUT -i ppp0 -p tcp --syn --dport 22 -m hashlimit --hashlimit 15/hour --hashlimit-burst 3 --hashlimit-htable-expire 600000 --hashlimit-mode srcip --hashlimit-name ssh -j ACCEPT iptables -A INPUT -i ppp0 -p tcp --syn --dport 22 -j LOG --log-prefix "[DROPPED SSH]: " iptables -A INPUT -i ppp0 -p tcp --syn --dport 22 -j DROP
http://spevack.wordpress.com/2011/09/21/firewalling-ssh-brute-force-attacks/
# set default policies iptables -P INPUT DROP
# all pre-established clients iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# new inbound ssh, protecting against brute-force attacks iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT