===== iptables =====
----
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
# 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:
http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables
===== Brad Tilley's Scripts =====
Presentation:
[[http://filebox.vt.edu/users/rtilley/public/iptables/iptables.pdf]]
itso_fw_off.sh
#!/bin/sh
# Written by Brad Tilley
# 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
# 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 "
===== loghost =====
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
===== opensource listserv discussions: =====
====port knocking====
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
====iptables====
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
====group notes====
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
==== dhcp and iptables ====
> 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
===== brute force block =====
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
===== iptables HowTo =====
http://www.thegeekstuff.com/2011/01/iptables-fundamentals/
Four tables
* filter
* INPUT chain
* OUTPUT chain
* FORWARD chain
* nat
* PREROUTING chain
* POSTROUTING chain
* OUTPUT chain
* mangle
* PREROUTING chain
* OUTPUT chain
* FORWARD chain
* INPUT chain
* POSTROUTING chain
* raw
* PREROUTING chain
* OUTPUT chain
Target Values
Following are the possible special values that you can specify in the target.
* ACCEPT – Firewall will accept the packet.
* DROP – Firewall will drop the packet.
* QUEUE – Firewall will pass the packet to the userspace.
* RETURN – Firewall will stop executing the next set of rules in the current chain for this packet. The control will be returned to the calling chain.
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:
* num – Rule number within the particular chain
* target – Special target variable that we discussed above
* prot – Protocols. tcp, udp, icmp, etc.,
* opt – Special options for that specific rule.
* source – Source ip-address of the packet
* destination – Destination ip-address for the packet
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)
===== iptables rate limiting as posted on slashdot =====
http://ask.slashdot.org/story/11/05/19/2025247/Ask-Slashdot-FTP-Server-Honeypots?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+Slashdot%2Fslashdot+%28Slashdot%29
# 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
===== Firewalling SSH brute force attacks =====
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