Sample iptables rules list, inviting your suggestions / criticisms (thanks) :-)

Redirected here from the "Post iptables rules in newsgroups" and "What iptables rules to allow name service" threads...

Thanks to all of your help, I think I have what looks to me like a reasonable set of iptables rules to shut down unneeded access while allowing DNS to work to/from the name server that runs on that host.

Please take a look at the following and let me know of any suggestions or criticisms you may have ... thanks :-)

(DESPERATELY hoping that my newsreader, or yours, doesn't hopelessly hose the formatting in the following cut-and-paste...)

# Firewall configuration excerpt # # Based on the config file written by Fedora Core 2 # system-config-securitylevel (the one that says # "Manual customization of this file is not recommended.") # # This firewall only controls access to the machine on which it # runs. This machine does not serve as a router to provide # network access to other machines. # # Objectives: # Allow ftp, http, mail, and ping to and from everybody # Allow ssh to and from certain (trusted) hosts # (the firewall allows ssh from all # and access is controlled in hosts.allow/deny) # Disable telnet, rlogin, rsh, rexec, etc. # (all of which are turned off in xinetd.d anyway...) # Allow name service to and from the name server that # runs on this host (this is a "primary" name server that # also serves several "secondary" name servers) #

*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] # Do I need this? See FORWARD chain below :OUTPUT ACCEPT [0:0] # ################################################################# # # Rule set for the INPUT chain # # Allow anything from the localhost #

-A INPUT -i lo -j ACCEPT # # Allow any icmp (mostly ping ... should I restrict it to ping # only? What other kinds of ICMP are there that could be # intrusive or dangerous?) #

-A INPUT -p icmp --icmp-type any -j ACCEPT # # Allow ftp, ssh, mail, http, https. ssh access is restricted # in hosts.allow and hosts.deny. # # (NOTE: I don't need "-m tcp -p tcp", do I? # Isn't "-m tcp" implied by "-p tcp"? #

-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT # # Enable DNS for input #

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

-A INPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT

-A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT # # Silently drop everything else # # NOTE: Could I eliminate the "-A INPUT -j DROP" rule by just # changing the ":INPUT ACCEPT [0:0]" to ":INPUT DROP [0:0]" up at # the beginning of this rules list? #

-A INPUT -j DROP # ################################################################# # # Rule set for the FORWARD chain. # Everything gets silently dropped. # # NOTE: Do I even need this at all, or should I just eliminate # the FORWARD chain entirely, or change ":FORWARD ACCEPT [0:0]" # to ":FORWARD DROP [0:0]" up near the top of this list? # # /proc/sys/net/ipv4/ip_forward is set to 0. # # If I don't need this, then should I also eliminate the # ":FORWARD ACCEPT [0:0]" up near the top of this list? #

-A FORWARD -j DROP # ################################################################# # # Rule set for the OUTPUT chain. These mostly have to do with # logging although there is one DROP rule. # # Don't log things to the localhost #

-A OUTPUT -o lo -j RETURN # # Disable outbound telnet from local users # (this is the only DROP rule in the chain) #

-A OUTPUT -m state --state NEW -m tcp -p tcp --dport 23 -j DROP # # Enable DNS for output # # NOTE: The following three rules were recommended to me by # 59cobalt on comp.security.firewalls in order to get DNS to # work. However, everything in the OUTPUT chain is ACCEPTed by # default except for one specific DROP to disable telnet, noted # above, so I shouldn't need the following three rules at all, # right? #

-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A OUTPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT

-A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT # # Don't log ping (or any ICMP), mail, http, https, X11-over-ssh, # or dns #

-A OUTPUT -p icmp --icmp-type any -j RETURN

-A OUTPUT -p tcp --sport 25 -j RETURN

-A OUTPUT -p tcp --dport 25 -j RETURN

-A OUTPUT -p tcp --dport 53 -j RETURN

-A OUTPUT -p udp --dport 53 -j RETURN

-A OUTPUT -p tcp --sport 80 -j RETURN

-A OUTPUT -p tcp --dport 80 -j RETURN

-A OUTPUT -p tcp --sport 443 -j RETURN

-A OUTPUT -p tcp --sport 6010 -j RETURN

-A OUTPUT -p tcp --dport 6010 -j RETURN # # Log everything else #

-A OUTPUT -j LOG # COMMIT

Reply to
C. J. Clegg
Loading thread data ...

I'm not familiar with the syntax used above, so I'll be using "default" iptables commandline syntax.

If I understand correctly the lines above set the default policies for the three default chains. These should *always* be set do DROP, otherwise your firewall would fail open, which would be a Really Bad Thing(tm).

iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP

Also make sure to delete all user-defined chains and flush the default chains when starting the firewall:

iptables -F iptables -X

OK.

I wouldn't recommend restricting it to ping only, but I'd definitely recommend applying some restrictions. I'd also recommend putting the rules into a user-defined chain, so you need to define them only once.

iptables -N ICMP iptables -A ICMP -p icmp --icmp-type echo-request -j ACCEPT iptables -A ICMP -p icmp --icmp-type echo-reply -j ACCEPT iptables -A ICMP -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A ICMP -p icmp --icmp-type source-quench -j ACCEPT iptables -A ICMP -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A ICMP -p icmp --icmp-type parameter-problem -j ACCEPT

iptables -A INPUT -p icmp -j ICMP ...

iptables -A OUTPUT -p icmp -j ICMP ...

Yes, "-m tcp" is implicit, so you can omit it to make the rules more concise. In addition to that you can use the "multiport" module to simplify the rules:

ALLOWED_TCP_PORTS="21,22,25,80,443" ... iptables -A INPUT -p tcp -m multiport --dport ${ALLOWED_TCP_PORTS} \\ -m state --state NEW -j ACCEPT

As I had suggested in I'd put the DNS rules into a user-defined chain, so you don't have to define them both in INPUT and OUTPUT chain (unless you don't want that box to access other DNS servers, in which case you can simply put the rules into the INPUT chain as you do above).

iptables -N DNS iptables -A DNS -p udp --dport 53 -m state --state NEW -j ACCEPT iptables -A DNS -p tcp --dport 53 -m state --state NEW -j ACCEPT

iptables -A INPUT -j DNS ...

iptables -A OUTPUT -j DNS ...

Keep in mind that you have to put the ESTABLISHED,RELATED rule into the corresponding chain:

- For allowing *inbound* DNS you need NEW in the INPUT chain and ESTABLISHED,RELATED in the OUTPUT chain.

- For allowing *outbound* DNS you need NEW in the OUTPUT chain and ESTABLISHED,RELATED in the INPUT chain.

As mentioned above you should *always* set the default to DROP. I suppose ":INPUT DROP [0:0]" would do that. In addition to that I suggest to REJECT connections rather than DROP them:

iptables -N DENY iptables -A DENY -p tcp -j REJECT --reject-with tcp-reset iptables -A DENY -p udp -j REJECT --reject-with icmp-port-unreachable

... iptables -A INPUT -j DENY

... iptables -A OUTPUT -j DENY

You can use the "limit" module to limit rejection, causing floods to be DROPed rather than REJECTed:

RATE="20/s" BURST="40" ... iptables -A DENY -p tcp -m limit --limit ${RATE} --limit-burst ${BURST} \\ -j REJECT --reject-with tcp-reset iptables -A DENY -p udp -m limit --limit ${RATE} --limit-burst ${BURST} \\ -j REJECT --reject-with icmp-port-unreachable

FORWARD is one of the netfilter default chains, which are *always* present. Thus you definitely should set a default for it (which should be to DROP everything).

It is *not* advisable to just disallow specific things and allow everything else. Find out what you need to allow, allow just that, and deny everything else.

Traffic with one of the given source-ports is most likely related to inbound requests so there's no need for separate rules for them.

OK.

The following (basic) ruleset should cover your needs:

----8 /proc/sys/net/ipv4/ip_forward

# Set default policies $ipt -P INPUT DROP $ipt -P OUTPUT DROP $ipt -P FORWARD DROP

$ipt -F $ipt -X

# Set up user-defined chains $ipt -N ICMP $ipt -A ICMP -p icmp --icmp-type echo-request -j ACCEPT $ipt -A ICMP -p icmp --icmp-type echo-reply -j ACCEPT $ipt -A ICMP -p icmp --icmp-type destination-unreachable -j ACCEPT $ipt -A ICMP -p icmp --icmp-type source-quench -j ACCEPT $ipt -A ICMP -p icmp --icmp-type time-exceeded -j ACCEPT $ipt -A ICMP -p icmp --icmp-type parameter-problem -j ACCEPT

$ipt -N DNS $ipt -A DNS -p udp --dport 53 -m state --state NEW -j ACCEPT $ipt -A DNS -p tcp --dport 53 -m state --state NEW -j ACCEPT

$ipt -N DENY $ipt -A DENY -p tcp -m limit --limit ${RATE} --limit-burst ${BURST} \\ -j REJECT --reject-with tcp-reset $ipt -A DENY -p udp -m limit --limit ${RATE} --limit-burst ${BURST} \\ -j REJECT --reject-with icmp-port-unreachable $ipt -A DENY -j LOG

# INPUT chain $ipt -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $ipt -A INPUT -i lo -j ACCEPT $ipt -A INPUT -p icmp -j ICMP $ipt -A INPUT -j DNS $ipt -A INPUT -p tcp -m multiport --dport ${ALLOWED_IN_TCP_PORTS} \\ -m state --state NEW -j ACCEPT $ipt -A INPUT -j DENY

# OUTPUT chain $ipt -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $ipt -A OUTPUT -p icmp -j ICMP $ipt -A OUTPUT -j DNS $ipt -A OUTPUT -p tcp -m multiport --dport ${ALLOWED_OUT_TCP_PORTS} \\ -m state --state NEW -j ACCEPT $ipt -A OUTPUT -j DENY

---->8----

cu

59cobalt
Reply to
Ansgar -59cobalt- Wiechers

Cabling-Design.com Forums website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.