File:  [NetBSD Developer Wiki] / wikisrc / nsps.mdwn
Revision 1.2: download - view: text, annotated - select for diffs
Sat May 25 21:37:03 2013 UTC (10 months, 3 weeks ago) by jdf
Branches: MAIN
CVS tags: HEAD
Semantical cosmetics.

# NetBSD Security Processes and Services

This document covers secure processes and services for NetBSD Operating
Systems and Networks. Most of the information in this document can
easily be translated to other BSD systems, however.

# Overview

## Setup Example

Simply writing this document without some sort of consistent example
would be quite difficult, so for the sake of easy discussion, the
following is what we want to accomplish:

    Internal Network                 clients, hosts, internal servers
                                              172.16.0.0
                                                  
                                                  |
                                                  |

    NetBSD Firewall                        fxp0 172.16.14.1
    Server with SSH Open                  ------------------
                                           ep0 216.68.250.60
                                                   
                                                  |
                                                  |
                                                   
    Internet Connection                     gateway switch/
    Provider Network                          router
                                            216.68.250.65
                                                   
                                                  |
                                                  |
                                                   
    Big Bad Internet                         insert cloud here

This is a pretty common setup for many organizations, to be connected
via a service providers network out onto the internet.

The purpose of this firewall is to allow the clients on the 172.16.0.0
network to interact with the internet.

## The Desired Setup of the Firewall

In a nutshell we want the firewall to be able to pass certain traffic in
and out, however, we only want one available service *at* the firewall
itself, that service is Secure Shell. Following is a matrix of how this
particular installation is to look:
<table>
	<tr>
    	<th>Service</th>
		<th>Connect to Firewall</th>
		<th>Pass In</th>
		<th>Pass Out</th>
	</tr>
	<tr>
		<th>DNS</th>
		<td>NO</td>
		<td>YES</td>
		<td>YES</td>
	</tr>
	<tr>
		<th>SMTP</th>
		<td>NO</td>
		<td>YES</td>
		<td>YES</td>
	</tr>
	<tr>
		<th>HTTP</th>
		<td>NO</td>
		<td>YES</td>
		<td>YES</td>
	</tr>
	<tr>
		<th>FTP</th>
		<td>NO</td>
		<td>YES</td>
		<td>YES</td>
	</tr>
	<tr>
		<th>SSH</th>
		<td>YES</td>
		<td>YES</td>
		<td>YES</td>
	</tr>
</table>

It is important to note here that we need to be able to pass DNS, SMTP,
FTP and HTTP traffic, however, we only really *want* the SSH service to
be able to establish a connection to the firewall. The reason noting
this now is important is because the rules in IPFILTER for making a
connection and passing traffic are nearly identical.


## More than one way to . . .

The setup used throughout this document is an example, there is
definitely more than one way to do this, for example:

    private network    firewall    DMZ with public    firewall  uplink
                                   web, ftp, etc.
                                   servers

The DMZ would have publicly accessible web servers, ftpd servers etc. In
our example, we do not require the DMZ since we are not hosting any web
servers or running a DNS server that will participate with the rest of
the internet.

# Configuring Secure Shell

NetBSD ships with a Secure Shell implementation based on OpenBSD's. The
default configuration of Secure Shell is done quite well, and there is
little an administrator needs to actually do in most cases. Turning on
the Secure Shell daemon is required, however. For posterity, we are
going to take a short look at configuring it.

## The Client Side Configuration File

The ssh client's configuration file is located in `/etc/ssh/ssh_config` and in
`~/.ssh/config` for single users.
The options contained in it are named intuitively and are rather verbose.
Documentation can be found in the ssh_config(5) manpage.

## The Server Configuration File

The server side of SSH is configured via `/etc/ssh/sshd_config`. The defaults
are set to high security levels by default. To enable the ssh server, put the
line `sshd=yes` into `/etc/rc.conf` and run

    /etc/rc.d/sshd restart

to start the server daemon and create any host keys if they are not already
present.

One item to take note of is that the server config does not allow X11 forwarding
by default, which of course on a firewall is a **good thing**. To enable it the
administrator must change the following lines:

    StrictModes no
    X11Forwarding yes

Again, there is little to nothing the administrator needs to do with the Secure
Shell setup unless they wish to alter the default config.

# Configuring IPFILTER

NetBSD ships with IPfilter as its default firewall and packet filtering
software.

## Understanding The ipf.conf File

The file that controls firewall rules for ipfilter is `/etc/ipf.conf` for IPv4
and `/etc/ipf6.conf` for IPv6. In this section we will go over the settings we
need and how I chose to implement them.

Basically, ipfilter operates on two basic principles:

 1. match the current line
 2. the last line supersedes previous ones

Following is a very rudimentary `ipf.conf` file:

    pass in on any all
    block in on any all

According to the first line, on any interface, all traffic may be
passed. On the second line, however, all traffic on any interface is
blocked.

## The Syntax

For the most part, ipfilter syntax is generally easy to follow, it is almost
natural. To pass in certain traffic, one says pass in, to pass out, pass out.
The interface can be specified or it can be all by saying something like:

    pass out on all . . .

If one wanted to specify the interface:

    pass out on ep0 . . .

So far so good, now lets look at the configuration we need for our firewall,
first we already know we want SSH traffic to be able to pass and connect:

    # sshd in from any
    pass in quick on ep0 proto tcp from any to 216.68.250.60/32 port = 22 keep state

You have probably already noticed some very new syntax here, let us take a look
at that now before we go any further.

### The quick Keyword

The `quick` keyword overrides any previous settings. It is most convenient when
large and complex firewalls are built with up to 100 rules in them. In our case
it is not so, however, we are including to be absolutely sure that the rule will
be processed.

### The proto Keyword

The `proto` keyword dictates, you guessed it, the protocol. In the case of
this firewall the protocol is always TCP.

### The port Keyword


The `port` keyword can be either the port number or the name as defined in
`/etc/services`, for posterity I have mixed and matched in this file.

### The keep state Keyword

The `keep state` keywords ensure packet checking from end to end within
the firewall and here is why, if you look closely at all of the rules,
they all use the `quick` keyword, so they circumvent previous rules and
hence checking on both sides of the firewall *may* not take place.

## Example Entries

Now lets look at the rest of the file in sections since we have a
slightly better idea of what we are looking at.

### Blocking Reserved & Local Machine Addresses


There are certain address classes we already know should not pass at all
through our firewall. The addresses are those specified as internal only
addresses and the localhost address (not the interface addresses):

 * 127.0.0.0/8 (the localhost)
 * 192.168.0.0/16 (reserved for internal networks, see
   [RFC 1918](tools.ietf.org/html/rfc1918))
 * 172.16.0.0/12 (reserved for internal networks, see RFC 1918)
 * 10.0.0.0/8 (reserved for internal networks, see RFC 1918)
 * 169.254.0.0/16 (IANA use)
 * 192.0.2.0/24 (netblock for documentation authors)
 * 204.152.64.0/23 (Sun Microsystems cluster interconnects)
 * 224.0.0.0/3 (class D and E multicasts)

It is important to note here that on one interface, fxp0, we want to be
able to pass in and out on the 172.16.0.0 network (since our internal
network is 172.16..0.0). To do this we can use the following rules:

    block in quick on any from 192.168.0.0/16 to any
    block in quick on any from 10.0.0.0/8 to any
    block in quick on any from 127.0.0.0/8 to any
    block in quick on any from 0.0.0.0/8 to any
    block in quick on any from 169.254.0.0/16 to any
    block in quick on any from 192.0.2.0/24 to any
    block in quick on any from 204.152.64.0/23 to any
    block in quick on any from 224.0.0.0/3 to any

In this table you will notice the 172.16.0.0/12 is omitted (even though
it should be blocked at least on ep0), you will see why in the next part
of the file.

### Paranoia Block

Next we will cut off all traffic to ep0, hence we do not need to explicitly
close off 172.16.0.0 from it.

    # block all
    block in quick on ep0 all

### Make the Firewall Act like an Internet Client

Next we want to make the firewall have the capability of acting like an internet
client, this is pretty simple:

    # pass out as if we were a single internet client
    pass out quick on ep0 proto tcp from 216.68.250.60/32 to any keep state
    pass out quick on ep0 proto udp from 216.68.250.60/32 to any keep state
    pass out quick on ep0 proto icmp from 216.68.250.60/32 to any keep state

### Passing the Rest

Now we ant to add all of the protocols we want to pass. It should be important
to note that if you have any of these services enabled **on the firewall** then
their port will be accessible **on the firewall**.
It is usually a safer bet *not to have anything but ssh, ipfilter and ipnat
running on it*, the exception this might be (as in my home setup) you simply do
not have the hardware to spare and must have DNS and/or other server processes
running on it as well.

    # dns stuff
    pass in log proto tcp from any to any port = 53 keep state
    pass in log proto udp from any to any port = 53 keep state

    # pass thru www and ftp
    pass in log proto tcp from any to any port = www keep state
    pass in proto tcp from any to any port = ftp keep state
    pass in proto tcp from any to any port = ftp-data keep state
    pass in proto tcp from any port = ftp-data to any port > 1023 keep state
    pass in log proto icmp all keep state

## IP Filter for Dial Ups

Dial up connections offer somewhat of a challenge for ipfilter in that most dial
up interfaces are assigned a different IP address each time the user makes the
connection.

In dial up or any dynamic address situation, the rules must be written in a
slightly less secure manner. In other words, rules cannot use the internet side
IP address, however, even just using the interface is normally enough to
guarantee pretty good security. As an example, here is one of the rules that
uses an IP address:

    # pass out as if we were a single internet client
    pass out quick on ep0 proto tcp from 216.68.250.60/32 to any keep state
    pass out quick on ep0 proto udp from 216.68.250.60/32 to any keep state
    pass out quick on ep0 proto icmp from 216.68.250.60/32 to any keep state

For our dial up connection we will have to change the ruleset to this:

    # pass out as if we were a single internet client
    pass out quick on ep0 proto tcp from any to any keep state
    pass out quick on ep0 proto udp from any to any keep state
    pass out quick on ep0 proto icmp from any to any keep state

Now what good does this do us now? Well, first, any ports that are still blocked
are *still* inaccessible. Second, if a service is not turned on and no inbound
proxying is enabled, all of this traffic is just passing through. There is no
way for anyone to connect to the firewall except via ssh.

# Configuring IPNAT

Network Address Translation (NAT) is part of IPfilter, which comes by default
with the NetBSD release. The job of NAT is to take a source IP address and
translate it to another out a different network interface. This is also known
as masquerading.

Luckily for you (as the exhausted reader) and I (the exhausted author)
configuring NAT is pretty simple, especially with the example we are using.

## What our /etc/ipnat.conf needs to look like

It is very simple:

    map ep0 172.16.0.0/16 -> 216.68.250.60/32 proxy port ftp ftp/tcp
    map ep0 172.16.0.0/16 -> 216.68.250.60/32 portmap tcp/udp 10000:20000
    map ep0 172.16.0.0/16 -> 216.68.250.60/32

First we are proxying ftp thru the ep0 interface. The next line says go ahead
and map all tcp/udp traffic right on through the interface and assign each out
bound "connection" a port from 10000 to 20000 and finally the last line says,
just plain map from 172.16.0.0/16 to 216.68.250.60/32. For our purposes this is
all we need so the rest of this document is of limited interest to those of you
in a crunch trying to get a firewall up.

## Other Nifty Stuff

A few items of interest for the curious, we can also map *into* the local
network as well:

    map fxp0 216.68.250.60/32 -> 172.16.14.1/32 (add whatever service here)

This might be handy to connect to a specific server inside (such as a web
server) or if you recall the DMZ example before, we may wish to translate *into*
the DMZ from the world. Additionally it can be used as a poor man's router to
link internal networks together - but there are much better was of doing that.

Instead of this, however, most administrators would locate the web server within
a DMZ and use ipfilter to ensure only http and ssh connections can be made to
the system.

If you look closely you will see all outbound connections map to a single IP 
address, what if you wanted to be able to map to more? You can do so by simply 
changing the single address to a network:

    map ep0 172.16.0.0/16 -> 216.68.250.0/24

Finally, the portmap range can be adjusted to whatever you feel is necessary.

## IPNAT With Dial Up Networking

Many home users use dial up connections to access the internet. Many dial up
connections are assigned a dynamic IP address every time the user connects. At
first glance it may appear that some method for putting this new address into
`/etc/ipnat.conf` is required. Luckily, that is not so. Take note of how
addresses can be shown on the internet side of the `ipnat.conf` file. Actually
entire subnets can be used like so:

    map ep0 172.16.0.0/16 -> 216.68.0.0/16

What this is saying is that addresses from 172.16.0.0 can be assigned any
address on 216.68.0.0's network. Keeping that in mind, on a dial up connection
you know you will be given one and one address, so the following entries
effectively do the same:

    map ppp0 172.16.0.0 -> 0/32 proxy port ftp ftp/tcp
    map ppp0 172.16.0.0 -> 0/32 portmap tcp/udp 40000:60000
    map ppp0 172.16.0.0 -> 0/32

Here we are saying map anything on 172.16.0.0 to one single address, the address
the interface will have.


# Activating Services

At this point, in theory, we are ready to start everything up. All of the
services we will need running are:

 * ipfilter
 * ipnat
 * ipmon
 * sshd

Additionally, we need to make sure that ip forwarding is enabled in the kernel.

## Turning on IP Forwarding

To turn on IP forwarding use the sysctl facility:

    sysctl -w net.inet.ip.forwarding=1

To have it turned on at bootup append the following text to `/etc/sysctl.conf`:

    net.inet.ip.forwarding=1

## /etc/defaults/rc.conf and /etc/rc.conf

NetBSD's default rc settings are all kept in `/etc/defaults/rc.conf`. To make
upgrades safer, override settings in `/etc/rc.conf` instead of
`/etc/defaults/rc.conf`.

### What we need in /etc/rc.conf

Basically, we can yank the contents of `/etc/defaults/rc.conf` and drop them
right into `/etc/rc.conf`:

    # cat /etc/defaults/rc.conf >>/etc/rc.conf
    # vi /etc/rc.conf

Note the double `>` here to avoid overwriting the contents of `/etc/rc.conf` as
shipped! Here is what `/etc/rc.conf` would look like after editing:
    #
    # see rc.conf(5) for more information.
    #
    # Use program=YES to enable program, NO to disable it. program_flags are
    # passed to the program on the command line.
    #

    # Load the defaults in from /etc/defaults/rc.conf (if it's readable).
    # These can be overridden below.
    #
    if [ -r /etc/defaults/rc.conf ]; then
            . /etc/defaults/rc.conf
    fi

    # If this is not set to YES, the system will drop into single-user mode.
    #
    rc_configured=YES

    # Add local overrides below
    #
    ipfilter=YES
    ipnat=YES
    ipmon=YES   ipmon_flags="-sn"
    sshd=YES

On i386 (PC) systems you will also see the wscons framework enabled:

    wscons=YES

## Activating the Services

Next we have to activate the services, we can do this one of two ways:

 1. reboot the system
 2. start using the rc scripts by hand

I prefer doing the latter first just to make sure everything is setup right,
then I do a reboot to make sure all of the services will start up properly
during the bootup sequence.

### Starting Services "by hand"

To start any service it is quite simple:

    # /etc/rc.d/[service_name] start

Additionally, a service may be stopped:

    # /etc/rc.d/[service_name] stop

or restarted:

    # /etc/rc.d/[service_name] restart

So for this firewall, here is the order we need to start the services:

    # /etc/rc.d/sshd start
    # /etc/rc.d/ipfilter start
    # /etc/rc.d/ipnat start
    # /etc/rc.d/ipmon start

In reality, when sshd and ipmon start is arbitrary, however, ipfilter
must be enabled before ipnat.

# Additional Products

The NetBSD release comes ready to roll with a host of advanced networking
capabilities. However, an administrator may wish to use additional or
alternative software. This section looks at other software that can run on
NetBSD the administrator may find of interest.

## Portsentry

The portsentry utility is a great tool. In a nutshell, portsentry
watches your system for scans and connection attempts and then will take
action to block a possible attacker. The main weakness portsentry has is
that it takes one connection attempt for portsentry to determine that
the host attempting to connect is hostile, so, if the first attempt is
successful, you are still out of luck.

### Getting Portsentry

Portsentry can be retrieved and installed using the
[pkgsrc](http://www.NetBSD.org/docs/software/packages.html) system:

    # cd /usr/pkgsrc/security/portsentry
    # make && make install

or using binary packages with pkgin:

    # pkgin install portsentry

### Configuring Portsentry

On NetBSD, portsentry is configured in `/usr/pkg/etc/portsentry.conf`.

### Port Configurations

In the configuration file there are three sets of ports shown, of these, one for
tcp and one for udp must be selected by uncommenting the line, the default is to
use the "middle" sets, they should look something like this:

    # Un-comment these if you are really anal:
    TCP_PORTS="1,7,9,11,15,70,79,80,109,110,111,119,138,139,143,512,513,514,515,540,
    635,1080,1524,2000,2001,4000,4001,5742,6000,6001,6667,12345,12346,20034,30303,32
    771,32772,32773,32774,31337,40421,40425,49724,54320"
    #UDP_PORTS="1,7,9,66,67,68,69,111,137,138,161,162,474,513,517,518,635,640,641,66
    6,700,2049,32770,32771,32772,32773,32774,31337,54321"
    #
    # Use these if you just want to be aware:
    #TCP_PORTS="1,11,15,79,111,119,143,540,635,1080,1524,2000,5742,6667,12345,12346,
    20034,31337,32771,32772,32773,32774,40421,49724,54320"
    UDP_PORTS="1,7,9,69,161,162,513,635,640,641,700,32770,32771,32772,32773,32774,31
    337,54321"
    #
    # Use these for just bare-bones
    #TCP_PORTS="1,11,15,110,111,143,540,635,1080,524,2000,12345,12346,20034,32771,32
    772,32773,32774,49724,54320"
    #UDP_PORTS="1,7,9,69,161,162,513,640,700,32770,32771,32772,32773,32774,31337,543
    21"

#### Advanced Stealth Detection

The number of ports portsentry should monitor in advanced mode, all of the ports
below the listed number(s) are monitored this way:

    ADVANCED_PORTS_TCP="1023"
    ADVANCED_PORTS_UDP="1023"

Additionally in this section portsentry can be told certain items to exclude
(such as loud NetBIOS services):

    # Default TCP ident and NetBIOS service
    ADVANCED_EXCLUDE_TCP="113,139"
    # Default UDP route (RIP), NetBIOS, bootp broadcasts.
    ADVANCED_EXCLUDE_UDP="520,138,137,67"

#### Configuration Files

Where files live, on NetBSD this is under `/usr/pkg/*`:

    # Hosts to ignore
    IGNORE_FILE="/usr/pkg/etc/portsentry.ignore"
    # Hosts that have been denied (running history)
    HISTORY_FILE="/usr/pkg/etc/portsentry.history"
    # Hosts that have been denied this session only (temporary until next restart)
    BLOCKED_FILE="/usr/pkg/etc/portsentry.blocked"

#### Response Options

This section is pretty straightforward just as it says in the file:

    # 0 = Do not block UDP/TCP scans.
    # 1 = Block UDP/TCP scans.
    # 2 = Run external command only (KILL_RUN_CMD)

    BLOCK_UDP="1"
    BLOCK_TCP="1"

#### Dropping Routes

This is the kill route option, the one used for NetBSD is already uncommented:

    # Generic BSD (BSDI, OpenBSD, NetBSD, FreeBSD)
    KILL_ROUTE="/sbin/route add $TARGET$ 333.444.555.666"

It should be noted that some can actually modify firewall tables, for example,
the FreeBSD packetfilter option:

    # For those of you running FreeBSD (and compatible) you can
    # use their built in firewalling as well.
    #
    #KILL_ROUTE="/sbin/ipfw add 1 deny all from $TARGET$:255.255.255.255 to any"

If another type of firewall is being used on your system, it may be possible to
add in something like this to your portsentry configuration.

#### TCP Wrappers

This section is the text that gets put into `/etc/hosts.deny`.

    #
    KILL_HOSTS_DENY="ALL: $TARGET$"

#### External Commands

Here, any external command (or script etc.) may be called.

    #KILL_RUN_CMD="/some/path/here/script $TARGET$ $PORT$"

As an example, altering the firewall could be here as well.

#### Scan Trigger Value

This is the number of port connects that portsentry allows before an alarm goes
up, the default is 0, 1 is usually pretty safe as well (to keep down the false
alarms).

#### Port Banner

This is a message that can be sent back to the person who tripped portsentry,
unless they are using a very verbose tool it usually ends up in a logfile on
their system (on NetBSD it ends up in `/var/log/messages`.

    #PORT_BANNER="** UNAUTHORIZED ACCESS PROHIBITED *** YOUR CONNECTION ATTEMPT HAS
    BEEN LOGGED. GO AWAY."

## NMAP

The nmap utility is a portscanner. It can scan one host, a network or 
combinations therein. It is currently in the pkgsrc tree.

### Getting and Installing NMAP


Use [pkgsrc](http://www.NetBSD.org/docs/software/packages.html):

    # cd /usr/pkgsrc/net/nmap
    # make && make install

or, using binary packages with pkgin:

    # pkgin install nmap

### Using nmap

The [nmap](http://insecure.org/) utility has **a lot** of options, we will look 
at three examples:

 1. scanning one host
 2. scanning several hosts
 3. scanning a NetBSD firewall

#### Scanning One Host

For this example we will use a pretty insecure system on an internal network:

    # nmap -P0 172.16.14.12
    
    Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
    Interesting ports on marie.ipsosasi.net (172.16.14.12):
    (The 1504 ports scanned but not shown below are in state: closed)
    Port       State       Service
    7/tcp      open        echo                    
    9/tcp      open        discard                 
    13/tcp     open        daytime                 
    19/tcp     open        chargen                 
    21/tcp     open        ftp                     
    23/tcp     open        telnet                  
    37/tcp     open        time                    
    111/tcp    open        sunrpc                  
    . . .

#### Scanning A Network

Now let's look at a whole bunch of machines!

    % nmap -P0 172.16.14.0/24 > nmap.out

Whenever it is either done (which could be awhile) or interrupted/stopped take a
peek at the file where all of the information was dumped, following is a sample
from the network I scanned:

    Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
    All 1523 scanned ports on  (172.16.14.0) are: closed
    Interesting ports on somename.blah.net (172.16.14.1):
    (The 1521 ports scanned but not shown below are in state: filtered)
    Port       State       Service
    23/tcp     open        telnet                  
    68/tcp     closed      bootpc                  

    All 1523 scanned ports on somename.blah.net (172.16.14.2) are: closed
    Interesting ports on somename.blah.net (172.16.14.3):
    (The 1520 ports scanned but not shown below are in state: closed)
    Port       State       Service
    23/tcp     open        telnet                  
    79/tcp     open        finger                  
    80/tcp     open        http                    

    Interesting ports on somename.blah.net (172.16.14.4):
    (The 1513 ports scanned but not shown below are in state: closed)
    Port       State       Service
    7/tcp      open        echo                    
    9/tcp      open        discard                 
    19/tcp     open        chargen                 
    . . .

#### Scanning a NetBSD Firewall

Last but definitely not least, lets nail a firewall:

    Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )

    Interesting ports on  (216.68.250.60):
    (The 1522 ports scanned but not shown below are in state: filtered)
    Port       State       Service
    22/tcp     open        ssh                     

    Nmap run completed -- 1 IP address (1 host up) scanned in 772 seconds

Now that is more like it.


# Examples

 * [[ipf.conf|http://netbsd.org/docs/network/nsps/examples/ipf.conf]]
 * [[ipnat.conf|http://netbsd.org/docs/network/nsps/examples/ipnat.conf]]
 * [[rc.conf|http://netbsd.org/docs/network/nsps/examples/rc.conf]]
 * [[sysctl.conf|http://netbsd.org/docs/network/nsps/examples/sysctl.conf]]
 * [[portsentry.conf|http://netbsd.org/docs/network/nsps/examples/portsentry.conf]]

CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb