Table of Contents
Prior to release 3.0, the favoured firewall tool for OpenBSD was combining ipf with nat.
For a wonderful tutorial on OpenBSD PF check out http://home.nuug.no/~peter/pf/en/ The tutorial is very thorough with many example configurations.
If you're really thinking of using these notes as the basis for firewalling, then don't. This should have been a tutorial for getting ipf, nat working but the OpenBSD FAQ came out with a real nice instructional, so grab the FAQ. I've just kept these notes as a reference hack. Besides, I don't always have an Internet connection to test configuration changes, ideas.
Why have it on the web if there wrong ? Well, some of them I've actually used and they work, and these are notes. These notes continue as an attempt to understand how the ipf rules work, and the basic configuration one would have to secure a site. The fiddles (rulesets) in this list will hopefully document what may have been a safe generic configuration.
Configuration in /etc/sysctl.conf and /etc/rc.conf
IP Filter rules in /etc/ipf.rules
Network Address Translation (NAT) rules in /etc/ipnat.rules
Examples are in /usr/share/ipf
Uncomment the line disabling ip filter
Edit the file: /etc/sysctl.conf
#net.inet.ip.forwarding=1 # 1= Permit forwarding (routing)
or packets
net.inet.ip.forwarding=1 # 1 = Permit forwarding (routing)
or packets
To effect the above (do the above) without having to restart the server. Use the following command documented in the FAQ.
# sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1
To enable ipf and ipnat at boot, change the default filter settings (NO) to YES
Edit the File /etc/rc.conf.local and add the following lines to Section 2
ipfilter=YES
ipnat=YES
This will override the standard settings in /etc/rc.conf
shown here:
ipfilter=NO
ipnat=NO
[ref: ipf(8)]
[File: /etc/ipf.rules]
The standard file location for the ipf.rules will reside in /etc as ipf.rules
Without restarting your computer, and after you've created your 1st set of rules, you can force ipf to start and use the new rules with a command similar to the below:
# ipf -Fa -vf /etc/ipf.rules -E
The -E, enables ipf so if you modify your rules then you can reload the new rules using the same above commands without the -E.
Note that reloading directly from file to the active ruleset is not recommended. Check the FAQ for a better method.
[File: /etc/ipnat.rules]
The standard file location for the ipnat.rules will reside in /etc as ipnat.rules
Without restarting your computer, and after you've created your 1st set of rules, you can force ipnat to start and use the new rules with a command similar to the below:
# ipnat -CF -f /etc/ipnat.rules
[files location: /usr/share/ipf]
The basic OpenBSD installation comes with a number of sample firewall rules. Samples files for ipfilter begin with firewall, while samples for NAT begin with nat.
firewall.1 - tight firewall through ppp connection
firewall.2 - heavy security firewall through a ppp connection
firewall.3 - restrictive firewall through a ppp connection
Other files (example.*) provide examples of specific block/allow scenarios with the filter system
nat.1 - direct-connect (ethernet card) connection to ISP
nat.2 - hints
nat.3 - ppp connection to ISP
[ref: ipf(8)]
Ipf reads its ruleset sequently until it gets to the end of the ruleset (unless it has otherwise been told to stop.) Whichever is the last 'valid' rule that applies to a packet will be the applied rule. This is different from ipfwadm and ipfw who quits on the first applicable rule to incoming packets.
| # ipf filtering example Generic System 1: # * stateless version (does not keep state information) # * class: heavy duty firewalling # Definitions # XTL_LINK - interface with the external to the world eg. xl0 # XTL_IPADDR - IP to external interface eg. 207.124.66.1 # INT_LINK1 - interface_1 on the internal network eg. xl1 # INT_LINK2 - interface_2 on the internal network eg. xl2 # INT_NETWORK - Internal IP network eg. 192.168.101.0 # INT_BMASK0 - Broadcast Mask on 0 eg. 192.168.101.0/16 # INT_BMASK255 - Broadcast Mask on 255 eg. 192.168.101.255/32 |
The above are the definitions used in this example.
| pass in quick on lo0 pass out quick on lo0 |
Allow any inbound/outbound on the loopback interface
| pass in quick on INT_LINK1 pass out quick on INT_LINK1 |
Allow any inbound/outbound on the LAN interface (we can tighten this up further, but for now we're looking after that evil external connection.)
| block in quick on XTL_LINK from 192.168.0.0/16 to any block in quick on XTL_LINK from 172.16.0.0/12 to any block in quick on XTL_LINK from 10.0.0.0/8 to any block in quick on XTL_LINK from 127.0.0.0/8 to any block in quick on XTL_LINK from localhost to any block in quick on XTL_LINK from 255.255.255.255/32 to any block in log quick on XTL_LINK from INT_NETWORK to any |
This ruleset prevents 'spoofing' of private internet addresses from the outside world. We should not be receiving these through the external link because private IP addresses are not routeable.
| block in log quick on XTL_LINK from INT_BMASK0 to any |
There shouldn't be anyone from our Network trying to get through on the outside network card either. This takes into consideration that we are using legitimate/routeable addresses on our internal network.
| block in log quick on XTL_LINK from any to INT_BMASK0 block in log quick on XTL_LINK from any to INT_BMASK255 |
The outside should not be broadcasting on our network either
| block out log quick on XTL_LINK from any to INT_NETWORK block out quick on XTL_LINK from any to 192.168.0.0/16 block out quick on XTL_LINK from any to 172.16.0.0/12 block out quick on XTL_LINK from any to 10.0.0.0/8 block out quick on XTL_LINK from any to 127.0.0.0/8 block out quick on XTL_LINK from any to localhost #[ERROR]block out quick on XTL_LINK from any to 0.0.0.0/32 block out quick on XTL_LINK from any to 255.255.255.255/32 |
Likewise, there should be no reason to find a private address on the outside, so don't waste bandwidth sending stuff that is not going to get routed.
Our two settings should help us diagnose problems with our rulesets or find some attack attempts from outside?
| block out log quick on XTL_LINK from any to INT_BMASK0 |
Since all our ip address should be inside our network, there is no need for sending information for our LAN out on the wire (external link.)
| block in quick on XTL_LINK proto icmp from any to any
icmp-type redir block in quick on XTL_LINK proto tcp/udp all with short block in quick on XTL_LINK from any to any with ipopts |
Block any inherently bad packets coming in from the outside world. These include ICMP redirect packets, IP fragments so short the filtering rules won't be able to examine the whole UDP/TCP header, and anything with IP options.
| block in quick on fxp0 proto tcp from any to any flags FUP |
From the FAQ: If you wanted to deny all packets with the FIN, URG, and
PSH flags set (like for instance an nmap OS fingerprinting attempt) you could
use a rule like the above.
| #pass in quick on XTL_LINK proto icmp from any
to INT_NETWORK icmp-type 0 block in log quick on XTL_LINK proto icmp from any to XTL_IPADDR #pass in quick on XTL_LINK proto icmp from any to INT_NETWORK icmp-type 11 |
LIMIT ACCESS so there is no smurfing ? (ICMP attacks) let in 0 (ping) and 11 (trace-route) but kill it for people who want to bash on the server. Because my sample network uses non-routeable we really shouldn't be allowing in any 'pings' or 'trace-route' from the outside.
| block in on XTL_LINK
proto udp from any to any block in log quick on XTL_LINK proto udp from any to any port = sunrpc block in log quick on XTL_LINK proto tcp/udp from any to any port = nfsd block in log quick on XTL_LINK proto tcp/udp from any to any port = msp block in log quick on XTL_LINK proto tcp/udp from any to any port = chargen block in log quick on XTL_LINK proto tcp/udp from any to any port = time pass in on XTL_LINK proto udp from any to any port = domain pass in on XTL_LINK proto udp from any to any port = talk pass in on XTL_LINK proto udp from any to any port = ntalk |
[UDP PACKETS] Block all incoming UDP traffic except talk and DNS traffic. NFS and portmap are special-cased and logged.
| block in log quick on XTL_LINK proto tcp from any to INT_NETWORK port = 513 block in log quick on XTL_LINK proto tcp from any to INT_NETWORK port = 514 block in log quick on XTL_LINK proto tcp from any to INT_NETWORK port = 23 block in log quick on XTL_LINK proto tcp/udp from any to XTL_IPADDR port = 109 block in log quick on XTL_LINK proto tcp/udp from any to XTL_IPADDR port = 110 block in log quick on XTL_LINK proto tcp/udp from any to XTL_IPADDR port = 143 block in log quick on XTL_LINK proto tcp/udp from any to XTL_IPADDR port = 220 block in log quick on XTL_LINK proto tcp/udp from any to XTL_IPADDR port = 901 |
[PORTS WITH BAD SECURITY] Block ports with clear-text password transfers from coming in on the external link
513 rlogin 109 pop2 901 swat
514 rsh 110 pop3
23 telnet 220/143 imap
| block return-rst in log on XTL_LINK proto tcp from any to any flags S/SA block return-rst in on XTL_LINK proto tcp from any to any port = auth flags S/SA block in log quick on XTL_LINK proto tcp/udp from any to INT_NETWORK port = 111 block in log quick on XTL_LINK proto udp from any to INT_NETWORK port = 514 block in log quick on XTL_LINK proto tcp from any to INT_NETWORK port = 515 block in log quick on XTL_LINK proto tcp/udp from any to INT_NETWORK port = 2049 block in log quick on XTL_LINK proto tcp from any to INT_NETWORK port = 6000 |
[KNOWN SERVICES] Block all incoming TCP traffic connections to known services, returning a connection reset so things like ident don't take forever timing out. Don't log ident (auth port) as it's so common.
| pass in on XTL_LINK proto tcp from any to any port 1024 >< 5000 #pass in on XTL_LINK proto tcp from any port = ftp-data to any port 1024 >< 5000 |
Allow incoming TCP connections to ports between 1024 and 5000, as these don't have daemons listening but are used by outgoing services like ftp and talk. For slightly more obscurity (though not much more security), the second commented out rule can chosen instead.
| pass out on XTL_LINK from INT_NETWORK to any keep state pass in on XTL_LINK from any to INT_NETWORK pass out on INT_LINK1 from INT_NETWORK to any pass in on INT_LINK1 from any to INT_NETWORK #pass out on INT_LINK2 from INT_NETWORK to any #pass in on INT_LINK2 from any to INT_NETWORK |
[GENERAL SETTINGS] Pass any packets from Internal Network to the world. Let in
any packets for Internal Network from the world
[ref: ipnat(8)]
| # ipnat Name Address Translation example Generic
System 1: # # Definitions # XTL_LINK - interface with the external connection to the world eg. xl0 # INTL_LINK - interface with the internal connection (LAN) e.g. xl1 # INT_NETWORK - Internal IP network eg. 192.168.101.0/16 # EXT_NETWORK - External IP network eg. 207.124.66.1 # # INT_RDR_MAIL - ip addr of Mail Server eg. 192.168.101.25 # INT_RDR_FTP - ip addr of FTP Server eg. 192.168.101.21 # INT_RDR_DNS - ip addr of DNS Server |
| map XTL_LINK INT_NETWORK -> XTL_LINK/32 portmap tcp/udp 10000:60000 map XTL_LINK INT_NETWORK -> EXT_NETWORK/32 |
map tells the NAT how a range of addresses should be translated. The entries use the following format:
| map ifname internal/mask -> external/mask options |
The ifname field is the interface to which packets are sent. Since we are trying to connect to the rest of the world, we use our external interface as 'ifname'.
| map xl0 192.168.101.0/16 -> 207.124.66.1/32 portmap tcp/udp 10000:60000 map xl0 192.168.101.0/16 -> 207.124.66.1/32 |
Our above rule remaps all connections originating from INT_NETWORK (192.168.101.0 through to 192.168.101.254) to the externally-connected network
The external address is the offically assigned IP number of the gateway or network.
mask is the netmask of the address. This mask is 32 bits long, and is divided into four 8-bit numbers.
The option portmap used in the above example solves the problem of trying to shove a large number of ip addresses (your LAN) into a one small 'external ip address' address space (the external interface.)
rdr tells the NAT how to redirect incoming packets. It is useful if one wishes to redirect a connection through a proxy, or to another box on the private network. The format of this directive is:
rdr ifname external/mask port service -> internal port service protocol
This setup is best described by an example of an actual entry:
|
# rdr XTL_LINK EXT_NETWORK/32 port ftp -> INT_RDR_FTP port ftp
rdr xl0 204.124.66.1/32 port ftp -> 192.168.101.21 port ftp |
This redirects all ftp packets received on XTL_LINK to EXT_NETWORK, port ftp. A netmask is not needed on the internal address; it is always 32. The external and internal fields, similar to the map directive, may be actual addresses, hostnames, or interfaces. Likewise, the service field may be the name of a service, or a port number. The protocol of the service may be selected by appending tcp, udp, tcp/udp, or tcpudp (the last two have the same effect) to the end of the line. TCP is the default.
I am using EXT_NETWORK above, as we are only accepting the ports access from real ip addresses to real ip addresses (no internal service should be directly accessible due to the firewall ipf rulesets)
| rdr XTL_LINK EXT_NETWORK/32 port www -> INT_RDR_WWW port www rdr XTL_LINK EXT_NETWORK/32 port smtp -> INT_RDR_MAIL port smtp rdr XTL_LINK EXT_NETWORK/32 port ssh -> INT_RDR_SSH port ssh |
Redirect www, smtp, ssh to the internal boxes that will be handling these services (keep the load off the gateway box.)
The following sample was published by Mr. James Deucker on the OpenBSD misc mailing list.
From: "Deucker, James H." To: "'misc@openbsd.org'"Subject: ipf.rules Date: Mon, 14 Aug 2000 22:43:16 -0500 I hear people asking for example rules sets for ipf, and they're really not that hard to put together from the manuals, faq and ipfilter web page. However, as I see so many people ask so often, I thought I'd post my ipf.rules set for perusal in the archives. I don't claim this set to be complete, I don't even claim that they secure. They seem to do what I want at the moment, and I'd certainly appreciate any comments on them. I'm here to have fun and learn heaps. Notes: my internal network is 172.16.2.0/24, on interface ep1. My external interface is on ep2, the ip changes, and it's hooked up to my cable modem (telstra bigpond [australia] cable network). I don't care what goes on in my internal network, and at the moment I don't use NAT, that's a project for next week when things have calmed down at work. I use Squid 2.3 from Ports for http, I use SOCKS5 for ICQ and napster. I run ssh on its normal port and a high one (2022). I use sendmail to send mail out from my network, and fetchmail to pull all our mailboxes down. I use homeip.net dyndns to give me a name to point to ssh in. I allow ident packets to the firewall. So, for your enjoyment, here they are.#----ipf.rules----8*<----snip-below-this-line---- # # LOOPBACK # # allow any inbound/outbound on the loopback interface pass in quick on lo0 pass out quick on lo0 # -------------------------------------------------------- # # LAN # # allow any inbound/outbound on the LAN interface pass in quick on ep1 pass out quick on ep1 # -------------------------------------------------------- # # HOSTILE # # prevent spoofing in and out # from unroutable addresses block in log quick on ep2 from 127.0.0.0/8 to any block in log quick on ep2 from 192.168.0.0/16 to any block in log quick on ep2 from 169.254.0.0/16 to any block in log quick on ep2 from 172.16.0.0/12 to any block in log quick on ep2 from 10.0.0.0/8 to any block out log quick on ep2 from 127.0.0.0/8 to any block out log quick on ep2 from 192.168.0.0/16 to any block out log quick on ep2 from 169.254.0.0/16 to any block out log quick on ep2 from 172.16.0.0/12 to any block out log quick on ep2 from 10.0.0.0/8 to any # explicit allow pass in quick on ep2 from any to any port = ssh pass in quick on ep2 from any to any port = 2022 # ssh high port pass in quick on ep2 proto tcp from any to any port = auth # block too-small fragments block in log quick proto tcp all with short # block source routed packets block in log quick on ep2 all with opt lsrr block in log quick on ep2 all with opt ssrr # block OS fingerprinting block in log quick on ep2 proto tcp from any to any flags FUP # default deny block return-icmp-as-dest(port-unr) in log quick on ep2 proto udp from any to any block return-rst in log quick on ep2 proto tcp from any to any block in log quick on ep2 from any to any # allow traffic out pass out on ep2 proto tcp from any to any keep state pass out on ep2 proto udp from any to any keep state pass out on ep2 proto icmp from any to any keep state#----ipf.rules---->*8----snip-above-this-line---- If people would so desire, I can also post my squid.conf, socks5.conf, fetchmail.conf and m4 for sendmail. (though I'd probably just post a diff against squid.conf from the default ports one) And just to reiterate, please if you have any comments or suggestions as to how I can do this any better, tell me :) enjoy, James Deucker Patrician of Networks
Relative References
OpenBSD FAQ
IP Filter Based Firewalls HOWTO
Internet Firewalls: FAQ
[Posted 2002-07-23]
I was able to create a firewall/router combination that handles both
Ethernet and wireless traffic by using OpenBSD 3.1 and pf. A full
description of my experience is at the URL that follows. Please feel free
to link to it, or contact me with comments or corrections:
http://www.well.com/~jbyrd/firewall.html
I have no opinion about which firewall solution or filtering package is
"best". I merely report what worked in my case, and I'm confident
that
other methods could have been used to achieve a similar result.
I don't subscribe to this list, so please feel free to contact me
out-of-band with comments or additions.
Sincerely,
John Byrd
Copyright (c) 2000/1/2 Samiuela LV Taufa. All Rights Reserved.
I reserve the right to be totally incorrect even at the best advice of betters. In other words, I'm probably wrong in enough places for you to call me an idiot, but don't 'cause you'll hurt my sensibilities, just tell me where I went wrong and I'll try again.
You are permitted and encouraged to use this guide for fun or for profit as you see fit. If you republish this work in what-ever form, it would be nice (though not enforceable) to be credited.
|
Firewalling - Keeping the BAD GUYS out |
Copyright © 2000/1/2 NoMoa.COM All rights reserved.