Whether or not you know it, the world runs on BSD. You can’t send a packet more than a few hops without a BSD-derived TCP/IP stack getting involved. Heck, you’d be hard pressed to find a machine which doesn’t already have BSD code throughout the OS.
Why BSD? Many companies don’t want to deal with GPL code and the BSD license allows any use so long as the BSD group is acknowledged. This is why Windows has BSD code, Mac OS X is based on BSD (both in its current incarnation which pulls much code from FreeBSD and NetBSD as well as via code which came from NeXTStep, which in turn was derived from 4.3BSD), GNU/Linux has lots of code which was written while looking at BSD code, and most TCP/IP stacks on routers and Internet devices are BSD code.
In the context of IT tools BSD excels due to its cleanliness and consistency. GNU/Linux, on the other hand, has so many different distributions and versions that it’s extremely difficult to do certain tasks across different distributions in any consistent way. Furthermore, the hardware requirements of GNU/Linux precludes using anything but typical x86 PC with a full compliment of associated resources. Managing GNU/Linux on non-x86 hardware is a hobby in its own right and not the kind of thing anyone would want to do in a production environment.
NetBSD in particular stands in stark contrast to GNU/Linux when deploying on machines of varying size and capacity. One could just as easily run NetBSD from an old Pentium 4 machine as a tiny StrongARM SheevaPlug, a retired PowerPC Macintosh, or a new 16 core AMD Interlagos machine. A usable system could have 32 megs of memory or 32 gigs. Disk space could be a 2 gig USB flash drive or tens of terabytes of RAID.
Configuration files are completely consistent across architecture and hardware. You may need to know a little about the hardware when you first install (wd, sd, ld for disks, ex, wm, fxp, et cetera for NICs, for example), but after that everything works the same no matter the underlying system.
Some instances where a BSD system can be invaluable are situations where the installed tools are too limited in scope to diagnose problems, where problematic hardware needs to be replaced or augmented quickly with whatever’s at hand, or where secure connectivity needs to be established quickly. Some examples where BSD has come in handy are:
In a warehouse where an expensive firewall device was flakey, BSD provided a quick backup. Removing the flaky device would have left the building with no Internet connection. An unused Celeron machine with a USB flash drive and an extra ethernet card made for a quick and easy NetBSD NAT / DHCP / DNS server for the building while the firewall device was diagnosed.
At another business an expensive firewall device was in use which is not capable of showing network utilization in any detail without setting up a separate computer for monitoring (and even then it is limited to giving very general and broad information), nor is it flexible when it comes to routing all traffic through alternate methods such as gre or ssh tunnels. Setting up an old Pentium 4 with a four port ethernet card gave us a router / NAT device which allowed us to do tests where we passed all traffic through a single tunnel to an upstream provider to test the ISP’s suggestion that too many connections were running simultaneously (which wasn’t the case, but sometimes you have to appease the responsible party before they’ll take the next step). They can also now monitor network traffic quickly and easily using darkstat (http://unix4lyfe.org/darkstat/), monitor packet loss, see who on the local networks is causing network congestion, et cetera. The machine serves three separate local network segments which can talk with each other. One segment is blocked from accessing the Internet because it contains Windows systems running Avid, but can be turned on momentarily to allow for software activation and similar things.
When another business needed a place to securely host their own WordPress blog, an unused Celeron machine was set up with a permissions scheme which regular web hosting providers won’t typically allow. WordPress is set up so that neither the running php code nor the www user can write to areas which allow for script execution, eliminating almost all instances where WordPress flaws can give full hosting abilities to attackers, which is how WordPress is so often used to host phishing sites and advertising redirectors.
DNS hosting, NAT or routing can be set up in minutes, a bridge can be configured to do tcpdump capture, or a web proxy can be installed to save bandwidth and perform filtering. An SMTP relay can be locally installed to save datacenter bandwidth.
So let’s say you think that a NetBSD machine could help you. But how? If you haven’t used NetBSD yet, then here are some tips.
The latest version is 6.0. The ISOs from NetBSD’s FTP server typically weigh in at around 250 to 400 megabytes, so CDs are fine. The installer is pretty straightforward and the mechanisms for installing on various architectures is not germane.
After boot, the system is pretty bare, so here are things you’ll want to do:
Let’s look at a sample /etc/rc.conf:
dhcpcd_flags=”-C resolv.conf -C mtu”
ifconfig_wm1=”inet 192.168.50.1 netmask 255.255.255.0″
dhcpd_flags=”wm1 -cf /etc/dhcpd.conf”
rtadvd_flags=”-c /etc/rtadvd.conf wm1″
So what we have here are a number of somewhat obvious and a few not-so-obvious options. Let’s assume you know what hostname, sshd, named9, ipnat and dhcpd are for. You can even make guesses about many of the options. What about ifconfig_wm0 (and its flags), ip6mode and other not-so-obvious rc.conf options? First, obviously, you can:
dhcpcd is a neat DHCP client which is lightweight, supports IPv6 auto discovery and is very configurable. man dhcpcd to see all the options; the example above gets a lease on wm0 but ignores any attempts by the DHCP server to set our resolvers or our interface’s MTU. ifconfig_wm1 should be pretty self-explanatory.
ipnat and ipfilter enable NetBSD’s built in ipfilter (also known as ipf) and its NAT. Configuration files may often be as simple as this for NAT in /etc/ipnat.conf:
map wm0 192.168.50.0/24 -> 0/32 proxy port ftp ftp/tcp
map wm0 192.168.50.0/24 -> 0/32 portmap tcp/udp 10000:50000
map wm0 192.168.50.0/24 -> 0/32
rdr wm0 0.0.0.0/0 port 5900 -> 192.168.50.175 port 5900
And lines which look like this for ipfilter in /etc/ipf.conf:
block in quick from 188.8.131.52/32 to any
There’s tons of documentation on the Internet, particularly here:
To quickly summarize, the first three lines set up NAT for the 192.168.50.0/24 subnet. The ftp line is necessary because of the mess which is FTP. The second line says to only use port numbers in that range for NAT connections. The third line is for non-TCP and non-UDP protocols such as ICMP or IPSec. The fourth redirects port 5900 of the public facing IP to a host on the local network.
The ipf.conf line is straightforward; ipf in many instances is used to block attackers since you wouldn’t turn on or redirect services which you didn’t intend to be public. Other examples are in the documentation and include stateful inspection (including stateful UDP; I’ll let you think for a while about how that might work), load balancing, transparent filtering (on a bridge), port spanning, and so on. It’s really quite handy.
Next is BIND. It comes with NetBSD and if you know BIND, you know BIND. Simple, huh?
rtadvd is the IPv6 version of a DHCP daemon and ip6mode=router tells the system you intend to route IPv6 which does a few things for you such as setting net.inet6.ip6.forwarding=1. You’re probably one of those, “We don’t need that yet” people, so we’ll leave that for another time. IPv6 is easier than you think.
dhcpd is for the ISC DHCP server. man dhcpd and check out the options, but most should already look familiar.
So you have a system up and running. What next? You may want to run some software which isn’t included with the OS such as Apache (although bozohttpd is included if you just want to set up simple hosting), PHP, MySQL, or if you’d like some additional tools such as emacs, nmap, mtr, perl, vim, et cetera.
To get the pkgsrc tree in a way which makes updating later much easier, use CVS. Put this into your .cshrc:
setenv CVSROOT :pserver:firstname.lastname@example.org:/cvsroot
cvs checkout -P pkgsrc
After that’s done (or while it’s running), set up /etc/mk.conf to your liking. Here’s one I use most places:
Set LOCALBASE if you prefer a destination other than /usr/pkg/. PKG_RCD_SCRIPTS tells pkgsrc to install rc.d scripts when installing packages. PKG_OPTIONS.whatever might be different for various packages; I put this one in here as an example. To see what options you have, look at the options.mk for the package you’re curious about. CLEANDEPENDS tells pkgsrc to clean up working directories after a package has been compiled.
After the CVS has finished, you have a tree of Makefiles (and other files) which you can use as simply as:
That will automatically download, compile and install all prerequisites (if any) for the vim package, then download, compile and install vim. I personally use “make update” in case I’m updating an older package, FYI.
With software installed, the rc.conf system works similarly to the above. After adding Apache, for instance (www/apache24/), you can just add apache=YES >> /etc/rc.conf. That sets Apache to launch at boot; to start it without rebooting, just run /etc/rc.d/apache start.
One package which comes in very handy when trying to keep a collection of packages up to date is pkg_rolling-replace (/usr/pkgsrc/pkgtools/pkg_rolling-replace). After performing a cvs update in /usr/pkgsrc, one can simply run pkg_rolling-replace -ru and come back a little later; everything which has been updated in the CVS tree will be compiled and updated in the system.
Finally, to update the entire OS, there are just a handful of steps:
cvs checkout -P -rnetbsd-6 src
In this instance, the netbsd-6 tag specifies the release branch (as opposed to current) of NetBSD.
I keep a wrapper called go.sh in /usr/src so I don’t need to remember options. This makes sure that all the CPUs are used when compiling and the destinations of files are in tidy, easy to find places.
./build.sh -j `sysctl -n hw.ncpu` -D ../dest-$1 -O ../obj-$1 -T ../tools -R ../sets -m $*
An example of a complete OS update would be:
./go.sh amd64 tools
./go.sh amd64 kernel=GENERIC
./go.sh amd64 distribution
./go.sh amd64 install=/
mv /netbsd /netbsd.old
mv /usr/obj/sys/arch/amd64/compile/GENERIC/netbsd /
shutdown -r now
Updating the OS is usually only necessary once every several years or when there’s an important security update. Security updates which pertain to the OS or software which comes with the OS are listed here:
The security postings have specific instructions on how to update just the relevant parts of the OS so that in most instances a complete rebuild and reboot are not necessary.
Security regarding installed packages can be checked using built-in tools. One of the package tools is called pkg_admin; this tool can compare installed packages with a list of packages known to have security issues. To do this, one can simply run:
A sample of output might look like this:
Package mysql-server-5.1.63 has a unknown-impact vulnerability, see http://secunia.com/advisories/47894/
Package mysql-server-5.1.63 has a multiple-vulnerabilities vulnerability, see http://secunia.com/advisories/51008/
Package drupal-6.26 has a information-disclosure vulnerability, see http://secunia.com/advisories/49131/
You can then decide whether the security issue may affect you or whether the packages need to be updated. This can be automated by adding a crontab entry for root:
# download vulnerabilities file
0 3 * * * /sbin/pkg_admin fetch-pkg-vulnerabilities >/dev/null 2>&1
5 3 * * * /sbin/pkg_admin audit
All in all, BSD is a wonderful tool for quick emergency fixes, for permanent low maintenance servers and anything in between.