summaryrefslogtreecommitdiff
path: root/content/blog/openbsd-firewall-appliance-intro.md
blob: 622ded3c63f3cc48b78560d819cd6dde8893617f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
+++
title = "OpenBSD firewall applicance - Intro"
categories = [ "OpenBSD", "Security" ]
date = "2017-06-15T09:25:47+02:00"
thumbnail = "/images/blog/openbsd-firewall-appliance-intro/alix_rpi.jpg"

+++

## History

Since some time our company [Eurospider](https://www.eurospider.com)
was using home-grown firewalls based on OpenBSD. Our administrator
at this time (Mihai Barbos, https://github.com/mbarbos) decided to
use Portwell NAR-2054 hardware with 3 up to 5 ethernet ports
and run a customized OpenBSD on it.

Now the company firewall is a Soekris net6501 as the Portwell
firewalls started to become a little bit rusty. There is still
one Portwell left in use for a control network serving access
to remote management consoles of our servers.

Also at home I'm using this solution on an
[Alix 2D.13](https://pcengines.ch/alix.htm) with 3
ethernet ports.

## Concepts

In theory you could just go with a default installation
and customize from there. A well-known security principle though
is to put the minimal amount of services onto a machine and add
only the things really needed to do the job.

Another solution would have been to go with an appliance like
[PfSense](https://www.pfsense.org), but they always provide 
some user interface (written in Lua, Php, etc.).
Web technology is not really in the base of OpenBSD, only
in the ports, so this could open a security threat.

A good security feature is to work with read-only media. In the
case of the Alix and the Portwell this is a compact flash, in
case of the Soekris a mini-USB-dongle. This prevents wearout and
more importantly, no processes can write onto the system (but
for a mfs (memory file system) for the /tmp directory.

Instead of a clicky-clicky web interface which generates a
big unreadable set of configuration files (for instance
firewall rules), I personally prefer a text editor and simple
rules. Again, complexity in a firewall setup is a no-go, the
less complex it is, the more likely you understand all rules
you put in there. And understanding what you are doing is the
key to a secure system.

So, we start from a build-machine running a standard OpenBSD.
From there a build script (build.sh) creates a virtual filesystem
(vnode disks, vnconfig, the Linux world would use loopback devices).
This image is then transfered with 'dd' to the real media (compact
flash or USB stick).

The early scripts are based on scripts from Chris Cappuccio,
sadly I was not able to find the original webpage anymore.

## Customization

The build.sh script takes a directory called 'template'. This
directory contains files which are copied as is to the image.
Usually this directory needs synching with the host system every
time you upgrade OpenBSD.

All binaries and required libraries are fetched from the
host system runing OpenBSD.

The directory 'config' contains files per appliance you want
to build.

Basic network connectivity is configured in the following files:

```
  rc.net
  dhclient.conf
  hosts
  networks
  rc.net
```

The 'rc.net' file is a snippet which gets added to the boot
script '/etc/rc'. There you set up the network directly with
OpenBSD commands like:

```
  dhclient vr0
  ifconfig bridge0 create
  ifconfig bridge0 add vr1
  ifconfig bridge0 add vr2 
  route add -net 192.168.1.0/24 192.168.1.1
```

The firewall lives in one file 'pf.conf' and contains the
standard OpenBSD firewall rules:

```
# interfaces
ext_if = vr0
...
match out on $ext_if from <intNetworks> nat-to ($ext_if)
...
pass in quick on $ext_if proto udp from port 67 to port 68
...
```

The other snippet which gets added to '/etc/rc' is
'rc.services'. There you start all services you want to
run on the machine:

```
echo unbound: starting DNS resolver..
cp -R /etc/unbound /tmp/var/unbound
/usr/sbin/unbound
```

You also put all required files for each service into that directory. For instance:

* for DHCP: dhcpd.conf

```
shared-network LAN {
  ...

  subnet 192.168.1.0 netmask 255.255.255.0 {
    option routers 192.168.1.1;
    range 192.168.1.128 192.168.1.249;
  }
```

* for NTP: ntpd.conf

```
servers pool.ntp.org
listen on 127.0.0.1
listen on 192.168.1.1
```

* for DNS resolving and caching (unbound subdir with unbound.conf)

* for DNS server you need a need one configuration directory per
  view (for a split-horizon setup):

```
nsd-external/
nsd-external/run
nsd-external/run/xfr
nsd-external/run/xfr/.gitkeep
nsd-external/zones
nsd-external/zones/myzone
nsd-external/zones/somebodyelseszone
nsd-external/etc
nsd-external/etc/nsd.conf
```

(this I will cover in another article, as it is a little bit more
tricky to set up). 

* Relaying traffic with relayd, relayd.conf:

```
...
http protocol "http_protocol" {
	...
	match request quick header "Host" value "www.mydomain.com" \
                forward to <someinternalserver> no tag
}
...
```

Finally you create a file with the CHS parameters of your media
(yes, this is needed for bootloading on OpenBSD) in a file
called 'hardware/myfirewall/flash_params':

```
BYTES_PER_SECTOR=512
SECTORS_PER_TRACK=32
TRACKS_PER_CYLINDER=16
SECTORES_PER_CYLINDER=512
CYLINDERS=978
OFFSET=32
```

To create the image you simple call:

```
./build.sh [your config profile] [flash_params profile]
```

## Future

I'm trying to keep up with new versions of OpenBSD.

I would like to test more things around the following topics:

- monitoring of firewall data (pflogd), sensor logging, remote syslog
- play with redundancy (CARP)
- automatic acme and relayd certificate renewal for HTTPS relaying
- in-situ updates: currently I have to open the device, remove the flash,
  stuff it into a floppy to compact flash adapter, write the image, put
  it back. This is tedious. :-)

## Github

The whole project can be found on Github:

http://github.com/andreasbaumann/OpenBSD-firewall

Feedback welcome. :-)