Roland's FreeBSD pageDocumentation and setup tips |
|
Location: homepage > FreeBSD
This page is a gathering place for all my FreeBSD related stuff, except my software.
Apart from the normal text, there are different colors used for
/path/of/file
configuration files
and
shell commands.
If a shell command is preceded by a dollar sign ($), it should be run by a normal user. Commands preceded by a hash mark (#) should be run as the root user.
Topics covered on this page:
When I was setting up my Athlon64 box with FreeBSD 5.3, I had some trouble figuring out how to retain device permissions across reboots. That's why I wrote manual pages for devfs.conf(5) and devfs.rules(5). These are included in current releases.
Before actually installing FreeBSD on my new amd64 box, I ran 5.3 inside qemu on my old Slackware box. This allowed me to practice things before doing the real install. At a minimum, I'd recommend keeping an old computer with an internet connection handy when installing.
Since my system has enough disk space, I did a complete installation. For partitioning, I didn't follow the system recommendation, but used a separate partition for /home.
One thing I will change if I re-install FreeBSD is the location of /usr/local. For easier dumps, I'd place it on a separate partition, since this is where most ports install their stuff.
My install went without problems. Before buying my new system, I had selected components that were supported by FreeBSD. A bit of reading through motherboard docs online goes a long way here. I cannot stress enough how important this is. A bit of work here can save you a world of grief afterwards. The thing to watch is de make and type of the chips on the motherboard and cards you want to buy, NOT the brand name of the card/mobo. This is especially true for WiFi cards, as these may be sold with different chipsets without changing the name or model number!
After installing the base system, I made some changes so that the system suits me better. I'm documenting them here in the hope that they will be usefull for others. These settings were made for FreeBSD 5.3 on amd64, but have been continuously updated to 7-STABLE.
To keep track of things, I keep configuration files (including the kernel configuration) under revision control with git. My reason for using git is that I use it for all my projects, including these webpages. Unlike traditional revision control systems, git handles binary files (e.g. pictures) well. It is also very fast. For text files like configuration files you could also use rcs or cvs.
The reason for doing this is that it makes it easier to spot and undo mistakes that can disrupt your system. Before I install a modified version of a configuration file, I commit the changes to the revision control system. If this change ends up breaking part of the system, it is easy to spot the change and restore a previous (working) version of the file in question.
I use a couple of perl scripts to check for differences between files in my configuration directory and the real files in the system directories, and to install newer files if possible. Both files use a list of files to compare, en excerpt of which follows:
filelist.root excerpt
# setup file perm system file commands boot/device.hints 644 /boot/device.hints boot/loader.conf 644 /boot/loader.conf etc/X11/xorg.conf 644 /etc/X11/xorg.conf etc/aspell.conf 644 /usr/local/etc/aspell.conf etc/cdrecord 644 /usr/local/etc/cdrecord etc/csh.cshrc 644 /etc/csh.cshrc etc/devfs.conf 644 /etc/devfs.conf etc/devfs.rules 644 /etc/devfs.rules etc/esd.conf 644 /usr/local/etc/esd.conf etc/fbtab 644 /etc/fbtab etc/fstab 644 /etc/fstab etc/group 644 /etc/group ...
Lines starting with a '#' are ignored. Other lines contain a file in the setup tree, a permission of the system file, the location of the system file and optional commands to be executed after the file is installed.
The script check.pl uses md5 sums to compare files in the setup directory with their associated file in the system configuration. If they don't match it prints the unified diff between them.
check.pl
#!/usr/bin/perl
# Check for changes in config files.
$name = `id -u -n`;
open(RF, "filelist.$name") || die "Cannot open list file 'filelist.$name'.";
while(<RF>) {
chomp;
if (/^#/) {next}; # skip comment lines.
($src,$perm,$dest) = split;
if (-r $dest) {
$msrc = `md5 -q $src`;
$mdest = `md5 -q $dest`;
if ($msrc ne $mdest) {
printf "%s != %s\n", $src, $dest;
system "diff", "-u", $dest, $src;
} else {
#printf "%s matches %s\n", $src, $dest;
}
} else {
printf "%s cannot be read.\n", $dest;
}
}
close(RF);
Using the same file description list, the script install.pl installs files that have changed in the setup directory or that are absent in the filesystem:
install.pl
#!/usr/bin/perl
# Install files according to instructions in 'filelist.$USER'.
# Time-stamp: <2008-12-27 21:59:54 rsmith>
$name = `id -u -n`;
open(RF, "filelist.$name") || die "Cannot open list file 'filelist.$name'.";
while(<RF>) {
chomp;
if (/^#/) {next}; # Skip comment lines.
@cmds = split;
$src = shift @cmds;
$perm = shift @cmds;
$dest = shift @cmds;
# Skip identical files.
if (-e $dest) {
$msrc = `md5 -q $src`;
$mdest = `md5 -q $dest`;
if ($msrc eq $mdest) {next};
}
# Create directories if necessary
$tdir = `dirname $dest`;
chomp $tdir;
if (! -d $tdir) {
print "\e[31m";
$rv = system "install", "-d", $tdir;
$rv>>8;
if ($rv == 0) {
printf "\e[32mCreated %s.\n\e[39m", $tdir;
} else {print "\e[39m";}
}
# Install the file
print "\e[31m";
$rv = system "install", "-p", "-m", $perm, $src, $dest;
$rv>>8;
if ($rv == 0) {
printf "\e[32mInstalled %s as %s.\n\e[39m", $src, $dest;
# Execute post-install commands.
if (@cmds) {
$rv = system @cmds;
$rv>>8;
if ($rv != 0) {
printf "\e[31mPost-install commands for %s failed.\n\e[39m",
$src;
}
}
} else {print "\e[39";}
}
close(RF);
My Laserjet 2550 printer attached to the parallel port printed very slowly. The system logfile mentioned that the system was throttling interrupts from the parallel port because of an "interrupt storm". After reading the ppc(4) manual page, I added the following to /boot/device.hints, to put the port into polling mode:
hint.ppc.0.flags="0x28"
The flag 0x08 puts the port into ECP mode, and 0x20 makes the driver poll the port, instead of using an interrupt.
When using CUPS like I am, its programs need to have access to the printer device. In my case connected to the parallel port;
# chown root:cups /dev/lpt0 # chmod g+rw /dev/lpt0
To make this change permanent, you can add the following rules to /etc/devfs.conf;
# Give cups printer access own lpt0 root:cups perm lpt0 0660
This will make sure that the relevant group and permissions will be installed after the next reboot.
In case you have a USB connected printer, you should add a rule to devfs.rules for a ulpt(4) device.
The printer now works fine with CUPS. One caveat I came across, is that you need to use the command-line tools to install a printer with a PPD file. I used the following command to install my printer in CUPS:
# /usr/local/sbin/lpadmin -E -p clj2550 -v parallel:/dev/lpt0 -P clj2550.ppd
My computer has an Asus P5KPL-VM motherboard, which has AC97 compatible onboard sound. To enable that, I added the following devices to my kernel configuration file:
# Soundcard support device sound device snd_hda
While playing music with xmms(1), I noticed little clicks and lags in the sound output. After some googling I added the following line to /boot/device.hints, to enlarge the DMA buffer for the sound driver (the default is 4096 bytes).
hint.pcm.0.buffersize="16384"
The sound driver is able to combine sounds from different sources and output then through one device. This is activated in sysctl.conf.
This was sufficient to fix the problem.
My ADSL connection goes through a Thompson Speedtouch 510 ADSL ethernet modem/router. This makes the setup very easy, because to the computer it's just another IP gateway to the internet. So it's compatible with almost all operating systems. If you want easy setup, go for one of these.
My aforementioned motherboard has a Attansic/Atheros L1 ethernet chip on-board. I also have an extra PCI ethernet card, an old 3Com Fast Etherlink XL. To enable these, I added the following to my kernel configuration file:
# PCI ethernet device device miibus device xl # 3Com Fast Etherlink XL device age # Attansic/Atheros L1 Gigabit Ethernet
Initially, I used a card with a realtek 8139 chip to connect a laptop for transferring files, but that didn't work very well. Transferring files from the laptop to the desktop could saturate the link, but transfer from the desktop to the laptop was extremely slow, topping out at an intermittant rate of 200 kB/s. Switching to an old 3Com card I had improved this enormously. This can saturate the link in both directions.
The following settings were added to /etc/rc.conf to enable these devices:
# Network settings ifconfig_lo0="inet 127.0.0.1" ifconfig_age0="inet 10.0.0.150/24 polling media 100baseTX mediaopt full-duplex" ifconfig_xl0="inet 192.168.0.1/24 polling media 100baseTX mediaopt full-duplex" defaultrouter="10.0.0.138" tcp_extensions="NO"
The defaultrouter entry points to my ADSL modem. The IP address for the sk0 interface can be freely chosen from the 10.0.0.x address range. This Just Works™.
FreeBSD 5.x has a dynamic /dev filesystem. This means that entries in /dev are created or removed depending on the available devices.
When devices are created, they get default ownership and permission settings. These settings can be changed via the devfs(8) program, or with the chown(1) and chmod(8) utilities. The problem is that settings made in this manner do not survive a reboot, and settings made with chmod and chown do not survive a device being unplugged.
Enter the files /etc/devfs.conf and /etc/devfs.rules. The first one is suited for changing those devices that are available at boot time, and are not likely to be unplugged, like CD-ROM drives etc. The second one is best suited for setting permissions etc. for devices that can be plugged in and removed during normal system operation, e.g. USB devices,
What I wanted to do is give groups of users access to the CD-ROM, floppy and USB devices, without giving everybody access and thereby compromising system security. So I created three groups (with the pw(8) utility); usb, floppy and cdrom, and made the users that were authorized to use these devices members of these groups.
Since I wanted to use cdrecord(1), I had to set up the CD drive commands to go through the CAM interface. To do this, the following devices were set in the kernel configuration:
device atapicam # Emulate ATAPI devices as SCSI via CAM
# Requires scbus and pass
device scbus # SCSI bus (required for SCSI)
device cd # Compact Disc
device da # Direct Access (disks)
device pass # Passthrough device
(The da device is added because it is used for USB mass storage devices, as we'll see later.)
After the new kernel is installed, and the system is rebooted, there will be a couple of new devices ; cdN instead of acdN (N is a number), passN and xpt0. The cdrecord program needs access to those devices to function.
To do that, the following lines are added to /etc/devfs.conf:
/etc/devfs.conf
# /etc/devfs.conf # Time-stamp: <2006-12-02 09:09:45 rsmith> # This is for devices present at boot. See devfs.rules for devices created # at runtime. # Give members of group cdrom access to the CD/DVD-ROM and DVD+RW via the # SCSI interface own xpt0 root:cdrom perm xpt0 0660 own cd0 root:cdrom perm cd0 0660 link cd0 cdrom link cd0 dvd own cd1 root:cdrom perm cd1 0660 # Access to the floppy disk. own fd0 root:floppy perm fd0 0660 # Give cups printer access own lpt0 root:cups perm lpt0 0660
What these commands essentially do is give members of the group cdrom read and write access to the devices necessary to let cdrecord function for a non-root user.
By default, ATAPI devices like CD-ROMs do not use DMA. You can enable DMA at runtime with the atacontrol(8) command. First, run atacontrol list (as root) to see on which channel your ATAPI device is. Say that it's the master on channel 1. Then the next step is to see it's current mode by running atacontrol mode 1. Next you can change the mode by running atacontrol mode 1 UDMA2 XXX. This should set the device to UDMA2, aka UDMA33. See the atacontrol manual page for a list of valid modes. You must specify modes for both master and slave, but XXX is an invalid mode and will be ignored.
To enable DMA for ATAPI devices at boot, add the following to /boot/loader.conf:
hw.ata.atapi_dma="1"
To set permissions etc. for the USB devices that might not be plugged in at boot, we use /etc/devfs.rules. The rules set in this files are processed by the /etc/rc.d/devfs script which uses devfs(8) to put the rules in the devfs system.
I've got a couple of USB mass storage devices that can be accessed via the da(4) driver, and a USB scanner that works with the uscanner(4) driver.
To get these devices to work properly for non-root users (specifically the members of usb group), the following rules are set in /etc/devfs.rules:
/etc/devfs.rules
# /etc/devfs.rules # Time-stamp: <2008-08-08 21:36:28 rsmith> [slackbox_usb=10] add path 'da*' mode 0660 group usb add path 'msdosfs/*' mode 0660 group usb add path 'uscanner*' mode 0660 group usb add path 'usb*' mode 0660 group usb add path 'ugen*' mode 0660 group usb add path 'tap*' mode 0660 group wheel add path 'pass*' mode 0660 group cdrom
The first line assigns a name and number to a set of rules. The devfs(8) command only knows about the number, the name is for convenience in the startup script.
The second line assigns read/write permissions for the group usb to all partitions of USB mass-storage devices.
The third line does the same for scanners.
To activate these settings after the next reboot, a line has to be added to /etc/rc.conf:
# Set the default devfs ruleset. devfs_system_ruleset="slackbox_usb"
The sysctl(8) program allows everybody to examine and root to modify kernel parameters. I have placed the following in my /etc/sysctl.conf file:
/etc/sysctl.conf
# /etc/sysctl.conf # Time-stamp: &tl;2008-12-27 21:49:01 rsmith> # Allow normal users to mount filesystems. vfs.usermount=1 # Speed up disk reads. vfs.read_max=32 # For X kern.ipc.shmmax=67108864 kern.ipc.shmall=32768 # Use pcm1 as default. hw.snd.default_unit=0 dev.pcm.0.play.vchans=4 hw.snd.maxautovchans=4 # Enable port forwarding (for NAT in pf.conf) net.inet.ip.forwarding=1 # Enable network device polling kern.polling.enable=1 # Blackhole against portscanning. net.inet.tcp.blackhole=2 net.inet.udp.blackhole=1 # Do not log fatal signal exits. (from §11.10.4 in the Handbook) kern.logsigexit=0 # More memory for directory hashes. vfs.ufs.dirhash_maxmem=16777216
With the variable vfs.usermount set, normal users are allowed to mount filesystems, provided they own the mount point..
To prevent logins from elsewhere, the following rule has been set as the only rule in the /etc/login.access file:
-:ALL:ALL EXCEPT LOCAL
This means that only local logins are possible. Do not use this if you want to be able to login remotely!
My workstation s configured as a client in /etc/rc.conf:
# PF Firewall pf_enable="YES"
The filtering rules for the pf firewall are contained in /etc/pf.conf:
/etc/pf.conf
# /etc/pf.conf
# Time-stamp: <2008-12-26 12:12:36 rsmith>
# Packet filter configuration for Slackbox.
# Macros: define common values, so they can be referenced and changed easily.
ext_if = "age0"
int_if = "xl0"
# Addresses that can't be routed externally.
# See http://www.rfc-editor.org/rfc/rfc3330.txt
# (10.0.0.138 is my router, so it should be reachable!)
table <unroutable> const { 0.0.0.0/8, 10.0.0.0/8, !10.0.0.138, 127.0.0.0/8, \
169.254.0.0/16, 172.16.0.0/12, 192.0.2.0/24, 192.168.0.0/16, 240.0.0.0/4 }
# Options: tune the behavior of pf.
set optimization normal
set block-policy drop
set loginterface $ext_if
set skip on lo
# Normalization: reassemble fragments etc.
scrub in all
# Translate outgoing packets' source addresses (any protocol).
# In this case, any address but the gateway's external address is mapped.
# The sysctl net.inet.ip.forwarding should be set for this to work.
# Alternatively, set gateway_enable="YES" in /etc/rc.conf.
nat pass on $ext_if inet from $int_if:network to any -> $ext_if
# Filtering
antispoof quick for $int_if
# Nobody gets in from the outside!
block in log quick on $ext_if all label "inblock"
# Block packets to unroutable addresses
block out log quick on $ext_if from any to <unroutable> label "unroutable"
# Block by default. (pass rules dhould follow later).
block out log on $ext_if all label "outblock"
# Internal "network" is trusted.
pass quick on $int_if all flags any no state
# Let outgoing traffic through, and keep state (which is the default now)
# Not using modulate state becaue that seems to be broken.
pass out on $ext_if inet proto tcp all
pass out on $ext_if inet proto udp all
# Let pings through.
pass out on $ext_if inet proto icmp all icmp-type 8 code 0
The setup above is designed for a workstation that has no servers running. Outgoing connection are remembered by the firewall, and it lets incoming packets related to outgoing ones in. Other incoming packets are blocked.
FreeBSD comes with the sensible default of most network daemons disabled (See /etc/defaults/rc.conf).
So if you want e-mail, you'll have to activate sendmail(1) in /etc/rc.firewall, or install and activate another mail daemon. Because I find it easier to configure, I use postfix.
To disable sendmail completely, the following is set in /etc/rc.conf:sendmail_enable="NONE"
Since sendmail(1) is symlinked to mailwrapper(8), we also need to configure the latter to use postfix, by editing /etc/mail/mailer.conf;
/etc/mailer.conf
# # Execute the Postfix sendmail program, named /usr/local/sbin/sendmail # sendmail /usr/local/sbin/sendmail send-mail /usr/local/sbin/sendmail mailq /usr/local/sbin/sendmail newaliases /usr/local/sbin/sendmail
By creating a symbolic link named malloc.conf in /etc, options for the malloc(3) family of library functions can be set. The different options are represented by letters. Capital letters mean that an option is enabled, while lowercase mean that an option is disabled.
# cd /etc; ln -s 'ajHR' malloc.conf
To reduce the power usage and temperature of my system when it's idling I've enabled powerd(8) in it's default adaptive mode. This is done in two steps.
First, the cpufreq(4) device has to be included in the kernel configuration;
# Control CPU frequency. device cpufreq
After rebuilding and installing the kernel, powerd has to be enabled in /etc/rc.conf:
# Enable power monitoring. powerd_enable="YES"
The smartd(8) daemon monitors the health of SMART capable harddisks. This will warn you before a harddisk fails, so you can make a backup and replace it before you loose your data. It is part of the smartmontools package (in /usr/ports/sysutils), so you have to install that first.
Now a config file, /usr/local/etc/smartd.conf will need to be written. Below is the relevant part of mine:
/dev/ad4 -o on -s (S/../.././02|L/../../6/04) -H \ -l error -l selftest -t -I 194 -I 9 \ -M exec /usr/bin/mail -m rsmith@localhost /dev/ad6 -o on -s (S/../.././03|L/../../6/05) -H \ -l error -l selftest -t -I 194 -I 9 \ -M exec /usr/bin/mail -m rsmith@localhost
It is important to use the "-M exec" parameter, because smartd assumes /bin/mail, which doesn't exist on FreeBSD. See the smartd.conf(5) manual page for the meaning of the parameters.
By default, most disk drives cache writes in internal memory before actually committing them to the disk.
This behaviour can make it more likely to trigger inconsistencies on a filesystem using soft updates in case of a power failure. Therefore I have disabled this feature by writing the following in /boot/loader.conf;
# Set ata devices to write-through cache. hw.ata.wc="0"
Cursors are themable in Xorg now. I like the redglass theme myself. To implement it, I set the following in my ~/.xinitrc file:
export XCURSOR_THEME=redglass
Additionally, I set the following in my ~/.Xresources file:
! Cursor theme Xcursor.theme: redglass
This might not be necessary. Most apps work fine with just the environment variable set.
But Firefox displays the old black/white watch cursor when loading a page. Apparently this is because it's looking for a cursor name that doesn't exist. The following will fix this:
# cd /usr/local/lib/X11/icons/redglass/cursors # ln -s left_ptr_watch 08e8e1c95fe2fc01f976f1e063a24ccd
This will make Firefox use the left_ptr_watch cursor, which is the normal left_ptr cursor with a blinking watch. You can of course use any of the other cursor to link to, if you like.
The same fix can of course be applied to other cursor themes as well.
Instead of a mouse, I prefer using a trackball. But a lot of trackballs are not usable for left-handed people like myself. The one I'm currently using is a Kensington Expert Mouse®. I like it because it has four buttons and a scroll-ring.
To use this trackball with the Xorg server, I put the following in xorg.conf;
Section "InputDevice"
Identifier "ExpertMouse"
Driver "mouse"
Option "Protocol" "Auto"
Option "Device" "/dev/psm0"
Option "Buttons" "6"
Option "ZAxisMapping" "4 5"
Option "ButtonMapping" "3 2 1"
Option "CorePointer" "on"
EndSection
The device /dev/psm0 is specific for FreeBSD. Linux users will want to use /dev/mouse.
The ButtonMapping option is used to switch buttons one and three because I'm left-handed. With this option, the button on the lower-right is button one, lower-left is button three and top-left is button two. Rotating the scroll-ring clockwise is button five, anti-clockwise is button four.
It is essential to make good backups. Disks can fail, operators will make errors, and without backups you will lose data!
Essentially there are two kinds of backups, disaster recorvery and archival storage. In this case I'm more concerned with the former than with the latter, since I keep all my data live on disk where I can reach it.
There are a myriad of applications for making backups, and there are many backup media. On this page, I will only touch on the method and media that I currently use.
My first line of defence is to have two identical disks in the machine. The first one (ad4) is normally used, while the second one (ad6) is a copy which is updated nightly by rsync(1) is a cron(8) job. I tried using gmirror(8), but that felt slow, and rebuilding the array took days.
Having two disks doesn't protect against calamities like fire or theft. So one should consider making backups and storing them away from the PC.
There are a few features that a backup program should have;
In the /rescue directory of both the FreeBSD base system and the install CD, you'll find statically linked binaries of restore(8) (for restoring backups made by dump(8)), tar(1) and pax(1). But only dump(8)/restore(8) is guaranteed to fullfill the second requirement on UFS2 filesystems. So that is what I use for system partitions.
The bulk of my data is in my /home partition. Things like holiday photos, scans and MP3 files take up a lot of space but change infrequently. Therefore I felt that a weekly level 0 backup was inappropriate for this partition.
The other important consideration is backup media. Traditionally, backups were made on magnetic tape. But tape drives are expensive, and their capacity has not kept up with modern disk sizes. A dump of a large partition can also easily be larger than a recordable DVD. And although it's possible to split dump output into DVD-sized chunks, it is an extra complication. Therefore I use a couple of disks in USB enclosures. Their size is sufficient to store complete backups. They are easy to use and store in a vault or off-site.
Next question is what to back up. It is customary to divide the disk into several partitions. Here is my break-up;
$ df -h Filesystem Size Used Avail Capacity Mounted on /dev/ad4s1a 484M 270M 175M 61% / devfs 1.0K 1.0K 0B 100% /dev /dev/ad4s1g.eli 373G 69G 274G 20% /home /dev/ad4s1e 48G 6.6G 38G 15% /tmp /dev/ad4s1f 19G 5.0G 13G 28% /usr /dev/ad4s1d 1.9G 1.1G 718M 61% /var
The /dev filesystem in FreeBSD is filled by the OS, so it doesn't have to be backed up. The /tmp filesystem is only used for temporary storage, so it doesn't need to be backed up either.
So the filesystems that need to be backed up in my case are /, /home, /usr and /var. On can summarize those as all UFS filesystems except /tmp.
If your disk has died, you need to re-partition and newfs your new disk to match the old one. To that end, one should always store a copy of /etc/fstab and the output of the bsdlabel command;
# bsdlabel /dev/ad4s1 # /dev/ad4s1: 8 partitions: # size offset fstype [fsize bsize bps/cpg] a: 1024000 16 4.2BSD 2048 16384 64008 b: 16777216 1024016 swap c: 976768002 0 unused 0 0 # "raw" part, don't edit d: 4194304 17801232 4.2BSD 2048 16384 28528 e: 104857600 21995536 4.2BSD 2048 16384 28528 f: 41943040 126853136 4.2BSD 2048 16384 28528 g: 807971826 168796176 4.2BSD 2048 16384 0
Another thing that is handy to save, is the output of the 'dumpfs -m' command for all of your partitions. This gives you the newfs command to recreate the partitions in question
# dumpfs -m / # newfs command for / (/dev/ad4s1a) newfs -O 2 -a 8 -b 16384 -d 16384 -e 2048 -f 2048 -g 16384 -h 64 -m 8 -o time -s 256000 /dev/ad4s1a # dumpfs -m /home # newfs command for /home (/dev/ad4s1g.eli) newfs -O 2 -U -a 8 -b 16384 -d 16384 -e 2048 -f 2048 -g 16384 -h 64 -m 8 -o time -s 201992956 /dev/ad4s1g.eli # dumpfs -m /usr # newfs command for /usr (/dev/ad4s1f) newfs -O 2 -U -a 8 -b 16384 -d 16384 -e 2048 -f 2048 -g 16384 -h 64 -m 8 -o time -s 10485760 /dev/ad4s1f # dumpfs -m /var # newfs command for /var (/dev/ad4s1d) newfs -O 2 -U -a 8 -b 16384 -d 16384 -e 2048 -f 2048 -g 16384 -h 64 -m 8 -o time -s 1048576 /dev/ad4s1d
My method of choice is to use dump(8) to make backups to a USB disk for the system partitions, and use rsync(1) for /home.
The usb disk is devided into a single slice, with two partitions, as described in the USB disk section.
First, the system partitions are backed up;
# rm -rf /usr/obj/* # src/scripts/dodumps 0 /tmp # mount /dev/da0s1a /mnt/root # rm -f /mnt/root/*.dump # cp -vp /tmp/*.dump /mnt/root # umount /mnt/root
Then the encrypted partition is mounted and the /home partition is syncronized;
# geli attach /dev/da0s1d # mount /dev/da0s1d.eli /mnt/root # rsync -axq --delete /home/ /mnt/root/home # sync # umount /mnt/root # geli detach /dev/da0s1d.eli
This file is read (via sys.mk) by make(1) every time it runs. It follows makefile syntax and is used to set variables for make.
There are variables that are used for configuration of the system during a 'make buildworld' or 'make kernel'. These will be covered first.
In 7.x part of the system configuration was moved to a separate file, src.conf.
It is also possible to set variables only when building in a specific directory. This is used for configuring ports(7).
Following is an annotated example of settings I've put in my make.conf. They are listed here as examples only. Do not senselessly copy them! They will probably not be correct for your system and might ruin it when you use them. You have been warned!
The first thing I specify is the type of CPU that the system should be built for.
# Type of CPU the system is built for. CPUTYPE=athlon64
I'm running the amd64 version of FreeBSD on my Athlon64 based computer. Do not copy this setting unless you know that it is correct! Reading /usr/share/mk/bsd.cpu.mk gives you an idea what types are available, and what they do.
Next is defining the kernel configuration.
# Kernel configuration KERNCONF=RFS
I've placed a file called RFS in the directory /usr/src/sys/amd64/conf. This file contains a description of which drivers and features I want the kernel to contain. In general, you should place your kernel configuration file (if you don't want to use the standard kernel named GENERIC) in /usr/src/sys/[arch]/conf, where [arch] is the machine architecture of your system. For most people this should be i386.
Moving on to documentation. To save on disk space, and because it is probably the most complete, I only install the English documentation.
# Documentation languages DOC_LANG=en_US.ISO8859-1
The following was added when the perl port was installed. Do not remove these.
# added by use.perl 2006-05-10 18:26:02 PERL_VER=5.8.8 PERL_VERSION=5.8.8
The following variables are used to configure certain ports. You can specify these variables when you invoke make to build a port, but this way you can't forget them.
A lot of ports use options these days. This presents you with a nice dialog where you can select features that you want in a port. But not all ports have been option-ized, and some things cannot be set with the options mechanism. To see what variables you can set, look through /usr/ports/[category]/[portname]/Makefile.
The statements like .if ${.CURDIR:M*/foo/bar mean that if make is invoked in a directory that ends in foo/bar, it should set the variables named in the .if/.endif block.
# Flags for different ports
.if ${.CURDIR:M*/print/cups*}
CUPS_OVERWRITE_BASE=true
.endif
.if ${.CURDIR:M*/x11/rxvt-unicode}
WITHOUT_IMLOCALE_FIX=yes
WITHOUT_PERL=yes
WITHOUT_UNICODE3=yes
WITHOUT_MENUBAR=yes
WITHOUT_RXVT_SCROLLBAR=yes
WITHOUT_NEXT_SCROLLBAR=yes
WITHOUT_XTERM_SCROLLBAR=yes
WITHOUT_PLAIN_SCROLLBAR=yes
WITHOUT_BACKSPACE_KEY=yes
WITHOUT_DELETE_KEY=yes
WITHOUT_LINESPACE=yes
WITHOUT_TERMINFO=yes
WITHOUT_AFTERIMAGE=yes
.endif
.if ${.CURDIR:M*/multimedia/ffmpeg}
WITH_FREETYPE2=yes
WITH_MP3=yes
WITH_OPTIMIZED_CFLAGS=yes
WITHOUT_FFMPEG_FFSERVER=yes
.endif
.if ${.CURDIR:M*/mail/mutt-devel}
WITH_MUTT_SLANG2=yes
WITHOUT_MUTT_HTML=yes
WITHOUT_MUTT_XML=yes
WITHOUT_MUTT_COMPRESSED_FOLDERS=yes
WITHOUT_NLS=yes
NOPORTDOCS=yes
.endif
.if ${.CURDIR:M*/graphics/povray}
WITH_OPTIMIZED_FLAGS=yes
.endif
.if ${.CURDIR:M*/multimedia/mplayer}
WITH_DVD_DEVICE=/dev/cd0
WITH_CDROM_DEVICE=/dev/cd0
.endif
.if ${.CURDIR:M*/math/octave}
WITH_BLAS=yes
.endif
.if ${.CURDIR:M*/sysutils/conky}
WITH_XFT=yes
.endif
.if ${.CURDIR:M*/graphics/xd3d}
WITHOUT_GIFSICLE=yes
.endif
.if ${.CURDIR:M*/print/ghostscript*}
A4=yes
BATCH=yes
.endif
.if ${.CURDIR:M*/editors/emacs*}
WITHOUT_GTK=yes
.endif
.if ${.CURDIR:M*/security/pinentry}
PINENTRY_GTK2=yes
.endif
.if ${.CURDIR:M*/security/isomaster}
WITHOUT_NLS=yes
.endif
.if ${.CURDIR:M*/devel/git}
WITHOUT_GUI=yes
.endif
.if ${.CURDIR:M*/lang/gcc*}
WITHOUT_JAVA=yes
.endif
.if ${.CURDIR:M*/x11-servers/xorg-server}
WITHOUT_HAL=yes
.endif
In 7.x, most of the base system configuration has been moved to src.conf, as not to interfere with building ports.
Below is my src.conf as an example. Do not copy this to your system, but read src.conf(5) and figure out what you should use.
# /etc/src.conf # Time-stamp: <2007-10-26 08:20:46 rsmith> WITHOUT_ATM=true WITHOUT_BLUETOOTH=true WITHOUT_CDDL=true WITHOUT_I4B=true WITH_IDEA=true WITHOUT_IPFILTER=true WITHOUT_IPX=true WITHOUT_LIB32=true WITHOUT_LIBKSE=true WITHOUT_LPR=true WITHOUT_NCP=true WITHOUT_PROFILE=true WITHOUT_RCMDS=true WITHOUT_SENDMAIL=true
After I had a computer of mine stolen, I decided to better secure my data. To that end switched over to encrypted backup disks, and an encrypted /home partition. Since most computer users wouldn't know what to do with a UFS partition, one can debate if this is necessary. But it does protect your data against more sophisticated attackers.
I didn't bother encrypting more partitions, although one could make the case that /tmp and /var should be encrypted as well.
What is commonly known as partitions are called slices in FreeBSD, because of it's UNIX heritage which predates the PC. In FreeBSD a partition is a subdivision of a slice. For instance, the /dev/ad0s1d device is the 'd' partition on the first slice 's1' of the first disk 'ad0'.
For backups, I use an external harddisk with a USB connection. This device uses the umass driver, which in turn needs the scbus and da devices.
This disk has a single BSD slice, devided into two partitions. The first 20BG partition (da0s1a) is for the dumps of /, / usr a /var. The rest of the disk is a geli(8) encrypted partition (da0s1d.eli) to store data from home.
# fdisk -I /dev/da0 # bsdlabel -w /dev/da0s1 # setenv EDITOR /usr/bin/ee # bsdlabel -e /dev/da0s1
The EDITOR variable is set to a somwhat friendlier editor then the default vi(1)!
Next, the slices are made.
# /dev/da0s1: 8 partitions: # size offset fstype [fsize bsize bps/cpg] a: 20971520 16 4.2BSD 2048 16384 28528 c: 488392002 0 unused 0 0 # "raw" part, don't edit d: 467420466 20971536 4.2BSD 0 0 0
The d partition is encrypted;
# geli init -l 256 /dev/da0s1d # geli attach /dev/da0s1d
for better security, I then filled the second partition with random data;
# dd if=/dev/random of=/dev/da0s1d bs=32k
After that, I initialised GEOM_ELI for that partition with geli(8), and attached it;
# geli init -l 256 /dev/da0s1d # geli attach /dev/da0s1d
The initialization needs to be done only once. Attaching must be done to to create the /dev/da0s1d.eli device. The 'geli init' command will ask you to choose a password, and confirm it. Attaching a device also asks for the password.
Now that the devices exists, we can create filesystems on it;
# newfs -U /dev/da0s1a # newfs -U /dev/da0s1d.eli
During system install, I chose to put /home on a separate partition. It is currently not possible to create encrypted filesystems with sysinstall(8). So this has to be done afterwards.
If you want to use encrypted filesystems, you'll need the initialization scripts /etc/rc.d/geli and /etc/rc.d/geli2. They are present in 6.x.
The first step is to make a level 0 dump of /home if you have any data on it. This dump should be put on another partition, since the partition for /home will be completely overwritten in the process. Look into /etc/fstab to see which device /home is on;
/dev/ar0s1g /home ufs rw 2 2
Now it is time to completely log out all normal users, and login as root. Next unmount /home.
# umount /home
If the GEOM_ELI device is not compiled into the kernel, make sure that it is loaded as a module.
# kldload geom_eli.ko
To make sure that this module is loaded after the next reboot, add the following to /boot/loader.conf. Again, you only need to do this when GEOM_ELI isn't compiled into the kernel;
geom_eli_load="YES"
As the next step we overwrite the partition with random data, to make the encrypted filesystem data harder to spot.
# dd if=/dev/random of=/dev/ar0s1g bs=32k
At this point it might still be possible to retrieve the previous contents of the filesystem. So if you're really paranoid, you'll want to wipe the partition before writing the random data.
The next steps are to initialize, attach and mount the encrypted device.
# geli init -l 256 /dev/ar0s1g # geli attach -d /dev/ar0s1g # newfs -U /dev/ar0s1g.eli # mount /dev/ar0s1g.eli /home
At the next boot, the system will ask you for the password for the encrypted partition, before you log in.
Most of the additional software on my system is installed via the ports system. If you want to install a piece of additional software, look if it's in ports first!
TeXLive is a very feature-rich and well-integrated TeX distribution. It contains more that the standard teTeX distribution in ports, so I choose to install this.
First I installed the system files from the CD that I got as an NTG member. It includes a shell-script to install things. The base directory that I used was /usr/local/share/tex/.
Because the TeXLive distribution does not come with FreeBSD amd64 binaries (it has i386 binaries, though) I had to compile the system myself, which was not very hard.
First, the source code is unpacked and configured:
$ cd tmp/ $ mkdir foo; cd foo $ tar xvzf source.tar.bz2 $ ./configure --prefix=/usr/local/texlive/2005 --without-dvi2tty --without-omega --without-musixflx --without-omega --enable-ipc --with-system-ncurses --with-system-pnglib --with-system-t1lib --with-system-zlib --with-system-gd --with-system-freetype
The build failed for omega, which I don't use anyway, so I patched TeX/texk/web2c/Makefile to disable it:
--- Makefile.orig Tue Feb 28 01:10:46 2006
+++ Makefile Tue Feb 28 01:22:05 2006
@@ -1143,10 +1143,10 @@
Makefile: omegadir/omega.mk
-omegafonts_programs = omegafonts/omfonts
-otps_programs = otps/otp2ocp otps/outocp
-omegafonts = omegafonts
-otps = otps
+#omegafonts_programs = omegafonts/omfonts
+#otps_programs = otps/otp2ocp otps/outocp
+#omegafonts = omegafonts
+#otps = otps
odvicopy = odvicopy
odvitype = odvitype
@@ -1155,7 +1155,7 @@
omegaware_programs = $(otangle) $(odvicopy) $(odvitype)
omega_programs = $(omega) $(otangle) $(odvicopy) $(odvitype) \
- $(otps_programs) $(omegafonts_programs)
+ #$(otps_programs) $(omegafonts_programs)
# The otangle used in the build is not be the otangle we build if we are
# cross-compiling.
@@ -1336,12 +1336,12 @@
# ^L
# Some additional programs for Omega: the programs themselves are named
# in the variable otps_programs, defined above.
-otps/otp2ocp:
- cd otps && $(MAKE) $(common_makeargs) otp2ocp
+#otps/otp2ocp:
+# cd otps && $(MAKE) $(common_makeargs) otp2ocp
otps/outocp:
cd otps && $(MAKE) $(common_makeargs) outocp
-omegafonts/omfonts:
- cd omegafonts && $(MAKE) $(common_makeargs) omfonts
+#omegafonts/omfonts:
+# cd omegafonts && $(MAKE) $(common_makeargs) omfonts
# ^L
# Installation.
install-omega: install-omega-exec install-omega-data
@@ -1354,11 +1354,11 @@
install-omega-programs: $(omega_programs) $(bindir)
for p in omega; do $(INSTALL_LIBTOOL_PROG) $$p $(bindir); done
cd otps && $(MAKE) $(install_makeargs) install-programs
- cd omegafonts && $(MAKE) $(install_makeargs) install-programs
+ #cd omegafonts && $(MAKE) $(install_makeargs) install-programs
install-links: #! install-omega-links
install-omega-links: install-omega-programs
- cd omegafonts && $(MAKE) $(install_makeargs) install-links
+ #cd omegafonts && $(MAKE) $(install_makeargs) install-links
#cd $(bindir) && (rm -f iniomega viromega; \
# $(LN) omega iniomega; $(LN) omega viromega)
@@ -1905,7 +1905,7 @@
$(pdftex) $(pdfetex)
programs: $(programs) $(engines) $(mpware_programs) \
- $(omegafonts_programs) $(otps_programs) $(pdftosrc)
+ $(otps_programs) $(pdftosrc)
# Additional dependencies for relinking.
# Note that each program and engine already depends on $(web2c_programs).
@@ -2555,7 +2555,7 @@
# ^L
# Cleaning.
-all_subdirs = doc lib man $(mpware) web2c window $(omegafonts) $(otps) $(pdftex
dir) $(pdfetexdir)
+all_subdirs = doc lib man $(mpware) web2c window $(otps) $(pdftexdir) $(pdfetex
dir)
# Having a multiple-target rule with the subdir loop fails because of
# the dependencies introduced by clean.mk. Yet, we want the
Use gmake instead of the normal make, otherwise the build will fail. Of course the ports png and t1lib should be installed first;
$ gmake $ su # gmake install
To use the binaries, I had to add /usr/local/texlive/2005/bin/x86_64-unknown-freebsd6.0 to the path of the default class in /etc/login.conf.
To make it all work correctly, I had to stop TeX from trying to use the Omega fonts. To do that, I copied /usr/local/texlive/2005/texmf/web2c/updmap.cfg to /usr/local/texlive/2005/texmf-var/web2c/updmap.cfg and removed the line
Map omega.map
After that I had to run updmap as root to make TeX aware of the change.
By default, a lot of hyphenations are enabled in TeXLive. I used texconfig(1) to disable the ones I don't use.
As described on my desktop page, I'm using torsmo to display system data. But I also wanted some graphs of system temperatures and network traffic.
The process of creating and displaying these graphs is divided in multiple steps:
For generating a temperature graph, steps one and two are combined in a shell-script called tempmon.sh, which is called every minute as a cron(8) job. This script uses mbmon(1), part of the xmbmon package, to collect temperature data. Using grep(1) and cut(1) the relevant data is selected from the mbmon(1) output, and then written to a file. The file is limited to 60 lines, representing data for the last hour. The gnuplot(1) program is then used to make a graph of the data. The background color of the graph matches the desktop background, and the graph colors match those used in my torsmo(1) setup. An example is displayed below.
Data about the network usage is gathered by pfstat(8) running every minute as a cron(8) job. Its output is written to /var/log/pfstat. The netdata.pl script selects the appropriate portions of the /var/log/pfstat file, and converts the absolute byte counts to average kB/s values. It writes two files; one containing the data for the last hour, and one containing the data for the last day. With the instructions contained in netplot.gp, data files are then used by gnuplot(1) to generate two graphs. One of stacked bar graph of incoming and outgoing bytes over the last hour. The second of combined network traffic over the last 24 hours. Examples of both graphs are shown below:
The data-gathering scripts are run every minute via cron:
# Crontab for root. # Time-stamp: <2006-07-25 09:28:10 rsmith> #minute hour mday month wday command PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin MDDIR=/usr/local/share/monitor MAILTO=rsmith #<monitor> Log data from pf every minute. pfstat version 1.7! * * * * * pfstat -q >>/var/log/pfstat # <monitor> Limit the size of the logfile. 1 1 * * 1 tail -n 20000 /var/log/pfstat >/tmp/pfstat; mv /tmp/pfstat /var/log/pfstat # <monitor> Graph the network data every minute * * * * * perl $MDDIR/netdata.pl; gnuplot $MDDIR/netplot.gp # <monitor> Gather and graph CPU and case temperature data every minute. * * * * * sh $MDDIR/tempmon.sh
The graphs are displayed on the desktop by telak, started via ~/.xinitrc. The configuration to show the graphs is as follows:
[temp] url = /usr/tmp/temp.png width = 300 height = 150 x = 0 y = 160 refresh = 60 [net_hour] url = /usr/tmp/net_hour2.png width = 300 height = 150 x = 0 y = 320 refresh = 60 [net_day] url = /usr/tmp/net_day2.png width = 300 height = 150 x = 0 y = 480 refresh = 60
The result is that the graphs fit well into the desktop. See my desktop page.