In case you follow the blogs here, you might have noticed that I got interested in FreeBSD over the last months (or even year(s)). The reasons for this are multiple: FreeBSD development is organized in very much the same way as it is with PostgreSQL. The license is very much the same. The history is really interesting as it goes back to the roots of Unix. A lot of companies trust in FreeBSD, but nobody really knows who they are and for what reasons (sounds familiar to PostgreSQL people). There are public references (e.g. here, or here) but as it is “do with it what you like” (same as PostgreSQL) there is no single source of reference. You are free to do with it whatever you want.

The installation is straight forward, so I am not going to look into that here (you might want to check this old post which has detailed screenshots for installing FreeBSD in a virtualized environment). In this first post, we’re going to look at the very basic differences when it comes to FreeBSD and a common Linux distribution. The last sentence already comes with a huge difference between those two: FreeBSD is a complete operating system (including packages and ports), while Linux usually refers to the kernel only. In the Linux world it is up to the distributions to bundle all the stuff you usually need for running a Linux server or workstation. FreeBSD is different, it is not only the kernel, it comes with almost everything you need by default.

Assuming you’ve installed FreeBSD in one way or the other (and you did not create additional users during the installation process) it looks like this once you log in (over ssh in this example)

FreeBSD 14.1-RELEASE GENERIC

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List:        https://www.FreeBSD.org/lists/questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

To change this login announcement, see motd(5).
root@freebsd14:~ # 

The message of the day gives you some hints for getting more information about FreeBSD. This is not commonly done by default in Linux distributions (except Ubuntu, which even comes with a dynamic motd). If you don’t like this, have a look at “man motd” which points you to “/etc/motd.template” which is the template for the message of the day.

One of the first things you’ll probably notice is, that you are not dropped into a bash shell (but the Bourne shell) as it usually is the case with Linux distributions:

root@freebsd14:~ $ echo $SHELL
/bin/sh
root@freebsd14:~ $ ls -la /bin/sh
-r-xr-xr-x  1 root wheel 168344 May 31 11:00 /bin/sh

If you want, you can get bash by installing the corresponding package using pkg:

root@freebsd14:~ $ pkg install bash

Doing that comes with another difference compared to Linux distributions. Additional programs do not go to either “/bin/” or “/usr/bin”, they go to “/usr/local/bin”:

root@freebsd14:~ $ which bash
/usr/local/bin/bash
root@freebsd14:~ $ ls /usr/local/bin/
drwxr-xr-x  2 root wheel     10 Nov 26 10:12 .
drwxr-xr-x  9 root wheel      9 Nov 26 10:12 ..
-rwxr-xr-x  1 root wheel 968408 Oct 31 02:13 bash
-r-xr-xr-x  1 root wheel   6902 Oct 31 02:13 bashbug
-rwxr-xr-x  1 root wheel  42640 Oct 31 02:05 envsubst
-rwxr-xr-x  1 root wheel  42728 Oct 31 02:05 gettext
-r-xr-xr-x  1 root wheel   5190 Oct 31 02:05 gettext.sh
-rwxr-xr-x  1 root wheel  10656 Oct 31 02:04 indexinfo
-rwxr-xr-x  1 root wheel  42496 Oct 31 02:05 ngettext
lrwxr-xr-x  1 root wheel      4 Oct 31 02:14 rbash -> bash

The same is true for package configuration files, they do not go into “/etc” but into “/usr/local/etc/”:

root@freebsd14:~ $ ls -la /usr/local/etc/
total 27
drwxr-xr-x  4 root wheel    6 Nov 26 10:12 .
drwxr-xr-x  9 root wheel    9 Nov 26 10:12 ..
drwxr-xr-x  2 root wheel    3 Nov 26 10:12 bash_completion.d
drwxr-xr-x  5 root wheel    5 Nov 26 10:12 periodic
-rw-r--r--  1 root wheel 2392 Oct 31 02:04 pkg.conf
-rw-r--r--  1 root wheel 2392 Oct 31 02:04 pkg.conf.sample

Before you can install additional packages, you need to setup your network (if not done automatically during the installation). Doing that in Linux varies from distribution to distribution, and in FreeBSD it is also different. If you try to get the current configuration using the “ip” command you’ll notice that it is not available:

root@freebsd14:~ $ ip
-sh: ip: not found

You need to do that using “ifconfig” (as in the old days of Linux or maybe even today with some distributions):

root@freebsd14:~ $ ifconfig
vtnet0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
     options=4c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,TXCSUM_IPV6>
        ether 52:54:00:af:79:80
        inet 192.168.122.34 netmask 0xffffff00 broadcast 192.168.122.255
        media: Ethernet autoselect (10Gbase-T <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

Adding a permanent configuration would look like this, using the sysrc utility:

root@freebsd14:~ $ sysrc ifconfig_vtnet0="inet 192.168.122.34 netmask 255.255.255.0"
ifconfig_vtnet0: inet 192.168.122.34 netmask 255.255.255.0 -> inet 192.168.122.34 netmask 255.255.255.0

The syntax for this is easy to understand: There is an “ifconfig” prefix (because this is what we want to do), followed by an underscore and then the name of the interface followed by the configuration for that interface.

What this is doing is to add this configuration to “/etc/rc.conf” (you could also add that manually, but it is recommend to use sysrc as it does some sanity checks):

root@freebsd14:~ $ grep vtnet0 /etc/rc.conf
ifconfig_vtnet0="inet 192.168.122.34 netmask 255.255.255.0"

The same procedure for the default router:

root@freebsd14:~ $ sysrc defaultrouter="192.168.122.1"
defaultrouter: 192.168.122.1 -> 192.168.122.1
root@freebsd14:~ $ grep defaultrouter /etc/rc.conf
defaultrouter="192.168.122.1"

The last step is to configure name resolution and this goes into “/ect/resolv.conf“, as it was on Linux before systemd:

root@freebsd14:~ $ cat /etc/resolv.conf 
nameserver 192.168.122.1
nameserver 8.8.8.8

As there is no systemd in FreeBSD, it is not used to control services. This is done using the “service” command (restarting the network stack in this case):

root@freebsd14:~ $ service netif restart && service routing restart
Stopping Network: lo0 vtnet0.
lo0: flags=8048<LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
vtnet0: flags=1008802<BROADCAST,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,TXCSUM_IPV6>
        ether 52:54:00:af:79:80
        media: Ethernet autoselect (10Gbase-T <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
Starting Network: lo0 vtnet0.
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
vtnet0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,TXCSUM_IPV6>
        ether 52:54:00:af:79:80
        inet 192.168.122.34 netmask 0xffffff00 broadcast 192.168.122.255
        media: Ethernet autoselect (10Gbase-T <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
delete host 127.0.0.1: gateway lo0 fib 0: gateway uses the same route
delete net default: gateway 192.168.122.1 fib 0: not in table
delete host ::1: gateway lo0 fib 0: gateway uses the same route
delete net fe80::: gateway ::1
delete net ff02::: gateway ::1
delete net ::ffff:0.0.0.0: gateway ::1
delete net ::0.0.0.0: gateway ::1
add host 127.0.0.1: gateway lo0 fib 0: route already in table
add net default: gateway 192.168.122.1
add host ::1: gateway lo0 fib 0: route already in table
add net fe80::: gateway ::1
add net ff02::: gateway ::1
add net ::ffff:0.0.0.0: gateway ::1
add net ::0.0.0.0: gateway ::1

Once this is ready, you should have a fully functional network:

oot@freebsd14:~ $ host dbi-services.com
dbi-services.com has address 188.114.96.3
dbi-services.com has address 188.114.97.3
dbi-services.com has IPv6 address 2a06:98c1:3121::3
dbi-services.com has IPv6 address 2a06:98c1:3120::3
dbi-services.com mail is handled by 0 dbiservices-com0i.mail.protection.outlook.com.
root@freebsd14:~ $ ping www.dbi-services.com
PING www.dbi-services.com (188.114.96.3): 56 data bytes
64 bytes from 188.114.96.3: icmp_seq=0 ttl=57 time=16.670 ms
64 bytes from 188.114.96.3: icmp_seq=1 ttl=57 time=17.779 ms
^C
--- www.dbi-services.com ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.670/17.224/17.779/0.554 ms

The first thing you should do once you have the network running, is to patch the system to the latest release. This is done using “freebsd-update” (“fetch” will inspect the system and download what is required, “install” will apply the patches):

root@freebsd14:~ $ uname -a
FreeBSD freebsd14.it.dbi-services.com 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64
root@freebsd14:~ $ freebsd-update fetch
Looking up update.FreeBSD.org mirrors... 3 mirrors found.
Fetching public key from update2.freebsd.org... done.
Fetching metadata signature for 14.1-RELEASE from update2.freebsd.org... done.
Fetching metadata index... done.
Fetching 2 metadata files... done.
Inspecting system... done.
Preparing to download files... done.
Fetching 115 patches.....10....20....30....40....50....60....70....80....90....100....110.. done.
Applying patches... done.
The following files will be updated as part of updating to
14.1-RELEASE-p6:
/bin/freebsd-version
/boot/kernel/cfiscsi.ko
...
root@freebsd14:~ $ freebsd-update install
Creating snapshot of existing boot environment... done.
Installing updates...
Restarting sshd after upgrade
Performing sanity check on sshd configuration.
Stopping sshd.
Waiting for PIDS: 857.
Performing sanity check on sshd configuration.
Starting sshd.
Scanning /usr/share/certs/untrusted for certificates...
Scanning /usr/share/certs/trusted for certificates...
 done.
root@freebsd14:~ $ reboot
root@freebsd14:~ $ uname -a
FreeBSD freebsd14.it.dbi-services.com 14.1-RELEASE-p5 FreeBSD 14.1-RELEASE-p5 GENERIC amd64
root@freebsd14:~ $ cat /etc/os-release 
NAME=FreeBSD
VERSION="14.1-RELEASE-p6"
VERSION_ID="14.1"
ID=freebsd
ANSI_COLOR="0;31"
PRETTY_NAME="FreeBSD 14.1-RELEASE-p6"
CPE_NAME="cpe:/o:freebsd:freebsd:14.1"
HOME_URL="https://FreeBSD.org/"
BUG_REPORT_URL="https://bugs.FreeBSD.org/"

This brought the system to the latest release (there is much more to learn from the output above, but this will be a topic for a later post).

Updating (or managing) packages is done with “pkg“, but as we do not have anything installed except bash, there is not much too see right now:

root@freebsd14:~ $ pkg update
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
root@freebsd14:~ $ pkg upgrade
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Checking for upgrades (1 candidates): 100%
Processing candidates (1 candidates): 100%
Checking integrity... done (0 conflicting)
Your packages are up to date.

Now we’re ready to go a step further and add users and groups, but this will be the topic for the next post.