[Techtalk] Re: iptables help needed ...

Raven Alder raven at oneeyedcrow.net
Thu Dec 26 16:15:07 EST 2002


Heya --

Quoth txjulie at austin.rr.com (Fri, Dec 20, 2002 at 12:33:55PM -0600):
> It was pretty trick.  It seems they came in via some hole in sshd
> and then deposited a =huge= root-kit.

	Yeah, there have been a few holes in various ssh implementations
lately.  When you rebuild the box, make sure that you have the very
latest version of the ssl libs and your ssh daemon of choice installed.
 
> When I switched to iptables I had to leave a few more things open, and
> my guess is that I left entirely too much open.

	Out of curiosity, why did you have to leave more things open?
Unless your needs changed, you should have been able to filter the same
sorts of things out as you had before.
 
> Recent enough -- but /, /usr, /var and friends were too trashed,
> and it's faster to re-install and be done with it than dredge up
> the backups

	Oh yeah -- I wouldn't restore binaries that might be rootkitted,
etc.  Just the data on the machine.  /home/julie or whatever.

> Things I want to let in are ssh, vnc (ports 5901 through 5910)
> from two different machines, and ftp from those same two machines.
> I'm not sure what I want to let through just yet -- the old firewall
> rules allowed everything out and only pre-existing connections
> back in, plus DNS responses from wherever.

	Okay, this is fairly easy to do.  I'm setting the default policy
for your firewall to drop packets (defaulting to drop or reject is wise,
it's up to you whether you'd rather silently discard or let the other
side know you're bouncing them).

iptables -P INPUT DROP

or, if you're feeling more like rejecting

iptables -P INPUT REJECT

This sends an ICMP error message when appropriate (almost always, but
won't send an ICMP error in response to an ICMP error, for example).
This lets people know their packets are being bounced by a firewall.  If
you want to make it look like the packets are being bounced by the
machine itself because it's simply not listening on that port (for TCP
connections),

iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

should be the last line in your iptables rules.  It being the last line
is important -- if it's before all your ACCEPT statements, it will end
up rejecting all TCP.  I doubt that's a desirable result. [grin]

	Then you'll want to allow in ssh connections from your two hosts
outside:

iptables -A INPUT -p tcp -s [IP of client 1] --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s [IP of client 2] --dport 22 -j ACCEPT

and VNC connections from those two IPs, too

iptables -A INPUT -p tcp -s [IP of client 1] --dport 5901-5910 -j ACCEPT
iptables -A INPUT -p tcp -s [IP of client 2] --dport 5901-5910 -j ACCEPT

(I'm assuming that VNC only runs over TCP -- from the quick googling I
did about it, those are the ports it seems to use.  If for some reason
you need to be able to access these ports via UDP, just take the "-p
tcp" out of those two lines and you should be fine.

	Other things it's generally good to allow back in through your
stateful firewall -- established and related connections, so that you
can use any sort of TCP client connection that you want from inside:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Established allows traffic in already established TCP connections, but
not new SYN packets.  Related allows the SYN packets of connections
related to established connections, like the data connection in an
active FTP session.

	Dropping connections of invalid state is probably a good thing,
too:

iptables -A INPUT -m state --state INVALID -j DROP

	You probably want to get ICMP error messages, too:

iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT

and echo-replies (if you want to be able to ping outwards successfully)

iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

	Note that this will not allow anyone outside of your firewall to
ping you -- you'll have to also allow echo-requests from the outside
world if you want them to be able to ping you.

(iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT)

	Also, you'll want to allow in DNS replies from your favorite DNS
server (or, depending on your paranoia level, all DNS servers):

iptables -A INPUT -p udp -s [your DNS server] --sport 53 -j ACCEPT

> What =must= work is ICMP has to be masqueraded.  I use NAT inside
> the house on a couple of 192.168.x/24 networks.  What I was trying
> to make work is an AT&T VPN gadget which idiotically tries to
> ping its destinations before attempting to connect to them.  Which
> is =retarded=.  ipchains doesn't handle ICMP properly, so the VPN
> was giving it after the pings failed -- even though it could have
> opened a TCP connection to them.

	How annoying.  

iptables -t nat -A POSTROUTING -o [output interface] -j MASQUERADE

should take care of your masquerading for you.  I haven't heard of any
problems with ICMP masquerading under iptables; it's working fine for me
at home.

	So in summation, you want to make a firewall script to run at
boot that looks something like this:

#!/bin/bash
# Julie's iptables script
#
# Load NAT and connection tracking modules
modprobe iptable_nat
modprobe ip_nat_ftp
modprobe ip_conntrack
modprobe ip_conntrack_ftp
# Add any other connection tracking modules needed
#
# Set sensible security defaults
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
#
# Turn on IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
#
# Clean old iptables 
iptables -F 
iptables -X 
iptables -Z
#
# Default forward policy to DROP (change to REJECT if desired)
iptables -P FORWARD DROP
#
# Turn on masquerading for your interface
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
#
# Allow ssh and VNC incoming connections
iptables -A INPUT -p tcp -s [IP of client 1] --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s [IP of client 2] --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s [IP of client 1] --dport 5901-5910 -j ACCEPT
iptables -A INPUT -p tcp -s [IP of client 2] --dport 5901-5910 -j ACCEPT
#
# Allow DNS from my nameserver
iptables -A INPUT -p udp -s [your DNS server] --sport 53 -j ACCEPT
#
# Allow established and related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Drop invalid connections
iptables -A INPUT -m state --state INVALID -j DROP
#
# Allow ICMP errors and ping replies
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
#
# Reject with TCP reset if desired
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

	Hope this helps you; it'll probably need a bit of tweaking
before it works for your particular setup.  Sorry it took so long --
holidays, and all.

	I have more fun iptables tricks if you're interested in getting
elaborate, but I think this is enough for now.

Cheers,
Raven

"And even on Christmas Eve, the vampires send me money!"
  -- RavenBlack on game development



More information about the Techtalk mailing list