Sunday, June 3, 2007

FreeBSD for Linux Users

Today's article examines some of the common command differences a Linux user might encounter on a FreeBSD system.

One of the minor irritations that comes with using another operating system is the change in the environment. Some of the first things many Linux users discover about a default FreeBSD installation are that it doesn't include bash and doesn't colorize the output of ls. Fortunately, if you've become accustomed to these features, it only takes a moment or so to integrate them into FreeBSD. First, as the superuser, add the bash package:
# pkg_add -r bash
That command will go out on the Internet, find the pre-compiled package, install it for you, and update /etc/shells. Note that the path for bash is different on FreeBSD, as it is a third-party application rather than part of the base operating system install:
$ which bash
/usr/local/bin/bash
Hint: in FreeBSD, user binaries that come with the operating system go in /bin, system binaries in /sbin, and system configuration files in /etc. You'll find the equivalents for third-party applications in /usr/local/bin, /usr/local/sbin, and /usr/local/etc. This makes it easier to determine what did and didn't come with the operating system.
Then, from your regular user account, create an alias to ls to use the colorized switch:
$ vi ~/.bashrc
alias ls='ls -G'
Once you've saved your file, type bash to start the shell and issue an ls command to test your change.
Modifying Existing User Accounts
Rather than typing bash every time you log in, you'll probably want to change the default shell of your regular user account to bash; this will require modifying the password database. Like most Linux distros, FreeBSD uses a shadow database. Unlike Linux, this isn't /etc/shadow. Instead, it's /etc/master.passwd, and--this is very important--you don't send this file directly to an editor. (See "Adding a User to FreeBSD, Part 2.")
Instead, use the chpass utility to update all of the password databases correctly. Here, I set the shell for the user dru:
# chpass -s /usr/local/bin/bash dru
chpass: updating the database...
chpass: done
Like the Linux command usermod, chpass has other switches; see man chpass for details. Alternately, if you're comfortable using the vi editor and prefer to see exactly what you're editing, use vipw instead. This will open up the password database in vi and update it correctly when you save your edits.
That reminds me. If you learned how to use vi in Linux, you probably instead learned how to use vim. FreeBSD, by default, uses nvi. If you miss vim, simply type:
# pkg_add -r vim5
Then, set vim as your default editor by adding this line to your ~/.bashrc file:
export EDITOR=/usr/local/bin/vim
Don't forget to type . ~/.bashrc to notify bash of the change to its configuration file. Now vipw will use vim instead of vi. If you're editing files that don't use the $EDITOR variable, and don't think you'll remember to type vim filename instead of vi filename, add an alias to vim in your ~/.bashrc file.
Creating User Accounts
Unix provides several utilities to create user accounts, and you'll probably find the utility you're used to using on a FreeBSD system. The FreeBSD Handbook gives an overview and some working examples of each in the modifying users section. In particular, if you're used to using adduser, you'll find that FreeBSD's version uses an interactive mode.
If you prefer to use an ncurses-type GUI, use the /stand/sysinstall menu. Its Configure option allows you to install software, create users, configure networking, and configure X.
Device Names
You'll find some minor differences in device names. For example, your first Ethernet NIC won't be /dev/eth0. Instead, the device name will indicate the chipset used in your NIC. Here's one way to find out your NIC name(s):
$ dmesg | grep Ethernet
rl0: Ethernet address: 00:05:5d:d2:19:b7
rl1: Ethernet address: 00:05:5d:d1:ff:9d
ed0: port 0x9800-0x981f irq 10 at
device 11.0 on pci0
This particular system has three Ethernet cards: two Realtek cards (rl0 and rl1) and one generic card (ed0). I found the names of the chipsets by sending those NIC names (minus their numbers) to whatis:
$ whatis rl
rl(4) - RealTek 8129/8139 Fast Ethernet device driver

$ whatis ed
ed(1), red(1) - text editor
ed(4) - ethernet device driver
man 4 rl and man 4 ed describe which particular NIC models the specified chipset covers.
You'll also find that the names for your hard drives and partitions are different:
$ df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ad0s1a 253678 65594 167790 28% /
devfs 1 1 0 100% /dev
/dev/ad0s1e 253678 18482 214902 8% /tmp
/dev/ad0s1f 13147670 6526230 5569628 54% /usr
/dev/ad0s1d 253678 42232 191152 18% /var
linprocfs 4 4 0 100% /usr/compat/linux/proc
Compare that to the df output from a Red Hat system:
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda2 9506024 2080628 6942516 24% /
/dev/hda1 99043 9275 84654 10% /boot
none 63016 0 63016 0% /dev/shm
/dev/cdrom 636408 636408 0 100% /mnt/cdrom
Red Hat uses hd to represent an IDE hard drive; FreeBSD uses ad. Red Hat uses a to represent the primary master; FreeBSD uses 0. Red Hat follows the a with a number representing the partition--in this case, 1 and 2 are the first two primary partitions. FreeBSD uses slices (hence the s) and this system has 1 FreeBSD slice divided into several partitions. By convention, partition a is / and b is /swap. This particular system also has d mounted on /var, e mounted on /tmp, and f mounted on /usr.
Note: like Linux, FreeBSD uses the file /etc/fstab to determine how to mount filesystems; however, it does not use the file /etc/mtab. (If you've installed Linux compatibility, use more /usr/compat/linux/proc/mtab instead.) The commands mount and df list the currently mounted filesystems.
What Happened to /proc?
You're in for a surprise if you habitually poke about /proc for information on your hardware and the state of your running Linux system. Again, if you've installed Linux compatibility, you'll find most of what you're looking for in /usr/compat/linux/proc. However, also experiment with FreeBSD's powerful sysctl mechanism.
Typing sysctl -a | more (a for "all") is the equivalent of viewing every /proc entry at once, and then some. This is an excellent way not only to watch what happens on a running system but also to understand what the term "kernel state" means. I recommend you try this command at least once.
A judicious use of grep can help when you know what you're looking for. For example, to see current memory usage:
% sysctl -a | grep -i memory
Virtual Memory: (Total: 614K, Active 185444K)
Real Memory: (Total: 295928K Active 100972K)
Shared Virtual Memory: (Total: 74960K Active: 68524K)
Shared Real Memory: (Total: 43296K Active: 40048K)
Free Memory Pages: 36412K
p1003_1b.memory_protection: 0
p1003_1b.shared_memory_objects: 1
The superuser has the capability of changing many of the sysctl tunables on the fly. For example, to view the system's TTL:
# sysctl -a | grep ttl
net.inet.ip.ttl: 64
To change (write to) it:
# sysctl -w net.inet.ip.ttl=100
net.inet.ip.ttl: 64 -> 100

#sysctl net.inet.ip.ttl
net.inet.ip.ttl: 100
man sysctl and the tuning with sysctl section of the Handbook have more information.
Many Linux commands (e.g., ps, top, and free, to name a very few) query /proc for information on what is currently happening on the system. Similarly, many FreeBSD commands query sysctl. While you could manually send the information in /proc to a pager or grep through sysctl -a, it's often easier to have a command do the query and format the results for you. For example, on a FreeBSD 5.x system, devinfo will show your system resources, categorized by type of resource:
$ devinfo -ru
Interrupt request lines:
0x0 (root0)
0x1 (atkbd0)
0x3 (sio1)
0x4 (sio0)
0x5 (rl0)
0x6 (fdc0)
0x7-0x8 (root0)
0x9 (acpi0)
0xa (pcm0)
0xb (uhci0)
0xc (psm0)
0xd (root0)
0xe (ata0)
0xf (ata1)
DMA request lines:
0-1 (root0)
2 (fdc0)
3-7 (root0)
I/O ports:
0x0-0xf (root0)
0x10-0x1f (acpi_sysresource0)
0x20-0x21 (root0)

I/O memory addresses:
0x0-0x9ffff (root0)
0xa0000-0xbffff (vga0)
0xc0000-0xcbfff (orm0)
0xcc000-0xfbffffff (root0)
0xfc000000-0xfdffffff (agp0)
0xfe000000-0xffffffff (root0)
open if_tun units:
0-32767 (root0)
swapinfo will show your currently mounted swap devices:
$ swapinfo
Device 1K-blocks Used Avail Capacity
/dev/ad0s1b 637704 156 637548 0%
There are dozens of other useful utilities available. To find them, try these commands:
$ apropos info | grep 8
$ apropos stat | grep 1
$ apropos stat | grep 8
Modules
Like Linux, the FreeBSD kernel supports the loading and unloading of modules. This allows an administrator to add or remove driver support without having to recompile the kernel or reboot the system. The possible modules are the files ending with the .ko extension in /boot/kernel.
To list the currently loaded modules:
$ kldstat
Id Refs Address Size Name
1 10 0xc0400000 3348d8 kernel
2 1 0xc0735000 51ac8 acpi.ko
3 1 0xc3168000 6000 linprocfs.ko
4 1 0xc316e000 19000 linux.ko
If you're curious as to the meaning of each of the columns, see man 2 kldstat. Note that the usage and output is similar to Linux's lsmod command.
Linux also provides the insmod and rmmod commands to load and unload modules. The FreeBSD equivalents are kldload and kldunload. For example, to load USB scanner support:
# kldload uscanner.ko
To remove it when you're finished:
# kldunload uscanner.ko
Loading something that is already statically compiled into the kernel produces this error message:
# kldload snd_pcm.ko
kldload: can't load snd_pcm.ko: File exists
If you don't know what a module does, ask whatis. Suppose that I'm curious about the module if_pcn.ko. I won't include the .ko in my query. I also won't include the if_; it categorizes the module as an interface type. (Similarly, snd_ represents the sound category.) That leaves pcn, making this command:
$ whatis pcn
pcn(4) - AMD PCnet/PCI fast ethernet device driver
I think my NIC might fall into that category. man 4 pcn gives the actual NIC models covered by this particular kernel module.
FreeBSD Terminology
To end this article, here are the FreeBSD equivalents to some common Linux tasks, as well as some document references to start you in your own research.
You won't find ipfwadm, ipchains, or ipfilter on a FreeBSD system. However, FreeBSD does come with several built-in firewalls. ipfw provides a stateful firewall with an easily understandable rule syntax. Ipfilter, or ipf, provides a more complex rulebase that supports the chaining of rules. Newer FreeBSD versions also support OpenBSD's pf. The firewall section of the Handbook is a good place start. It contains hyperlinks to several sites with more detailed documentation.
FreeBSD also supports NAT (IP masquerading) and bandwidth limiting (known as dummynet). Start with the Advanced Networking section of the Handbook.
The author of dummynet has a useful dummynet tutorial and Erudition has a comprehensive NAT tutorial.
FreeBSD uses vinum to provide software RAID. Dan Langille details real-world vinum usage at his FreeBSD Diary.
FreeBSD also supports netgraph (4) to augment the kernel's networking support. DaemonNews has an excellent netgraph article, and the See Also section of the manpage refers to the available netgraph modules. There are also several working examples found within the subdirectories of /usr/share/examples/netgraph.
Finally, FreeBSD 5.x supports the use of gbde to encrypt disk partitions. BSD News has a tutorial showing how to encrypt a USB thumbdrive using both GBDE and the CFS third-party application.
Conclusion
Once you're familiar with FreeBSD terminology and some of the design differences between Linux and FreeBSD, you'll find that most of your Linux skills easily transfer over to FreeBSD. As you read the FreeBSD handbook and manpages, you're likely to discover new skills that you can practice on both operating systems.