Roland's FreeBSD configuration page |
|
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 useful for others. These settings were started for FreeBSD 5.3 on amd64, but have been continuously updated to 8.0-RELEASE.
To keep track of things, I keep configuration files (including the kernel configuration) under revision control with git. This is explained on my configfiles page.
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 tool lpadmin(8) 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 HDA compatible sound chip (Realtek ALC662) on board. 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) on 6.x, 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 was 4096 bytes).
hint.pcm.0.buffersize="16384"
This was sufficient to fix the problem. N.B., as of 7.x this should not be necessary anymore, because the default buffer size has increased.
The sound driver is able to combine sounds from different sources and output then through one device. This is activated in sysctl.conf by setting the number of virtual channels or vchans, see sound(4).
My ADSL connection goes through a Thompson 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 something like this.
My aforementioned motherboard has a Attansic/Atheros L1 ethernet chip on-board. I also have an extra PCI ethernet card, an Realtek 8139. To enable these, I added the following to my kernel configuration file:
# PCI ethernet device
device miibus
device age # Attansic/Atheros L1 Gigabit Ethernet
device rl # RealTek 8129/8139
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_rl0="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 age0 interface can be freely chosen from the 10.0.0.x address range. This Just Works™.
Since 5.3 FreeBSD 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(1) 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. See also devfs.conf(5) and devfs.rules(5).
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 to write CDs, and growisofs to write DVDs, 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.) As far as I know, these cannot be loaded as modules.
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:
# 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
own cd1 root:cdrom
perm cd1 0660
link cd1 cdrom
link cd1 dvd
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 scanner that works via the ugen(4) driver and libusb(3).
Note: Prior to 8.0, USB connected scanners used the uscanner(4)* *driver. This has been removed in 8.x.
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:
[slackbox_usb=10]
add path 'da*' mode 0660 group usb
add path 'msdosfs/*' mode 0660 group usb
add path 'usb/*' mode 0660 group usb
add path 'ugen*' mode 0660 group usb
The first non-comment 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 all usb devices. Note that in 8.x USB devices
appear in the subdirectory /dev/usb/ instead of directly under /dev/. The
ugen devices in 8.x are just links to devices in /dev/usb/.
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
# Time-stamp: <2009-11-29 13:46:44 rsmith>
# $Id: 69f0add3e942705a44942b5ba18be53adaf08d49 $
# 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
# 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
# Disallow memory mapping at the NULL address.
security.bsd.map_at_zero=0
As usual with configuration files, lines starting with a ‘#’ are comments.
With the variable vfs.usermount set, normal users are allowed to mount
filesystems, provided they own the mount point. Setting vfs.read_max can
increase read speeds. I did some testing and discovered that a value of 32
seemed about right for my setup. You can find the meaning of any sysctl by
using the -d option of the sysctl(8) command.
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! See login.access(5).
My workstation is configured to run the pf firewall. This is done 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
# Time-stamp: <2009-11-14 17:07:18 rsmith>
# $Id: e120d78e3c04413c9a1cb8b882eeda8651e9d12d $
# Packet filter configuration for Slackbox.
# Macros: define common values, so they can be referenced and changed easily.
ext_if = "age0"
int_if = "rl0"
# 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 should 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 and dropped.
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 in /etc/rc.conf, or install and activate another mail transfer agent. Because I find it easier to configure, I prefer 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;
#
# 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. I used the following command;
# 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"
powerd_flags="-n hiadaptive -a hiadaptive"
The powerd_flags is used to set the options for powerd(8). The setting I use
were chosen to get the CPU to slow down sooner.
The smartd(8) daemon monitors the health of SMART capable hard disks. This
will warn you before a hard disk 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 behavior can make it more likely to trigger inconsistencies on a filesystem using soft updates in case of a power failure. One can disable this feature by adding the following in /boot/loader.conf;
# Set ata devices to write-through cache.
hw.ata.wc="0"
There is a performance penalty associated with this, though.
If you have more than one FreeBSD machine, keeping the ports on them up-to-date means more work. There is a way around this, but it requires that the machines in question are running the same hardware architecture and major OS version, e.g. amd64 8.x. As a consequence of this method, all machines will have the same ports installed. I find that useful myself.
If this is the case, you can use the fastest machine to build ports, then distribute them to other machines with rsync(1).
Here is what I do to keep the ports on my laptop in sync with my desktop. Both are running 8.0-RELEASE amd64. Running the same minor release isn’t critical. Just make sure that the architecture and major release are the same. The faster desktop is used as the build machine.
portsnap fetch updateportmaster -a -B -drsync --daemon’ on the laptop.rsync -av --delete /usr/local/ laptop::local’The laptop has the following in /usr/local/etc/rsyncd.conf:
[local]
path = /usr/local
comment = usr/local directory tree
uid = root
gid = wheel
read only = false
If you don’t mind losing the ability to build ports on the dependent machines,
you can remove the directories /usr/ports, /var/db/ports and /var/db/pkg
on those machines, as I’ve done on the laptop.
The file make.conf(5) 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(5).
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 just 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=nocona
I’m running the amd64 version of FreeBSD on my Core2 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=QUADSLACK
I’ve placed a file called QUADSLACK 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 or
amd64. To build your own kernel configuration, start off with making a copy
of the GENERIC config for your FreeBSD version and architecture, and edit
that.
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 are added or updated when the perl port is installed of updated. Do not remove these!
# added by use.perl 2009-09-13 09:22:46
PERL_VERSION=5.10.1
Ports are applications that have been ‘ported’ to FreeBSD. I.e, someone has figured out where to download the source, and how to compile (with modifications, if necessary) and install it successfully. This knowledge is saved as instructions for the system to repeat that. This system also takes care on installing any prequisites. This is one of the main selling points of FreeBSD, in my opinion.
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} means that if make is invoked
in a directory that ends in foo/bar, it should set the variables named in
the .if/.endif block.
.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/cd1
WITH_CDROM_DEVICE=/dev/cd1
.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*/sysutils/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}
WITH_OPENSSL_BASE=yes
.endif
.if ${.CURDIR:M*/cad/calculix}
# Add 'WITH_EXAMPLES=YES' to the command-line when running make install.
#WITH_EXAMPLES=YES
BROWSER=firefox
WITH_BLAS=YES
CCX_NPROC=4
.endif
.if ${.CURDIR:M*/math/arpack}
WITH_BLAS=YES
.endif
.if ${.CURDIR:M*/math/taucs}
WITH_BLAS=YES
.endif
.if ${.CURDIR:M*/print/freetype2}
WITH_LCD_FILTERING=YES
.endif
.if ${.CURDIR:M*/shells/bash}
NOPORTDOCS=YES
WITHOUT_NLS=YES
WITHOUT_HELP=YES
.endif
.if ${.CURDIR:M*/editors/openoffice.org-*}
WITHOUT_MOZILLA=YES
WITHOUT_GNOME=YES
WITH_SYSTEM_ICU=YES
WITH_GPC=YES
.endif
In 7.x, most of the base system configuration has been moved to /etc/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: <2009-11-27 14:45:31 rsmith>
# $Id: a0441bcb84fe0f95886115e2670bf2257bfa8890 $
WITHOUT_ACCT=true
WITHOUT_AMD=true
WITHOUT_APM=true
WITHOUT_ATM=true
WITHOUT_AUDIT=true
WITHOUT_BLUETOOTH=true
WITHOUT_CDDL=true
WITHOUT_CTM=true
WITHOUT_CVS=true
WITHOUT_FLOPPY=true
WITHOUT_FREEBSD_UPDATE=true
WITHOUT_GCOV=true
WITHOUT_GDB=true
WITHOUT_GPIB=true
WITHOUT_I4B=true
WITH_IDEA=true
WITHOUT_INET6=true
WITHOUT_IPFILTER=true
WITHOUT_IPX=true
WITHOUT_LPR=true
WITHOUT_NDIS=true
WITHOUT_NETGRAPH=true
WITHOUT_OBJC=true
WITHOUT_PPP=true
WITHOUT_PROFILE=true
WITHOUT_QUOTAS=true
WITHOUT_RCMDS=true
WITHOUT_SENDMAIL=true
WITHOUT_SSP=true
WITHOUT_TELNET=true
Note that this configuration file only regulates which part of the system is built and installed. It does not remove old binaries and libraries! The reason for that is because the system cannot know with certainty which files are to be removed.
Discovering and removing old binaries is covered in my miscellaneous page
—– Copyright © 2010, Roland Smith rsmith@xs4all.nl

This <span
xmlns:dc=“http://purl.org/dc/elements/1.1/”
href=“http://purl.org/dc/dcmitype/Text” rel=“dc:type”>work is licensed
under a Creative Commons
Attribution 3.0 Unported License