You are here: Home / OpenBSD / OpenBSD 3.5 on an OpenBrick-E

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:

An OpenBrick-E next to an OpenBSD 3.5 CD set for comparison

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

When:

Where:

Contact