ipfw Rules, v2007/12/12



Based on extensive feedback, these rules are now much improved over the initial draft. Thanks, all!

All the versions of this post are getting out of hand, so Rich has provided a permanent URL for the current Leopard ipfw post for future reference. Please use that link, so future visitors get the latest and greatest.

Chris


# DO NOT USE THESE RULES without customizing them first!
# Version: 2007/12/12

# For more information, see http://securosis.com/2007/11/15/ipfw-rules/
# & http://securosis.com/2007/11/16/ipfw-rules-20071116-revision/#comments

# These rules *MUST* be customized to your requirements.
# In particular, if you have a private home network (behind an AirPort
# Base Station, Linksys WRT54G, etc.), change “10.42.24.0/24″ below to
# your private network range; duplicate rules with different ranges, if use use this computer on multiple networks.
# Additionally, allow only ports you actually use; block unused ports.

# Thanks to:
# Rich Mogull http://securosis.com
# windexh8er: http://www.slash32.com/
# Rob
# Lee: http://thnetos.wordpress.com/
# Josh
# Chris Pepper http://www.extrapepperoni.com/
# Apple (Server Admin is a good way to create an ipfw ruleset)
# http://www.apple.com/server/macosx/
# FreeBSD (where Apple got ipfw) http://www.freebsd.org/

# We don’t really want this, but it’s unavoidable on Mac OS X Server, so
# document it here (serialnumberd).
# 100 allow udp from any 626 to any dst-port 626

# Let me talk to myself over the loopback.
add 200 allow ip from any to any via lo0

# Loopback traffic on a ‘real’ interface is bogus.
add 300 deny log logamount 1000 ip from any to 127.0.0.0/8

# Block multicast unless you need it.
# add 400 deny log logamount 1000 ip from 224.0.0.0/4 to any in

# If we let a conversation begin, let it continue.
# Let my clients go!
add 500 allow tcp from any to any out keep-state
add 510 allow udp from any to any out keep-state
# Block replies, if we don’t recall initiating the conversation.
add 520 deny log tcp from any to any established in

# Allow DHCP responses (keep-state can’t handle DHCP broadcasts).
add 600 allow udp from any to any src-port 67 dst-port 68 in

# Do you never need fragmented packets?
# add 700 deny udp from any to any in frag

# Let yourself ping.
# add 1000 allow icmp from 10.42.24.0/24 to any icmptypes 8

# Server Admin provides these by default.
add 1100 allow icmp from any to any icmptypes 0
add 1110 allow igmp from any to any

# mDNS (Bonjour) from trusted local networks (fill in your own,
# preferably non-standard, networks after ‘from’).
# For Back to My Mac, you might need this from ‘any’.
# add 5000 allow udp from 10.42.24.0/24 to any dst-port 5353
# add 5010 allow udp from 10.42.24.0/24 5353 to any dst-port 1024-65535 in

# ssh — should be restricted to trusted networks if at all possible; if
# open to the Internet, make sure you don’t have “PermitRootLogin yes
# in sshd_config (at least use
# PermitRootLogin without-password“, please!)
add 5200 allow tcp from any to any dst-port 22

# iTunes music sharing
# add 5300 allow tcp from 10.42.24.0/24 to any dst-port 3689

# AFP
# add 5400 allow tcp from 10.42.24.0/24 to any dst-port 548

# HTTP (Apache); HTTPS
# add 5500 allow tcp from any to any dst-port 80
# add 5510 allow tcp from any to any dst-port 443

# L2TP VPN — is this complete?
# add 5600 allow udp from any to any dst-port 1701
# add 5610 allow esp from any to any
# add 5620 allow udp from any to any dst-port 500
# add 5630 allow udp from any to any dst-port 4500

# iChat: local
# add 5700 allow tcp from 10.42.24.0/24 to any dst-port 5298
# add 5710 allow udp from 10.42.24.0/24 to any dst-port 5298
# add 5720 allow udp from 10.42.24.0/24 to any dst-port 5297,5678

# Server Admin SSL (Mac OS X Server only)
# add 5800 allow tcp from 10.42.24.0/24 to any dst-port 311
# add 5810 allow tcp from 10.42.24.0/24 to any dst-port 427
# add 5820 allow udp from 10.42.24.0/24 to any dst-port 427

# syslog — uncommon
# add 5900 allow udp from 10.42.24.0/24 to any dst-port 514

# ipp (CUPS printing)
# add 6000 allow tcp from 10.42.24.0/24 to any dst-port 631

# MTU discovery
add 10000 allow icmp from any to any icmptypes 3

# Source quench
add 10100 allow icmp from any to any icmptypes 4

# Ping out; accept ping answers.
add 10200 allow icmp from any to any icmptypes 8 out
add 10210 allow icmp from any to any icmptypes 0 in

# Allow outbound traceroute.
add 10300 allow icmp from any to any icmptypes 11 in

# My default policy: log and drop anything that hasn’t matched an allow
# rule above
add 65534 deny log logamount 1000 ip from any to any

# Hard-coded default allow rule (compiled into Darwin kernel)
add 65535 allow ip from any to any

Posted on

24 comments

  1. windexh8er Dec 12

    Nice work — haven’t really gone over it in detail yet but the one thing that stuck out was commented out line 1000 is already uncommented in line 10200. 1100 trumps 10210, so it would never get hit. 1100 lets replies go so people can ping you. If you don’t need that just erase 1100 and 10200 and 10210 will take care of you nicely.

    –windexh8er

  2. davidlballenger Dec 12

    Thanks for this, it’s helped me tune up my on rule set. However, this version seems to be missing the check-state statement that was in previous versions. Isn’t that required?

    - David

  3. windexh8er Dec 12

    They catch it back in with the established in line (520). I personally don’t like doing it that way, but… I’ve argued my point on that one enough. :)

  4. windexh8er Dec 12

    Ooop, read that wrong they left that as a deny. Not sure actually if this would work the way it’s stated.

  5. diem Dec 13

    @davidballenger:

    None of the rules now include the ‘keep-state’ or ‘limit’ keywords which create the dynamic ruleset, hence there is no need to check this dynamic set with ‘check-state’.

    It would however be nice to know the rationale for removing this?

  6. diem Dec 13

    By the by, I really like the variable substitution features of the ruleset published here:

    http://www.novajo.ca/firewall.html

  7. Pepper Dec 13

    @windexh8er,

    You’re right, 1000/1100 doesn’t make sense; I lifted that directly from the configuration Apple’s Server Admin creates, but I can’t think of a reason to do it that way. Next round, 1000 is for the chop!

    What do you mean about a deny not working as stated? The keep-states are allows.

    @davidballenger,

    keep-state (500/510) implicitly includes check-state, so the preceding check-state rule was redundant and I removed it (someone suggested this in a previous comment). If there were intervening rules, having the check-state earlier might be worthwhile, but not if they’re adjacent.

    @diem,

    No, dynamic rules are all handled within 500/510.

    Yes, I really like variable substitution. If you write your own shell script, you can do it, too! But I’m not going to take on the task of writing a robust, safe, and secure firewall loading engine, so I suggested Hany add this to WaterRoof. It’s a new type of complexity, though, so I don’t know if he’ll bother.

    Just note that it’s easy to re-cast these rules (or whatever you get out of “ipfw list” as a shell script to load rules, and then you get shell features like $VARIABLES.

    What I really want, though, is auto-configuration of local networks, so you can allow Bonjour, printing, SLP, etc. from whatever network you’re in. For that, we’d need code with enough smarts to detect the addresses and netmasks of all active interfaces, and a trigger on network reconfiguration (I had this back in the Jaguar area — it’s probably easier to do with launchd now), and a preference for whether to update automatically on network reconnection.

    The idea is that whenever configd/launchd notices a network change, the firewall configuration engine would generate 0 or more lines, substituting in all the local networks for $LOCAL in a template ruleset. Note that in this scenario, (un-)plugging a network cable or changing AirPort networks would implicitly flush all dynamic rules, so outstanding HTTP/HTTPS responses would be dropped.

  8. windexh8er Dec 13

    @diem:

    Sure there are:
    add 500 allow tcp from any to any out keep-state
    add 510 allow udp from any to any out keep-state

    So where is the check-state?

  9. windexh8er Dec 13

    The reason why check-state, to me, is valuable is in this situation. I have my check-state above my deny established which directly follows. Now I have my keep-states below this. What this does for me is allows my check-state (as in the config posted here) to not get lost in the mix and accidentally allow something I might otherwise not have wanted back in. That and if my ruleset is particularly large, having the check-state at the top of the rules allows IPFW to do less work (as we parse the rules in order until we get an allow or deny). For a workstation this is probably trivial, but I like to know where things are getting back in with regards to dynamic entries. I can also easily log all dynamic transactions in as well using this methodology.

  10. Pepper Dec 13

    @windexh8r,

    If there were intervening rules, I’d keep the check-state so it ran earlier for performance reasons (since most traffic statistically is HTTP & email responses to dynamic rules). Since the rules were adjacent, though, the only performance impact would be a negative — one more rule to process before ipfw gets to 520.

    As far as clarity, I think that makes perfect sense for you, but less for the intended audience of this post, many of whom don’t yet know what check-state/keep-state do.

    I don’t see any mention of the source rule in the dynamic entries (”ipfw -d list”), so I’m not too concerned with breaking that out for logging.

  11. windexh8er Dec 13

    @pepper,

    You’re correct with regards to your explanation (and it’s a good one). I think if someone were to read through IPFW they would wonder where the check-state is however since the outline usually describes the check-state as a staple rule.

    The source rule (i.e. check-state) never gets referenced in the dynamic entries list because that would make it confusing to see why the dynamic entry was allowing the traffic in with no apparent reference. If you have a lot of keep-states it makes sense that the dynamic entries tell you which rule it is paired up with, but the primary check-state will still be the rule to process the transaction.

    For me I’m more in the mindset of using IPFW on a server or as a dedicated firewall, and I’ve seen rulesets in excess of 70k rules which probably drives my persuasion of building rulesets slightly. :)

  12. arnulf Dec 18

    here’s yet another ipfw rule set: http://textsnippets.com/posts/show/1267

  13. nobby Apr 15

    I tried to add pptp support for this ruleset, but despite making port 1723 available and allowing gre packeges to pass through my Mac failed to establish a connection with the VPN-gateway. Any hints on that?

  14. random Apr 17

    Are implicit check-states (via keep-state) rule specific?
    That is, in the absence of an explicit check-state: does
    the first rule with a keep-state (call it rule N) invoke
    a check-state that applies to all dynamic rules, or just
    those created by rule N?

    My apologies if that’s terribly worded.

  15. Pepper Apr 17

    random,

    keepstate applies to all dynamic rules.

  16. random Apr 17

    Thanks, Pepper.

    Also, I wonder if 500&510 should or could
    have a “setup keep-state” rather than just
    “keep-state”. Perhaps that’s unnecessarily
    strict for outgoing traffic.

  17. dream.x Jun 16

    Taking advice from http://codesnippets.joyent.com/posts/show/1267 , I’d suggest some other rules in order to make SAMBA work properly in Leopard:

    # SMB
    add 5412 allow tcp from me to 10.42.24.0/24 137,138,139 keep-state setup out
    add 5413 allow tcp from 10.42.24.0/24 137,138,139 to me keep-state setup in
    add 5410 allow udp from me to 10.42.24.0/24 137,138,139 keep-state out
    add 5411 allow udp from 10.42.24.0/24 137,138,139 to me keep-state in

  18. Andy Jun 25

    Do not want to get posted online but you can pass on the thanks to those who assist in this group.

    As a single home computer plugging into a router I often get confused as to how to set up Leopard Firewall for max security. So many rule-sets are for networks and thus complicated, or with too many rules for a simple single user.
    I’m pretty much an average user with an unusual amount of hacking and hijinx going on trying to get into my system. I don’t use bonjour or sharing. I just pretty much use iTunes for internet radio, almostVPN and Secure-Tunnel.com for security at times while surfing,(it’s the principle-I don’t view porn or engage in subversive activities, unless now days poetry or other writings of our current state is such?), and email. I want to keep my system tight just for those services and block others. (Those guys next door are skilled and can and do get in at times.)

    I have included my most recent rule-set patched out of the basic Leopard rules with a few other suggestions added.
    Can anyone comment on these? (I do want to express my gratitude to all you security geeks who post on setting up the ipfw firewall in OS X and of course the WaterRoof people. They make it possible that I can actually setup and adjust my ipfw firewall and you all give the rule-sets to try out)

    I wonder if I am being overly redundant with the check-state and ‘deny log all from any to any not verrevpath in’ and if I have them placed correctly?
    And from rule 2 to 5?
    Do I need to put in rules to keep out netbios as not being on a network I don’t think I need it and in many firewall suggestions, as in Windows, they suggest blocking it or closing it’s ports? Or is this rule-set pretty much an air tight, hack-proof, set?

    I do suggest a series of single home rule-sets for us less
    skilled at this than you who post on this site. The basic Leopard set was a great start at this. Something easy to import into WaterRoof. If each line had a basic explanation as the Basic Leopard did then people would know what to delete or change to deny. Once done it would of enormous benefit to thousands of non-networked home users and perhaps WaterRoof could include your webpage as added security sets for the single home user.
    Perhaps I will email them suggesting that.

    From the Basic Leopard ipfw rule-set with a few added suggestions. How good is this?

    add 01000 allow ip from any to any via lo0
    add 01200 deny ip from 127.0.0.0/8 to any in
    add 01300 deny ip from any to 127.0.0.0/8 in
    add 01400 deny log ip from 224.0.0.0/3 to any in
    add 01500 deny log ip from 224.0.0.0/8 to any in
    add 01600 check-state
    add 01700 deny log ip from any to any frag
    add 01800 deny log tcp from any to any established in
    add 01900 allow udp from any 67 to any dst-port 68 in
    add 02000 deny log all from any to any not verrevpath in
    add 02100 allow icmp from any to any icmptypes 3
    add 02110 allow icmp from any to any icmptypes 4
    add 02120 allow icmp from any to any icmptypes 8 out
    add 02130 allow icmp from any to any icmptypes 0 in
    add 02140 allow icmp from any to any icmptypes 11 in
    add 01800 deny igmp from any to any
    add 65500 allow tcp from me to any keep-state
    add 65510 allow udp from me to any keep-state
    add 65534 deny log ip from any to any
    add 65535 allow ip from any to any

    Again: Much thanks to you all who assist us home users.

    I did check out MIT ipfw@http://codesnippets.joyent.com/posts/show/1267. As soon as I get my brain transplant I will try this one out. Most of us need it to be kept pretty simple.

    Cheers-Andy Apple-Seed

  19. Juanito Jul 2

    Hi,

    This is all nice but i would need a dynamic rule that would work as Fail2Ban on linux.
    I’m a total new-bee when it comes to firewalls and computer security, but i doo lately have a lot of brute-force hackling attempts. At least my secure.log is full of failed login attempts.

    I don’t want to ban any ip for good. Just block them for a while when 3 failed attempts has happend.

    Any one able to assist someone a new-bee like me. I would prefere to keep it as simple as possible. If i need to recompile anything i will need assistance there too.

    I was considering writing an AppleScript but that is not the way to go i think.

  20. cygo Jul 3

    @juanito:

    Regarding SSH login attempts, you may specify


    LoginGraceTime 30s
    MaxAuthTries 3

    in

    /private/etc/sshd_config

    For more information on configuring sshd see:

    http://codesnippets.joyent.com/posts/show/1326

    http://www.apple.com/support/security/guides/

    Similar to Fail2Ban on Linux you may be “Using TCP_Wrappers To Block Attacks”

    http://www.la-samhna.de/library/brutessh.html#5

    Bye

    cygo

  21. Juanito Jul 6

    Thank you for your reply.

    I’ve tried to figure out this with TCP_Wrappers but as I sit on Mac OS X Leopard. I cannot find the files that this tutorial referes to ( http://www.la-samhna.de/library/brutessh.html#5 ).

    Or doo I need to do some further configurations for sshd?

  22. cygo Jul 7

    @juanito:

    Just make sure the files & directories the script is going to use exist, i.e. just create them if necessary.

    sudo mkdir -p path_to_dir
    sudo touch path_to_file
    chmod 0644 path_to_dir path_to_file

    (see: man 5 hosts_access)

    For an alternative btw see:
    http://www.hmug.org/pub/MacOS_X/BSD/Administration/Log/BlockHosts/

    To block an IP address on the fly you may use:

    sudo route -n add -host 127.0.0.1 -blackhole # block
    netstat -rn | grep # show routing table
    sudo route delete 127.0.0.1 # undo blocking

    Bye

    cygo

  23. cygo Jul 7

    @juanito:

    Correcting … To block an IP address on the fly you may use:

    sudo route -n add -host IPNUM 127.0.0.1 -blackhole # block IPNUM
    netstat -rn | grep IPNUM # show routing table
    sudo route delete IPNUM 127.0.0.1 # undo blocking

    … and in /private/etc/sshd_config you may specify

    MaxStartups 5

    to specify the maximum number of concurrent unauthenticated connections to the SSH daemon.

    (see man 5 sshd_config for further options)

    Bye

    cygo

  1. Sicher mit OS X Leopard: Firewall einrichten | QuarkStar

Leave a reply

Related Posts

Leopard Firewall- Apple Documents And Potentially Good News
Permanent Link For ipfw Rules
ipfw Rules, 2007/11/15 revision