OpenBSD 3.5 on an OpenBrick-E
How to securely build, using local resources, a transparent bridging firewall using an Openbrick-E and OpenBSD 3.5. Using a 533MHz Via processor with 256MB of memory and a 512MB Compact Flash card, our OpenBrick has no moving parts. With 3 10/100 interfaces, that leaves one leftover for CARP!
**Note: these instructions have been clarified and updated for an OpenBSD 4.0 install . This page is retained for archival purposes.**
First, here's a picture:
These directions are modified from the Netikus documents (Guides section), updated for 3.5 plus fixes for /DEV, /var/db, and read-only /
You will need a USB floppy and boot floppy, or USB CD-ROM drive and the OpenBSD 3.5 CD. Here I'll show the floppy method, since it's trickier.
Create a boot floppy for OpenBSD Install
On a Windows system:
Download ftp://openbsd.engr.ucdavis.edu/3.5/tools/ntrw.exe
Download ftp://openbsd.engr.ucdavis.edu/3.5/i386/floppy35.fs for IDE install, floppyB35.fs for SCSI install and floppyC35.fs for laptop install.
Insert a blank floppy and from the command prompt type ntrw floppy35.fs a:, e.g:
H:\OpenBSD>ntrw floppy35.fs a: 3.5", 1.44MB, 512 bytes/sector bufsize is 9216 1474560 bytes written H:\OpenBSD>
Substitute floppyB35.fs or floppyC35.fs if using SCSI or a laptop.
If you're running an OpenBrick and you want to upgrade, I suggest just pulling the flash card out and installing on a brand new one.
You can just swap if things go south, and you now have a "hot spare".
I'm going to redirect output to a serial console using 'set tty com0'; read the FAQ for more on serial consoles:
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
Copyright (c) 1995-2004 OpenBSD. All rights reserved. http://www.OpenBSD.org
OpenBSD 3.5 (RAMDISK) #161: Mon Mar 29 12:53:24 MST 2004
deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/RAMDISK
cpu0: VIA Samuel 2 ("CentaurHauls" 686-class) 533 MHz
cpu0: FPU,DE,TSC,MSR,MTRR,PGE,MMX
real mem = 265863168 (259632K)
avail mem = 242614272 (236928K)
using 3271 buffers containing 13398016 bytes (13084K) of memory
mainbus0 (root)
bios0 at mainbus0: AT/286+(4b) BIOS, date 02/24/03, BIOS32 rev. 0
@0xfb500
apm0 at bios0: Power Management spec V1.2
pcibios0 at bios0: rev. 2.1 @ 0xf0000/0xded4
pcibios0: PCI IRQ Routing Table rev. 1.0 @ 0xfde40/144 (7 entries)
pcibios0: PCI Exclusive IRQs: 10 11 12
pcibios0: PCI Interrupt Router at 000:07:0 ("VIA VT82C596A ISA" rev 0x00)
pcibios0: PCI bus #1 is the last bus
bios0: ROM list: 0xc0000/0xc000 0xcc000/0x4000! 0xd0000/0xa800
pci0 at mainbus0 bus 0: configuration mode 1 (no bios)
pchb0 at pci0 dev 0 function 0 "VIA VT8601 PCI" rev 0x05
ppb0 at pci0 dev 1 function 0 "VIA VT82C601 AGP" rev 0x00
pci1 at ppb0 bus 1
vga1 at pci1 dev 0 function 0 "Trident CyberBlade i1" rev 0x6a
wsdisplay0 at vga1: console (80x25, vt100 emulation)
pcib0 at pci0 dev 7 function 0 "VIA VT
pciide0 at pci0 dev 7 function 1 "VIA VT82C571 IDE" rev 0x06: ATA100,
channel 0
configured to compatibility, channel 1 configured to compatibility
pciide0: channel 0 disabled (no drives)
wd0 at pciide0 channel 1 drive 0: <SanDisk SDCFB-512>
wd0: 1-sector PIO, LBA, 488MB, 1000944 sectors
wd0(pciide0:1:0): using PIO mode 4
"VIA VT83C572 USB" rev 0x1a at pci0 dev 7 function 2 not configured
"VIA VT83C572 USB" rev 0x1a at pci0 dev 7 function 3 not configured
"VIA VT82C686 SMBus" rev 0x40 at pci0 dev 7 function 4 not configured
rl0 at pci0 dev 8 function 0 "Realtek 8139" rev 0x10: irq 12
address 00:40:f4:8a:0c:f8
rlphy0 at rl0 phy 0: RTL internal phy
rl1 at pci0 dev 9 function 0 "Realtek 8139" rev 0x10: irq 10
address 00:40:f4:8a:0c:f7
rlphy1 at rl1 phy 0: RTL internal phy
rl2 at pci0 dev 11 function 0 "Realtek 8139" rev 0x10: irq 11
address 00:40:f4:8a:0c:f6
rlphy2 at rl2 phy 0: RTL internal phy
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
npx0 at isa0 port 0xf0/16: using exception 16
pccom0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
pccom0: console
pccom1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
biomask 8040 netmask 9c40 ttymask 9c42
rd0: fixed, 3560 blocks
wd0: no disk label
root on rd0a
rootdev=0x1100 rrootdev=0x2f00 rawdev=0x2f02
erase ^?, werase ^W, kill ^U, intr ^C, status ^T
(I)nstall, (U)pgrade or (S)hell? i
Welcome to the OpenBSD/i386 3.5 install program.
This program will help you install OpenBSD in a simple and rational way. At
any prompt except password prompts you can run a shell command by typing
'!foo', or escape to a shell by typing '!'. Default answers are shown in []'s
and are selected by pressing RETURN. At any time you can exit this program by
pressing Control-C and then RETURN, but quitting during an install can leave
your system in an inconsistent state.
Terminal type? [vt220]
Do you wish to select a keyboard encoding table? [no]
IS YOUR DATA BACKED UP? As with anything that modifies disk contents, this
program can cause SIGNIFICANT data loss.
It is often helpful to have the installation notes handy. For complex disk
configurations, relevant disk hardware manuals and a calculator are useful.
Proceed with install? [no] yes
Cool! Let's get to it...
You will now initialize the disk(s) that OpenBSD will use. To enable all
available security features you should configure the disk(s) to allow the
creation of separate filesystems for /, /tmp, /var, /usr, and /home.
Available disks are: wd0.
Which one is the root disk? (or 'done') [wd0]
Do you want to use *all* of wd0 for OpenBSD? [no] yes
Putting all of wd0 into an active OpenBSD MBR partition (type 'A:6')
... no disk label
done.
You will now create an OpenBSD disklabel inside the OpenBSD MBR
partition. The disklabel defines how OpenBSD splits up the MBR partition
into OpenBSD partitions in which filesystems and swap space are created.
The offsets used in the disklabel are ABSOLUTE, i.e. relative to
the start of the disk, NOT the start of the OpenBSD MBR partition.
# using MBR partition 3: type A6 off 63 (0x3f) size 1000881 (0xf45b1)
Treating sectors 63-1000944 as the OpenBSD portion of the disk.
You can use the 'b' command to change this.
Initial label editor (enter '?' for help at any prompt)
> p
device: /dev/rwd0c
type: ESDI
disk: ESDI/IDE disk
label: SanDisk SDCFB-51
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 993
total sectors: 1000944
free sectors: 1000881
rpm:
16 partitions:
# size offset fstype [fsize bsize cpg]
a: 1000881 63 unused 0 0
c: 1000944 0 unused 0 0
> d a
> a a
offset: [63]
size: [1000881] 65M
Rounding to nearest cylinder: 132993
FS type: [4.2BSD]
mount point: [none] /
> a b
offset: [133056]
size: [867888] 1M
Rounding to nearest cylinder: 2016
FS type: [swap]
> a d
offset: [135072]
size: [865872] 65M
Rounding to nearest cylinder: 133056
FS type: [4.2BSD]
mount point: [none] /var
> a e
offset: [268128]
size: [732816]
FS type: [4.2BSD]
mount point: [none] /usr
> p
device: /dev/rwd0c
type: ESDI
disk: ESDI/IDE disk
label: SanDisk SDCFB-51
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 993
total sectors: 1000944
free sectors: 0
rpm: 3600
16 partitions:
# size offset fstype [fsize bsize cpg]
a: 132993 63 4.2BSD 2048 16384 16 # /
b: 2016 133056 swap
c: 1000944 0 unused 0 0
d: 133056 135072 4.2BSD 2048 16384 16 # /var
e: 732816 268128 4.2BSD 2048 16384 16 # /usr
> w
> q
No label changes.
The root filesystem will be mounted on wd0a.
wd0b will be used for swap space.
Mount point for wd0d (size=66528k)? (or 'none' or 'done') [/var]
Mount point for wd0e (size=366408k)? (or 'none' or 'done') [/usr]
Mount point for wd0d (size=66528k)? (or 'none' or 'done') [/var] done
No more disks to initialize.
You have configured the following partitions and mount points:
wd0a /
wd0d /var
wd0e /usr
The next step creates a filesystem on each partition, ERASING existing data.
Are you really sure that you're ready to proceed? [no] yes
/dev/rwd0a: 132992 sectors in 132 cylinders of 16 tracks, 63 sectors
64.9MB in 1 cyl groups (132 c/g, 64.97MB/g, 8320 i/g)
/dev/rwd0d: 133056 sectors in 132 cylinders of 16 tracks, 63 sectors
65.0MB in 1 cyl groups (132 c/g, 64.97MB/g, 8320 i/g)
/dev/rwd0e: 732816 sectors in 727 cylinders of 16 tracks, 63 sectors
357.8MB in 3 cyl groups (328 c/g, 161.44MB/g, 20608 i/g)
/dev/wd0a on /mnt type ffs (rw, asynchronous, local,
ctime=Mon Jun 7 20:53:06 2004)
/dev/wd0e on /mnt/usr type ffs (rw, asynchronous, local, nodev,
ctime=Mon Jun 7 20:53:07 2004)
/dev/wd0d on /mnt/var type ffs (rw, asynchronous, local, nodev,nosuid,
ctime=Mon Jun 7 20:53:07 2004)
System hostname? (short form, e.g. 'foo') openbrickwall
Configure the network? [yes]
Available interfaces are: rl0 rl1 rl2.
Which one do you wish to initialize? (or 'done') [rl0] rl1
Symbolic (host) name for rl1? [openbrickwall]
The default media for rl1 is
media: Ethernet autoselect (100baseTX full-duplex)
Do you want to change the default media? [no]
IP address for rl1? (or 'dhcp') www.xxx.yyy.zzz
Netmask? [255.255.255.0] 255.255.255.128
Available interfaces are: rl0 rl2.
Which one do you wish to initialize? (or 'done') [rl0] done
DNS domain name? (e.g. 'bar.com') [my.domain] ucdavis.edu
DNS nameserver? (IP address or 'none') [none] 169.237.250.250
Use the nameserver now? [yes]
Default route? (IP address, 'dhcp' or 'none') www.xxx.yyy.zzz
add net default: gateway www.xxx.yyy.zzz
Edit hosts with ed? [no]
Do you want to do any manual network configuration? [no]
Password for root account? (will not echo)
Password for root account? (again)
You will now specify the location and names of the install sets you want to
load. You will be able to repeat this step until all of your sets have been
successfully loaded. If you are not sure what sets to install, refer to the
installation notes for details on the contents of each.
Sets can be located on a (m)ounted filesystem; a (c)drom, (d)isk or (t)ape
device; or a (f)tp, (n)fs or (h)ttp server.
Where are the install sets? (or 'done') f
HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]
Display the list of known ftp servers? [yes] no
Server? (IP address, hostname or 'done') openbsd.engr.ucdavis.edu
Does the server support passive mode ftp? [yes]
Server directory? [pub/OpenBSD/3.5/i386] 3.5/i386
Login? [anonymous]
The following sets are available. Enter a filename, 'all' to select
all the sets, or 'done'. You may de-select a set by prepending a '-'
to its name.
[X] bsd
[ ] bsd.rd
[X] base35.tgz
[X] etc35.tgz
[X] misc35.tgz
[X] comp35.tgz
[X] man35.tgz
[X] game35.tgz
[ ] xbase35.tgz
[ ] xshare35.tgz
[ ] xfont35.tgz
[ ] xserv35.tgz
File name? (or 'done') [bsd.rd]
The following sets are available. Enter a filename, 'all' to select
all the sets, or 'done'. You may de-select a set by prepending a '-'
to its name.
[X] bsd
[X] bsd.rd
[X] base35.tgz
[X] etc35.tgz
[X] misc35.tgz
[X] comp35.tgz
[X] man35.tgz
[X] game35.tgz
[ ] xbase35.tgz
[ ] xshare35.tgz
[ ] xfont35.tgz
[ ] xserv35.tgz
File name? (or 'done') [xbase35.tgz] -g*
The following sets are available. Enter a filename, 'all' to select
all the sets, or 'done'. You may de-select a set by prepending a '-'
to its name.
[X] bsd
[X] bsd.rd
[X] base35.tgz
[X] etc35.tgz
[X] misc35.tgz
[X] comp35.tgz
[X] man35.tgz
[ ] game35.tgz
[ ] xbase35.tgz
[ ] xshare35.tgz
[ ] xfont35.tgz
[ ] xserv35.tgz
File name? (or 'done') [game35.tgz] done
Ready to install sets? [yes]
Getting bsd ...
100% |**************************************************| 4956 KB 00:06
Getting bsd.rd ...
100% |**************************************************| 4497 KB 00:05
Getting base35.tgz ...
100% |**************************************************| 30270 KB 01:24
Getting etc35.tgz ...
100% |**************************************************| 1603 KB 00:13
Getting misc35.tgz ...
100% |**************************************************| 2104 KB 00:09
Getting comp35.tgz ...
100% |**************************************************| 17358 KB 01:26
Getting man35.tgz ...
100% |**************************************************| 6516 KB 00:33
Sets can be located on a (m)ounted filesystem; a (c)drom, (d)isk or (t)ape
device; or a (f)tp, (n)fs or (h)ttp server.
Where are the install sets? (or 'done') done
Do you wish sshd(8) to be started by default? [yes]
Do you expect to run the X Window System? [yes] no
Saving configuration files...done.
Generating initial host.random file...done.
What timezone are you in? ('?' for list) [Canada/Mountain] US/Pacific
Setting local timezone to 'US/Pacific'...done.
Making all device nodes...done.
Installing boot block...
boot: /mnt/boot
proto: /usr/mdec/biosboot
device: /dev/rwd0c
/usr/mdec/biosboot: entry point 0
proto bootblock size 512
/mnt/boot is 3 blocks x 16384 bytes
fs block shift 2; part offset 63; inode block 120, offset 2984
using MBR partition 3: type 166 (0xa6) offset 63 (0x3f)
done.
CONGRATULATIONS! Your OpenBSD install has been successfully completed!
To boot the new system, enter halt at the command prompt. Once the
system has halted, reset the machine and boot from the disk.
# halt
syncing disks... done
The operating system has halted.
Please press any key to reboot.
rebooting...
Now detach your USB floppy/CD-ROM
First, let's get the firewall going. We have:
openbrickwall# ifconfig -a
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33224
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x6
rl0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
address: 00:40:f4:8a:0c:f8
media: Ethernet autoselect (100baseTX full-duplex)
status: active
rl1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
address: 00:40:f4:8a:0c:f7
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet www.xxx.yyy.zzz netmask 0xffffff80 broadcast www.xxx.yyy.zzz
inet6 fe80::240:f4ff:fe8a:cf7%rl1 prefixlen 64 scopeid 0x2
rl2: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
address: 00:40:f4:8a:0c:f6
media: Ethernet autoselect (100baseTX full-duplex)
status: active
pflog0: flags=0<> mtu 33224
pfsync0: flags=0<> mtu 2020
enc0: flags=0<> mtu 1536
We'll use rl1 as an admin interface and do bridging with rl0 and rl2:
openbrickwall# echo 'up' > /etc/hostname.rl0 openbrickwall# echo 'up' > /etc/hostname.rl2 openbrickwall# echo 'add rl0 add rl2 up' > /etc/bridgename.bridge0
We didn't have these files before, so there's nothing to save. We don't need to turn on forwarding, since this uses bridging instead.
Finally, turn on pf:
openbrickwall# vi /etc/rc.conf.local
Add line:
pf=YES # Packet filter / NAT
This overrides the setting in /etc/rc.conf, which you shouldn't edit directly. Now reboot, and watch the output:
openbrickwall# reboot now
Note:
pf enabled starting network starting system logger starting rpc daemons:. savecore: no core dump checking quotas: done. building ps databases: kvm dev. clearing /tmp starting pre-securelevel daemons:. setting kernel security level: kern.securelevel: 0 -> 1 creating runtime link editor directory cache. preserving editor files starting network daemons: sshd. starting local daemons:. standard daemons: cron. Mon Jun 7 15:29:35 PDT 2004
Let's check that bridging works:
openbrickwall# ifconfig -a
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33224
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x6
rl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
address: 00:40:f4:8a:0c:f8
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet6 fe80::240:f4ff:fe8a:cf8%rl0 prefixlen 64 scopeid 0x1
rl1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
address: 00:40:f4:8a:0c:f7
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet www.xxx.yyy.zzz netmask 0xffffff80 broadcast www.xxx.yyy.zzz
inet6 fe80::240:f4ff:fe8a:cf7%rl1 prefixlen 64 scopeid 0x2
rl2: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
address: 00:40:f4:8a:0c:f6
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet6 fe80::240:f4ff:fe8a:cf6%rl2 prefixlen 64 scopeid 0x3
pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33224
pfsync0: flags=0<> mtu 2020
enc0: flags=0<> mtu 1536
bridge0: flags=41<UP,RUNNING> mtu 1500
Yup. Now, I'm going to load in my previously-written pf.conf. Otherwise, just start with the default one and work from there:
openbrickwall# cp /etc/pf.conf /etc/pf.conf.old
Now I just load it via sftp. Since I use UltraEdit and leave it in UNIX format, it just works. Let's test:
openbrickwall# pfctl -n -f /etc/pf.conf openbrickwall# pfctl -f /etc/pf.conf
Voila! Internet connection restored! The firewall is now functioning.
I could stop here, but there's a few more things that should be taken care of.
First, if you want to do any firewall troubleshooting, you need pftop.
You can get it in the 3.5/packages directory on the OpenBSD 3.5 CD (which you should have bought).
I'm working with the OpenBrick, which still might have USB problems. So I'll retrieve it from our local, fast mirror:
openbrickwall# pkg_add -v ftp://openbsd.engr.ucdavis.edu/3.5/packages/i386/pftop-0.4.tgz Adding ftp://openbsd.engr.ucdavis.edu/3.5/packages/i386/pftop-0.4.tgz
Let's give it a spin:
openbrickwall# /usr/local/sbin/pftop <lot's of stuff displayed>
Okay, we should fix things up so we're not logging in as root all the time.
Also, the shell we're using is not very comfortable.
We'll fix both problems using sudo and ksh.
First, let's add a user:
openbrickwall# adduser Couldn't find /etc/adduser.conf: creating a new adduser configuration file Reading /etc/shells Enter your default shell: csh ksh nologin sh [sh]: ksh Your default shell is: ksh -> /bin/ksh Reading /etc/login.conf Default login class: auth-defaults auth-ftp-defaults daemon default staff [default]: Enter your default HOME partition: [/home]: Copy dotfiles from: /etc/skel no [/etc/skel]: Send message from file: /etc/adduser.message no [no]: Do not send message Prompt for passwords by default (y/n) [y]: Default encryption method for passwords: auto blowfish des md5 old [auto]: Use option ``-silent'' if you don't want to see all warnings and questions. Reading /etc/shells Reading /etc/login.conf Check /etc/master.passwd Check /etc/group Ok, let's go. Don't worry about mistakes. I will give you the chance later to correct any input. Enter username []: adam Enter full name []: Adam Getchell Enter shell csh ksh nologin sh [ksh]: Uid [1000]: Login group adam [adam]: Login group is ``adam''. Invite adam into other groups: guest no [no]: Login class auth-defaults auth-ftp-defaults daemon default staff [default]: Enter password []: Enter password again []: Name: adam Password: **** Fullname: Adam Getchell Uid: 1000 Gid: 1000 (adam) Groups: adam Login Class: default HOME: /home/adam Shell: /bin/ksh OK? (y/n) [y]: Added user ``adam'' Copy files from /etc/skel to /home/adam Add another user? (y/n) [y]: n Goodbye!
Now we're going to add ourselves to the wheel group:
openbrickwall# user mod -G wheel adam
Now we'll configure sudo to allow us to run everything as root:
openbrickwall# visudo
Change the following line:
# Uncomment to allow people in group wheel to run all commands %wheel ALL=(ALL) ALL
As a general rule, don't just randomly add people to wheel.
Instead, you can add particular commands you want them to run as members of particular groups.
Look at man sudo for more details.
Now we'll change the ksh prompt to something friendlier:
openbrickwall# cd /home/adam openbrickwall# ls .cshrc .login .mailrc .profile .rhosts openbrickwall# vi .profile
Add the following line:
export PS1=`whoami`\@`hostname -s`':$PWD # '
Finally, we'll ban root from logging in via SSH:
openbrickwall# cd /etc/ssh openbrickwall# cp sshd_config sshd_config.old openbrickwall# vi sshd_config
Change the following line:
PermitRootLogin no
Now let's logout, then login as ourselves.
We're now going turn off unneeded services.
Again, we'll modify rc.conf.local instead of rc.conf so we can back out changes.
Otherwise, when you boot single mode, you get ed.
Editing files using ed is not fun; if you think vi is bad, vi is a visual wrapper for ed. Enough said:
adam@openbrickwall:/home/adam # vi /etc/rc.conf.local vi: /etc/rc.conf.local: Permission denied
As it should be. We need to run sudo:
adam@openbrickwall:/home/adam # sudo cp /etc/rc.conf /etc/rc.conf.old
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these two things:
#1) Respect the privacy of others.
#2) Think before you type.
Password:
Now edit the file:
adam@openbrickwall:/home/adam # sudo vi /etc/rc.conf.local
(Sudo won't prompt for the password again, it remembers it for 5 minutes.)
Add these lines:
sendmail_flags=NO inetd=NO
Now we'll delete unused directories. We'll leave /var/www because we might run something like Hatchet (which ran on my 3.4 CF) someday:
adam@openbrickwall:/home/adam # sudo rm -rf /var/games adam@openbrickwall:/home/adam # sudo rm -rf /var/named adam@openbrickwall:/home/adam # sudo rm -rf /var/yp
Now let's mount /usr read-only. Naturally, you should backup /etc/fstab, or get real comfortable with ed:
adam@openbrickwall:/home/adam # cd /etc adam@openbrickwall:/home/adam # sudo cp fstab fstab.old adam@openbrickwall:/home/adam # sudo vi fstab
Change the second line to:
/dev/wd0e /usr ffs ro,nodev 1 2
Don't reboot yet, or you won't be able to install rsync.
We'll need rsync to copy files to and from the ramdisk.
Here I'll go fetch the package from our local, fast mirror:
adam@openbrickwall:/etc # sudo pkg_add -v ftp://openbsd.engr.ucdavis.edu/3.5/p> Adding ftp://openbsd.engr.ucdavis.edu/3.5/packages/i386/rsync-2.5.7.tgz adam@openbrickwall:/etc # pkg_info -a pftop-0.4 curses-based real time state and rule display for pf rsync-2.5.7 mirroring/synchronization over low bandwidth links
Now we'll remove unnecessary cron jobs:
adam@openbrickwall:/etc # sudo crontab -e crontab: installing new crontab
Comment out line 9:
#*/30 * * * * /usr/sbin/sendmail -L sm-msp-queue -Ac -q
Add ROOTBACKUP=0 under HOME=/var/log (line 5)
Now we'll turn on the Serial console (instead of having to redirect at the boot prompt):
adam@openbrickwall:/etc # sudo vi /etc/ttys
Change line:
tty00 "/usr/libexec/getty std.9600" vt100 on secure
Now reboot:
adam@openbrickwall:/etc # sudo reboot now
Now if you try to login via SSH as root, you will get Access denied.
We're going to configure the system to use mfs, which is a file system entirely in memory.
This saves read-write cycles on the CompactFlash.
See the Netikus document for more details:
adam@openbrickwall:/home/adam # sudo cp /etc/fstab /etc/fstab.old
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these two things:
#1) Respect the privacy of others.
#2) Think before you type.
Password:
adam@openbrickwall:/home/adam # sudo vi /etc/fstab
Add these lines:
swap /tmp mfs rw,-s=65536,nodev,noatime,noexec,nosuid 0 0 swap /var/log mfs rw,-s=131072,nodev,noatime,noexec,nosuid 0 0 swap /var/run mfs rw,-s=2048,nodev,noatime,noexec,nosuid 0 0 swap /var/tmp mfs rw,-s=16384,nodev,noatime,noexec,nosuid 0 0
Now we want to persist /var/log across reboots:
adam@openbrickwall:/home/adam # sudo mkdir -p /mfs/var.log Password: adam@openbrickwall:/home/adam # sudo rm /var/log/*.gz adam@openbrickwall:/home/adam # sudo /usr/local/bin/rsync -vorpug /var/log/ /mfs/var.log building file list ... done adduser authlog daemon failedlogin ftpd lastlog lpd-errs maillog messages pflog secure sendmail.st wtmp xferlog wrote 328127 bytes read 244 bytes 93820.29 bytes/sec total size is 327215 speedup is 1.00 adam@openbrickwall:/home/adam # sudo cp /etc/rc /etc/rc.old adam@openbrickwall:/home/adam # sudo vi /etc/rc
Add just after "mount /var >/dev/null 2>&1:
# Fill /var/log directory printf "copying files to mfs ..." /usr/local/bin/rsync -orpug /mfs/var.log/ /var/log echo " done." adam@openbrickwall:/home/adam # sudo reboot now
Now /var/log is in memory. We need to copy it to disk during shutdown, using /etc/rc.shutdown:
adam@openbrickwall:/home/adam # sudo cp /etc/rc.shutdown /etc/rc.shutdown.old
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these two things:
#1) Respect the privacy of others.
#2) Think before you type.
Password:
adam@openbrickwall:/home/adam # sudo vi /etc/rc.shutdown
Append these lines:
# Save /var/log directory printf "Copying /var/log to CF ..." # ReMount / read-write now mount -uw /dev/wd0a / /usr/local/bin/rsync -orpug --delete /var/log/ /mfs/var.log echo " done." adam@openbrickwall:/home/adam # sudo reboot now
Now we're going to setup the device files in /dev:
adam@openbrickwall:/dev # sudo mkdir /mfs/dev
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these two things:
#1) Respect the privacy of others.
#2) Think before you type.
Password:
adam@openbrickwall:/dev # sudo cp /dev/MAKEDEV /mfs/dev
adam@openbrickwall:/dev # cd /mfs/dev
adam@openbrickwall:/mfs/dev # sudo ./MAKEDEV all
(This will take awhile)
Now here's where the excellent Netikus document led me astray.
As near as I can tell, their mfs /dev partition is too small.
Edit /etc/fstab so that it looks like this:
/dev/wd0a / ffs rw,noatime,softdep 1 1 /dev/wd0e /usr ffs ro,nodev,noatime,softdep 1 2 /dev/wd0d /var ffs rw,nodev,noatime,nosuid,softdep 1 2 swap /tmp mfs rw,-s=65536,nodev,noatime,noexec,nosuid 0 0 swap /var/log mfs rw,-s=131072,nodev,noatime,noexec,nosuid 0 0 swap /var/run mfs rw,-s=2048,nodev,noatime,noexec,nosuid 0 0 swap /var/tmp mfs rw,-s=16384,nodev,noatime,noexec,nosuid 0 0 swap /dev mfs rw,-s=16384,nosuid 0 0 swap /var/db mfs rw,-s=65536,nodev,noatime,noexec,nosuid 0 0
Of course, you need to make the /mfs/var.db filesystem.
Otherwise the pkg* tools won't remember what's in the package database.
Also, things like Hatchet won't run:
adam@openbrickwall:/mfs/dev # sudo mkdir -p /mfs/var.db
Now we edit /etc/rc appropriately by inserting after the rm -f fastboot line:
#mount -uw / # root on nfs requires this, others aren't hurt rm -f /fastboot # XXX (root now writeable) # Copy dev files before anything else cp -Rp /mfs/dev/* /dev # Remount / read-only mount -ur /dev/wd0a /
And then at our normal spot:
mount /var >/dev/null 2>&1 # Fill /var/log directory printf "copying files to mfs ..." /usr/local/bin/rsync -orpug /mfs/var.log/ /var/log /usr/local/bin/rsync -orpug /mfs/var.db/ /var/db echo " done."
So we've done three things:
- prevented / from mounting writeable by commenting out #mount -uw
- copied our device files
- copied our /var/db files.
Now we need to reboot to let /var/db get copied to /mfs/var.db
Now let's go edit rc.shutdown to ensure our /var/db files get written:
# Save /var/log directory printf "Copying /var/log /var/db to CF ..." # Remount / read-write now mount -uw /dev/wd0a / /usr/local/bin/rsync -orpug --delete /var/log/ /mfs/var.log /usr/local/bin/rsync -orpug --delete /var/db/ /mfs/var.db echo " done."
Now when we want to save this file, we get Read-only filesystem! What to do?
Control-Z to suspend vi:
[1] + Stopped sudo vi /etc/rc.shutdown adam@openbrickwall:/home/adam # sudo mount -uw / adam@openbrickwall:/home/adam # fg
Now save the file using :wq!
To verify this works, let's look at the contents of /var/db:
adam@openbrickwall:/var/db # ls host.random libc.tags ns kvm_bsd.db locate.database pkg
And try our pkg_info commands:
adam@openbrickwall:/var/db # pkg_info -a pftop-0.4 curses-based real time state and rule display for pf rsync-2.5.7 mirroring/synchronization over low bandwidth links
Now we'll reboot and see if everything is kosher:
adam@openbrickwall:/home/adam # cd /var/db adam@openbrickwall:/var/db # ls host.random libc.tags ns kvm_bsd.db locate.database pkg adam@openbrickwall:/var/db # pkg_info -a pftop-0.4 curses-based real time state and rule display for pf rsync-2.5.7 mirroring/synchronization over low bandwidth links
It is!
We now have a nice, small footprint, transparent bridging firewall (once we remove rl1).
- It's almost entirely read-only (barring some parts of /var).
- Local administration can be done via sudo
- root cannot login via ssh, but can login via serial console if the situation is dire.
Hopefully this has also illustrated some best practices towards running what is already the most secure OS.
Best of all, we can backup the firewall by merely copying the flash card.
Enjoy!
Thanks again to the Netikus team for starting the ball rolling, and of course, the misc@openbsd.org mailing list!
REFERENCES
http://www.netikus.net/resources_guides.html
http://www.openbsd.org/faq/pf/index.html



