TSR – The Server Room Show – Episode 43 – OpenBSD

OpenBSD

OpenBSD is a 4.4BSD-based UNIX-like operating system built from the ground up to focus its efforts on emphasize portability, standardization, correctness, proactive security and integrated cryptography. OpenSSH the popular software comes from OpenBSD.

Why might you want to use it?Some interesting things to mention….

  • OpenBSD runs on many different hardware platforms.
  • OpenBSD is thought of as the most secure UNIX-like operating system by many security professionals, as a result of the never-ending comprehensive source code audit.
  • OpenBSD is a full-featured UNIX-like operating system available in source and binary form at no charge.
  • OpenBSD integrates cutting-edge security technology suitable for building firewalls and private network services in a distributed environment.
  • OpenBSD benefits from strong ongoing development in many areas, offering opportunities to work with emerging technologies and an international community of developers and end users.
  • OpenBSD attempts to minimize the need for customization and tweaking. For the vast majority of users, OpenBSD just works on their hardware for their application.
  • OpenBSD runs on a lot of different architectures although less than NetBSD does 🙂
  • It is very well documented and has mailing lists in place for those who want to get involved.
  • OpenBSD has gone through heavy and continual security auditing to ensure the quality and security of the code.
  • OpenBSD does not support journaling filesystems. Instead we use the soft updates feature of the Fast File System (FFS).
  • OpenBSD comes with Packet Filter (PF). This means that Network Address Translation, queuing, and filtering are handled through pfctl(8), pf(4) and pf.conf(5).
  • OpenBSD’s default shell is ksh, which is based on the public domain Korn shell. Shells such as bash and many others can be added from packages.
  • Devices are named by driver, not by type. In other words, there are no eth0 and eth1 devices. It would be em0 for an Intel PRO/1000 Ethernet card, bge0 for a Broadcom BCM57xx or BCM590x Ethernet device, ral0 for a RaLink wireless device, etc.
  • OpenBSD/i386, amd64, and several other platforms use a two-layer disk partitioning system, where the first layer is the fdisk BIOS-visible partition and the second is the disklabel.
  • Some other operating systems encourage you to customize your kernel for your machine. OpenBSD users are encouraged to simply use the standard GENERIC kernel provided and tested by the developers.
rc and init

rc is the command script that is invoked by init(8) when the system starts up. It performs system housekeeping chores and starts up system daemons.

In Unix-based computer operating systems, init (short for initialization) is the first process started during booting of the computer system. Init is a daemon process that continues running until the system is shut down. It is the direct or indirect ancestor of all other processes and automatically adopts all orphaned processes. Init is started by the kernel during the booting process; a kernel panic will occur if the kernel is unable to start it. Init is typically assigned process identifier 1. In Unix systems such as System III and System V, the design of init has diverged from the functionality provided by the init in Research Unix and its BSD derivatives. Up until recently, most Linux distributions employed a traditional init that is somewhat compatible with System V, while some distributions such as Slackware use BSD-style startup scripts, and others such as Gentoo have their own customized versions.

Since then, several additional init implementations have been created, attempting to address design limitations in the traditional versions. These include launchd, the Service Management Facility, systemd, Runit and OpenRC.

Additionally, rc is intricately tied to the netstart(8) script, which runs commands and daemons pertaining to the network. rc is also used to execute any rc.d(8) scripts defined in rc.conf.local(8). The rc.securelevel, rc.firsttime, and rc.local scripts hold commands which are pertinent only to a specific site.

All of these startup scripts are controlled to some extent by variables defined in rc.conf(8), which specify which daemons and services to run.

rc is the command script that is invoked by init(8) when the system starts up. It performs system housekeeping chores and starts up system daemons. Additionally, rc is intricately tied to the netstart(8) script, which runs commands and daemons pertaining to the network. rc is also used to execute any rc.d(8) scripts defined in rc.conf.local(8). The rc.securelevel, rc.firsttime, and rc.local scripts hold commands which are pertinent only to a specific site.

All of these startup scripts are controlled to some extent by variables defined in rc.conf(8), which specify which daemons and services to run.

Before init(8) starts rc, it sets the process priority, umask, and resource limits according to the “daemon” login class as described in login.conf(5). It then starts rc and attempts to execute the sequence of commands therein.

OpenBSD as a Desktop Operating System — Daily Driver
Installation of OpenBSD 6.7
Running xenodm as root to bring up to logon manager
Logged in as normal user to the fresh OpenBSD 6.7 installation
Networking and DNS resolution works fine. top is running on the right terminal window
OpenBSD as a Firewall/Router

I found this great article about OpenBSD as a firewall I want to talk about.
https://dzone.com/articles/high-availability-routerfirewall-using-openbsd-car

in this example two small appliances are used to serve as R1 and R2 with OpenBSD in a home network scenario. One PCEngines APU4C4 and an older Soekris net5501. They are set up in failover mode using CARP and pfsync

https://lh5.googleusercontent.com/UY4DMYRIRbNr-ERHu_0yoidz5wG8aYYoQGCmOJZiobPjoA7iQPOxZeJNWVe_-BIcQ35ZSAFss0a6mtvjNXMXu1g-qXcf8N7xD8R3HgsG7ifGnqi6nEG-vwp9Liq99JGs0xytZhmW
Example Network Topology from https://dzone.com & Chad Gross
  • All three switches are unmanaged switches.
  • Both R1 and R2 handling out DHCP Addresses from the same pool but split *R1 in the range of .151-250 and R2 in the range of .100-150
  • vr0 and em0 are the WAN interfaces of R1 and R2 respectively receiving IP assigned via DHCP from ISP *or ISP’s router perhaps*

Example Network Topology from https://dzone.com & Chad Gross


R1 and R2 has pfsync service running and keeping them in sync on vr1 and em1 interfaces

R1 and R2 has pflow service running and keeping them in sync on vr2 and em2 interfaces


CARP and pfsync

CARP is the Common Address Redundancy Protocol. Its primary purpose is to allow multiple hosts on the same network segment to share an IP address. CARP is a secure, free alternative to the Virtual Router Redundancy Protocol (VRRP) and the Hot Standby Router Protocol (HSRP).

CARP works by allowing a group of hosts on the same network segment to share an IP address. This group of hosts is referred to as a “redundancy group.” The redundancy group is assigned an IP address that is shared amongst the group members. Within the group, one host is designated the “master” and the rest as “backups.” The master host is the one that currently “holds” the shared IP; it responds to any traffic or ARP requests directed towards it. Each host may belong to more than one redundancy group at a time.

One common use for CARP is to create a group of redundant firewalls. The virtual IP that is assigned to the redundancy group is configured on client machines as the default gateway. In the event that the master firewall suffers a failure or is taken offline, the IP will move to one of the backup firewalls and service will continue unaffected.

CARP supports IPv4 and IPv6.

The pfsync(4) network interface exposes certain changes made to the pf(4) state table. By monitoring this device using tcpdump(8), state table changes can be observed in real time. In addition, the pfsync(4) interface can send these state change messages out on the network so that other nodes running PF can merge the changes into their own state tables. Likewise, pfsync(4) can also listen on the network for incoming messages.

y default, pfsync(4) does not send or receive state table updates on the network; however, updates can still be monitored using tcpdump(8) or other such tools on the local machine.

When pfsync(4) is set up to send and receive updates on the network, the default behavior is to multicast updates out on the local network. All updates are sent without authentication. Best common practice is either:

Connect the two nodes that will be exchanging updates back-to-back using a crossover cable and use that interface as the syncdev (see below).
Use the ifconfig(8) syncpeer option (see below) so that updates are unicast directly to the peer, then configure ipsec(4) between the hosts to secure the pfsync(4) traffic. 

When updates are being sent and received on the network, pfsync packets should be passed in the filter ruleset:

pass on $sync_if proto pfsync

$sync_if should be the physical interface that pfsync(4) is communicating over.

Links

http://www.troubleshooters.com/linux/pf/index.htm

https://www.openbsd.org/faq/pf/filter.html

https://www.openbsd.org/faq/pf/

https://dzone.com/articles/high-availability-routerfirewall-using-openbsd-car

https://en.wikipedia.org/wiki/Init

https://man.openbsd.org/rc.8

https://www.openbsd.org/papers/eurobsd-firewalls-2002.pdf

https://bsd.cat/es/