This little paper covers Solaris and *BSD with Ipfilter. Some general procedures apply to all Systems so don't skip these if you are only interested in Linux.

0.1 What  is Ipfilter ?

Ipfilter is a powerful packetfilter. It includes advanced Packetfiltering and NAT (Network Address Translation) Functions. With Ipfilter its simple to connect a whole private Network to the internet with just one global IP. It works the same way as Linux Masquerading.

It should be noted that NAT is limited to protocols with certain properties like no embedded IPs, fixed Ports etc. - otherwise the use of special Proxy's is required. Ipfilter has some Proxy's for common used Application Protocol's like FTP or Realaudio.

The examples in the text are based on Solaris 8 with some comments on how this may look like on OpenBSD. FreeBSD/NetBSD should work either similar or the same as with OpenBSD. The focus of the text is not the configuration of ipfilter - its the configuration of a secure System - which in the end will run the packetfilter.

The examples showing additional Services like BIND running on the Firewall should be taken with great care. In general it's a very BAD Idea to run anything else on your Firewall than the packetfilter itself or some Proxys.

Home Users and/or small Businesses with limited resources and no (low) budget who need to protect access to the internal Network may want to compromise security for DNS speedup and things like that.  To put it in another way  -  you definitly should run those Services on separate machines to prevent someone injecting some nasty code through a vulnerable service.  If this isn't possible use at least Features like chroot (Jails), non-exec Stacks etc. to limit the damage by bufferoveruns and the like !

0.1 Everybody uses  ipchains / netfilter - why ipfilter ?

Some good reasons for using Ipfilter :
  1. Ipfilter is portabel (Solaris, *BSD, True64, Irix ). Changing the Platform were Ipfilter runs is possible and simple. Runs on Risc and CISC CPU's.
  2. Ipfilter is stateful (tcp, udp and icmp). Sessions (TCP 3 Way Handshaking) and  request/ response (UDP/ICMP)  are recognized in the sense of related packets.
  3. Ipfilter has a powerful well thought out filtering Language similar to the Cisco Pix and way better than netfilter (cmd line).
  4. Ipfilter has some NAT features not available in Linux (1x1 or blocks of IPs).
  5. Ipfilter can cope with thousands of Rules Ipfilter has many Options for Filtering traffic based on IP, Proto, Port and Header Fields Installing Ipfilter is simple (Solaris) if needed at all (*BSD). Just a  Kernel Modul plus some User Programms. Only two simple configuration Files.
  6. OpenBSD, NetBSD and FreeBSD come with Ipfilter. OpenBSD removed Ipfilter around May 2001 (license Issue). The new ipfilter compatible packetfilter is called pf, which has almost identical Syntax. Ipfilter still runs on OpenBSD. PF will be covered soon .

1.0 Pre Setup Steps

1.1 Additional Resources

At www.sun.com (Admin Link) you can fetch some PDF's about securing Solaris Systems :
    • security.pdf . Reduce Services to a bare minimum, set strict Filesystem permissions, minimal Accounts etc.
    • network.pdf. Using ndd to tune Solaris TCP/IP for Security. Explains common Attacks like Syn Floods etc. and how to deal with it.
    • minimization.pdf .  Reducing Solaris to a point were nothing else runs or is installed beside the services we really need.
Official Solaris Tunable Parameters Reference Manual
    The 'official' ipfilter HOWTO Document. 2nd best Document to learn ipfilter.
http://www.openlysecure.org/ - The only Ipfilter Book i know (OpenBSD Examples and Setup)
    Companion Site  to the Book 'Building Linux and OpenBSD Firewall' from Wes Sonnenreich & Tom Yates  (Willey  - 2000).
    Some nice Papers about 'hardening' Operating Systems like Solaris 
A nice Paper about Network tunables in Solaris 2.x

1.1.1 Some important Solaris Setup Files

1.1.2 Basic Commands

1.1.3 Technical Papers - Links

1.2 Preparing the Firewall

Running a packetfilter on a unstable or insecure system makes no sense at all. So building a secure base is essential. Candidates to remove from /etc/init.d

Either remove the Link from /etc/rc?.d , or rename the the Files. S??xxx should be renamed to s??xxx, K??xxx to k??xxx
NFS Service /etc/rc2.d/S73nfs.client
RPC /etc/rc2.d/S71rpc


1.2.1 Networksetings & Solaris ndd

ndd allows to set/get properties from the network sub systems. You can also query which options a device supports (ndd  device \?).
Example - /dev/arp # /usr/sbin/ndd /dev/arp \?
?                             (read only)
arp_cache_report              (read only)
arp_debug                     (read and write)
arp_cleanup_interval          (read and write)
arp_publish_interval          (read and write)
arp_publish_count             (read and write)

# /usr/sbin/ndd  -get /dev/arp arp_publish_count

To make arp spoofing attacks a bit harder you can hardwire MAC<-->IP Mappings. Changing a broken Network card requires manual changing the Arp table or the Host is out of business.

arp -f  /etc/staticArp

ICMP  (see R.W. Stevens / TCP/IP Illustrated Vol. I for Broadcasts, Source Routing ..)
  • Preventing broadcast floods (smurf) is always a good idea
  • don't reply to Bcast pings

  • close Information leaks
/usr/sbin/ndd -set /dev/ip ip_respond_to_echo_broadcast 0
/usr/sbin/ndd -set /dev/ip ip_forward_directed_broadcasts 0
/usr/sbin/ndd -set /dev/ip ip_forward_src_routed 0
/usr/sbin/ndd -set /dev/ip ip_ignore_redirect 1
/usr/sbin/ndd -set /dev/ip ip_respond_to_timestamp 0
/usr/sbin/ndd -set /dev/ip ip_respond_to_timestamp_broadcast 0
Set strong ISS
/etc/default/inetinit and change from TCP_STRONG_ISS=1 to TCP_STRONG_ISS=2
Routing No Source Routing // Ipfilter does this with opt lsrr
# ndd -set /dev/ip ip_forward_src_routed 0
possible DoS
# ndd -set /dev/ip ip_ignore_redirect 1


1.2.2 Using ifconfig

ifconfig manages the network interfaces. It shows or sets properties.

Sparc : # ifconfig -a

lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4> mtu 8232 index 1
        inet netmask ff000000
hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
        inet netmask ffffff00 broadcast
        ether 8:0:20:a8:45:dd
Intel : # ifconfig -a
lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4> mtu 8232 index 1
        inet netmask ff000000
elxl0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
        inet netmask ff000000 broadcast
        ether 0:60:8:4c:65:e8
iprb0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 3
        inet netmask ffffff00 broadcast
        ether 0:a0:c9:93:13:69
shut down hme0
# ifconfig hme0 down
remove interface from stream
# ifconfig hme0 unplumb
activate interface (push module on stream)
# ifconfig hme0 plumb

set some properties for hme0 like IP, Mask etc.

# ifconfig hme0 netmask up

Failover Sequence from hme0 to hme1

# ifconfig hme0 down
# ifconfig hme0 unplumb
# ifconfig hme1 plumb
# ifconfig hme1 netmask up
Virtual Interfaces look like this:   hme0:1

Adding a phys. Interface

A new Interface only needs the  /etc/hostname.DriverInstance File.


Der Name sun1 ist defined in /etc/hosts. Issue  touch /reconfigure or at boot boot -r . This rebuilds the Device Database and adds the necessary need device node(s).
Virtual Interfaces follow the same convention as phys. Interfaces: /etc/hostname.<DRVinst#:Log#>

1.2.3 ACL's and File Permissions

There are Scripts out there to look for permissions problems (unnecessary suid , world reads etc.) and correct them. Beside this Solaris has RBAC (Role based access control, ACL's (Access Control Lists),  Security Levels (aset) and Accounting (acct).

1.2.2 Executable Code on the  Stack

The popular buffer overrun exploits almost all  execute code on the Stack. On Solaris this can be disabled (.. this may break some code using this 'feature').
This needs a reboot to take effect !


set noexec_user_stack=1
set noexec_user_stack_log=1
# searching for file with specific perms
find / -user root -perm -4000 -exec ls -ldb {} \;

2.0  Configuration

The example is based on a dialup connection with asppd (/dev/ipdptp) but could be anything else .

2.1 DSL and Modem Configuration

See my examples for Solaris/T-Online oder OpenBSD/T-Online (Modem or DSL) LINKS -> (a / a2 / b / c). In all these examples the Firewall and Border Router is one machine. With static IP's you will get a Border Router from your ISP. This is more secure (additional filtering , Net between you and the outside world).

2.2 Netmask's with Solaris

The examples shows a subnet on a Class C Network with 32 nets each with 8 IP's (1 for Net ,  1 for BCAST and 6 for Hosts). If you get some real IP's from your ISP
it's likely to get only a part of a Class C Network.

(Solaris) /etc/netmasks
a.b.c.0        a.b.c.248

2.3 NAT

The example shows how to map outgoing requests from the internal Network ( to the global (dynamic) IP assigned to the PPP Interface. The 0/32 references whatever IP is actually assigned at that moment. The first line sets up the FTP-Proxy, so that ftp works for inside hosts. Ipfilter takes special care to this connections, allowing the server to build the data channel.  The 2nd line gives a range for remapping tcp and udp connections. Outgoing Packets from inside are rewritten with the external IP of the Firewall and Portnumbers are remapped since this may collide with existing connections on the Firewall. The last line sets the actual translation. The configuration should be in that order or it may not work.

           # NAT Rules
            map ipdptp0 -> 0/32 proxy port 21 ftp/tcp
            map ipdptp0 -> 0/32 portmap tcp/udp 40000:42999
            map ipdptp0 -> 0/32

            # example for redir rule
            # redirect to  internal smtp server
            # rdr global_ip/32 port 25 -> port 25

* the internal Net is
* the IP bound to ipdptp0 is refernced with  0/32 (subsitute the actual IP of ipdptp0)

With dynamic IP's the process of looking up the actual IP has to be triggered manualy. Simply run ipf -y from a script if a new Session was established.
WITH PPPOE the MTU size has to be changed to 1412/1450 !

Internal Clients have to be configured this way to make this NAT Configuration work :

Note : Ipfilter has some other NAT features that allows 1x1 mappings and asigments of ADR-blocks.

2.4 Filter Rules

The following rules are minimal and should be seen as a starting point. It assumes a simple  PPP  Scenario were users from inside do anything they want and nothing gets through from the outside, except packets that are replies from requests generates from the inside LAN. It begins with spoofing rules to block packets that normally can't come from the external Network (unroutable ADR's). Then we block fragments because mostly advanced scanning technics and exploit stuff comes this way. Next is to block Source Routing . The ICMP Block allows PING to work (debugging).  The next block allows internal connects from inside for tcp/udp and icmp. In any case ipfilter keeps track of the session and lets packets related to inside sessions pass through.
# Firewall Rules
#  loopback
pass in on lo0 all
# spoofing
block in log quick on ipdptp0 from to any
block in log quick on ipdptp0 from to any
block in log quick on ipdptp0 from to any
block in log quick on ipdptp0 from to any
block in log quick on ipdptp0 from to any
# short + frag
block in quick on ipdptp0 all with short
block in quick on ipdptp0 all with frags
# source routing + strict source routing
block in quick on ipdptp0 all with opt lsrr
block in quick on ipdptp0 all with opt ssrr
# icmp - XXXX%)
pass in log quick on ipdptp0 proto icmp from any to any icmp-type echo
pass in log quick on ipdptp0 proto icmp from any to any icmp-type echorep
pass in log quick on ipdptp0 proto icmp from any to any icmp-type timex
# allow all outbound traffic and keep state on this
pass out quick on iptpdp0  proto tcp from 192.168.10/0/24 to any keep state
pass out quick on ipdptp0  proto udp from  to any keep state
pass out quick on ipdptp0 proto icmp from  to any keep state

             # no connects from outside are allowed
             block in log on ipdptp0 all
# allow forwarding - in rc2.d
ndd -set /dev/tcp ip_forwarding 1
# refresh IP
/sbin/ipf -y
# reload rules
ipf -FSa
ipf -f /etc/opt/ipf/ipf.conf
ipnat -CF /etc/opt/ipnat.conf

2.5 Cache Only Name Server

To speed up DNS lookups is nice to use a cache only server. This is configured in a matter of minutes on any UNIX System.

2.5.1 Solaris with BIND 8 (fictional Domain warpnet.com)

options {
        directory "/var/named";
zone "0.0.127.in-addr.arpa" in {
        type master;
        file "db.127.0.0";
zone "." in {
        type hint;
        file "db.cache";


@ IN SOA dragon.warpnet.com. dummy.warpnet.com. (
        1 ;
        86400 );
        IN NS dragon.warpnet.com.
1 IN PTR localhost

db.cache  ftp://rs.internic.de/domain/named.root

2.5.2 Solaris with BIND 4

directory       /var/named
cache     .                                                     db.cache
primary   0.0.127.IN-ADDR.ARPA  db.127.0.0

Note : OpenBSD 2.x uses a change rooted environment were the impact of BIND exploits is limited. This technique can also be applied with any other UNIX.


;       @(#)localhost.rev       5.1 (Berkeley) 6/30/90

@       IN      SOA     dragon.warpnet.com. rwh.dragon.warpnet.com.  (
                                14      ; Serial
                                3600    ; Refresh
                                900     ; Retry
                                3600000 ; Expire
                                3600 )  ; Minimum
        IN      NS      dragon.warpnet.com.
1       IN      PTR     localhost.warpnet.com.

db.cache  ftp://rs.internic.de/domain/named.root

2.6 IDS

Some additional security can be obtained by using IDS Systems. IDS Systems monitor all communication and look for patterns that are typical for some sort of attack or scan.  Some systems even respond to attack patterns with simply shutting down the connection with an RST to the Source (works for TCP ).

Note:  Not so advanced or bad configured IDS may trigger a huge amount of False Positives and flood your logs with useless crap. Logging to the firewall can be dangerous in such a situation (FS full ..).

        Snort is a lightweight IDS with realtime analysis capabilities. It has a Database with a huge amount of exploit patterns.
        New Patterns can be downloaded at :www.whiteheads.com .

2.6.2 Scanlogd

Scanlogd doesn't compile cleanly on Solaris (libnids 244,249,250). Some struct Members (udp.h) have wrong names which has to be corrected. Scanlog is a nice tool to detect stealth scans from nmap and tools like this. Its very lightweight and simple to install.

2.7 Proxys

Using Proxy's is a good way to shield the internal net from the outside and controll access the the internet. Another advantage is caching frequently used pages on a local system (proxy cache).

2.7.1 Squid

Transparent Proxy Support. This has to be set in squid.conf Ipfilter (ipnat.conf) :  rdr de0 port 80 -> port 3128 tcp
Linux (iptables) : iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

see squid configuration (out dated) Link.

2.7.2 FWTK

FWTK has a bunch of Application Level Proxy's and a auth service. Popular protocols like pop3,http, ftp, telnet, nntp are supported. Generic TCP Proxy also available.

3.0 Test your Installation

Its wise to read the Manpages, FAQ and other Documents around before trying to build a firewall System. Getting all things right at the first try isn't that easy. The following lists some useful debugging tools :

 3.1 IPFilter Links

IPfilter Homepage http://cheops.anu.edu.au/~avalon/ip-filter.html
IPfilter on FreeBSD  http://www.freebsddiary.org/ipfilter.html 

Ipfilter is Part of FreeBSD, OpenBSD and NetBSD.

IPfilter on OpenBSD http://www.openBSD.org
IPFilter FAQs & Tutorials http://www.obfuscation.org/ipf/ipf-howto.txt 
IPFilter based Products http://www.netsec.net