Installing FreeBSD 5

As part of learning about FreeBSD, I installed it a great many times. To facilitate these installations and later maintenance, I've tried to create, document, and script simple procedures so I can be sure I do it right the next time. This page is my effort to share the procedure I've gradually developed with others (and myself, for my next round).

This page documents a procedure for building a FreeBSD system from scratch, with most of the obligatory detail work saved into files for reuse; I've tried to document the rest, and provide the specific commands in the page, for copy & paste. My goal is to have a simple and low-effort procedure for bringing up a new server with a rich set of services.

Additionally, I'd like to be able to trust portupgrade -ai (upgrade all ports, with confirmation), which requires some local configuration in pkgtools.conf. My goal is to use cvsup.sh && build-world-kernel.sh, and have the system remind me what to do next to complete the installation with as little effort as practical.

This document is not a beginner's tutorial. There's very little explanation of what is going on, mostly due to time constraints, but also because it's intended as a reference for working efficiently -- a lot of verbiage would get in the way. If you're not familiar with the commands and concepts here, I suggest getting a disposable desktop and reading the excellent FreeBSD Handbook. After you've successfully installed FreeBSD, upgraded your kernel, and installed a couple ports, this page can hopefully provide some useful tips for maintaining your system and working with ports.

You should also be aware of the instant-server and instant-workstation meta-ports, which incorporate suggested slates of services and desktop applications, respectively. Specifically, if you type cd /usr/ports/misc/instant-workstation && make, your system will attempt to install a variety of useful software automatically (it will take a while!). The instructions here cover some of the same territory as these ports, but also a great deal of other material.

I'm not writing an actual script to do this stuff, since it changes over time with upgrades and I'm not deploying on a large number of systems. Instead, my goal is to be simple and avoid assumptions; thus in several places the document says to vi somefile, leaving the details unspecified. I provide examples where feasible, but in each such situations you'll have to decide (with or without my suggestions) what to actually enter.

Note: $myself and $hostname, used below, aren't intended as actual shell variables. Where you see them in the text, enter the correct information for your own situation. Postfix does use variables directly in main.cf, though -- the (un-italicized) variable names in the Postfix configuration are literal variable names which should be entered directly, so Postfix can do its own variable substitution.

Note: The files used for this procedure are intended to be fairly generic, and include a variety of suggestions I've come up with in my own use of FreeBSD. This means they aren't customized or optimized for your needs or systems, but should provide useful starting points for your own customization. I suggest downloading http://www.reppep.com/~pepper/freebsd/install/reppep.tgz, reviewing and adjusting to suit your own needs, and then copying to /root/reppep to continue with the procedure here, saving your tweaked copies on another system so they're available next time.

FreeBSD 5 does service startup a bit differently than 4; the details are available at http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/configtuning-rcng.html.

Base Install (sysinstall)

  1. Install the full distribution ("All system sources, binaries and X Window System").
  2. Install the ports collection.
  3. Configure the network.
  4. Recommended packages:
  5. Note: If you want each user to have its own personal groups (Linux & Panther style), create the new groups first in sysinstall. Make sure any administrative accounts have group 0 (wheel) membership -- otherwise su will be unavailable.

Accounts & Basic Setup

  1. Enable serial console: echo "-hD" > /boot.config # "man boot" for details
  2. If you didn't enable serial terminal in sysinstall, do it now: echo 'ttyd0 "/usr/libexec/getty std.9600" vt100 on secure' >> /etc/ttys
  3. visudo # uncomment full access for %wheel
  4. cd /root && ftp http://www.reppep.com/~pepper/freebsd/install/reppep.tgz && tar xzf reppep.tgz && ls -lt reppep # get recommended additions & patches, and unpack as /root/reppep
  5. If you have local patches, unpack them too: tar xzf local.tgz && ls -lt reppep
  6. patch /etc/ssh/sshd_config /root/reppep/sshd_config.diff
  7. Install your custom kernel configuration file in /usr/src/sys/i386/conf (if you have one).
  8. cd /etc && cp /root/reppep/make.conf . && cat /root/reppep/rc.conf* >> rc.conf && vi resolv.conf rc.conf make.conf && egrep -v '(^$|^#)' rc.conf | sort | more # put your own customizations in rc.conf.local; make sure no variables are defined twice in rc.conf
  9. mkdir -p /usr/sup && cp /root/reppep/cvsupfile /root/reppep/rc.firewall.local /root/reppep/periodic.conf /root/reppep/ntp.conf /etc && cp /root/reppep/refuse /usr/sup && vi /etc/cvsupfile /etc/ntp.conf /usr/sup/refuse
  10. mkdir -p ~root/bin ~root/log
  11. cd /root/reppep && cp build-world-kernel.sh cvsup.sh /root/bin && chmod u+x /root/bin/*.sh && rehash
  12. mkdir -p /var/log/pkgtools && patch /usr/local/etc/pkgtools.conf /root/reppep/pkgtools.conf.diff
  13. adduser -C

Upgrade Source, Kernel & World (do this periodically)

Note: The official recommendation, described at http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html, is a bit more involved but safer. If you're not clear on the differences between this procedure and the official one, you should use the Handbook's procedure instead.

Warning: It's easy to break your system, or lock yourself out, when upgrading the kernel or world. Make sure you have console access (PS/2-style or serial) before upgrading.

  1. cvsup.sh # upgrade FreeBSD base (kernel & world) source, and the ports tree; doesn't affect installed ports
  2. cd /usr/src && mergemaster -p # mergemaster is potentially time-consuming, so it's nice to do it before taking the system down.
  3. build-world-kernel.sh
  4. make installkernel
  5. shutdown -r now
  6. Verify new kernel.
  7. shutdown now # single-user
  8. cd /usr/src && make installworld
  9. mergemaster
  10. shutdown -r now
  11. Edit any additional configuration files in /etc or /usr/local/etc.
  12. Test the network connection and firewall rules (perhaps with ipfw list).

Note: If you're using this section to upgrade a running system, rather than configuring a new one, run portupgrade -ai when satisfied with the kernel & world.

Configure BIND

  1. (Assuming FreeBSD 5.3+ with BIND 9): cd /var/named/etc/namedb/ && sh make-localhost && vi named.conf && grep named /etc/rc.conf # should see named_enable="YES"
  2. vi named.conf # mandatory: configure options & add zones
  3. Install any (master) zone files
  4. /etc/rc.d/named start && tail -20 /var/log/messages

Install Ports

  1. cd /usr/ports/lang/perl5.8 && make install && rehash && perl --version # use.perl port no longer necessary
  2. portupgrade -a ; portversion -l \< # try to upgrade everything -- if this doesn't work, follow the instructions under 20040226 in /usr/ports/UPDATING.
  3. portinstall -f www/apache2 postfix imap-uw # force
  4. portinstall analog cronolog curl docproj-nojadetex htmldoc lsof lynx-ssl mailman minicom netatalk nmap nut portaudit procmail portaudit smartmontools webmin squirrelmail drac mozilla ntop screen p5-MIME-Base64 p5-Time-HiRes pyzor p5-Mail-SpamAssassin && rehash
  5. echo "- -noddp -passwdminlen 6 -loginmaxfail 6 -uamlist uams_dhx.so -advertise_ssh" >> /usr/local/etc/afpd.conf # to actually handle tunnelled ssh, also add something like "- -fqdn me.example.com"
  6. vi /etc/pam.d/netatalk:
    netatalk	auth	required	pam_unix.so	try_first_pass
    netatalk	account	required	pam_unix.so	try_first_pass
    netatalk	session	required	pam_permit.so
  7. If desired: configure X (beyond the scope of this document) http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/x-config.html.
  8. If and when X is working, you might want to KDE automatically at boot: echo 'ttyv9 "/usr/local/bin/kdm" xterm on secure' >> /etc/ttys, or use KDE with startx: echo exec startkde > ~/.xinitrc # as each user who will use X11

Configure Mail

amavisd-new

  1. cd /etc/mail && mv mailer.conf mailer.conf.sendmail && cp /root/reppep/mailer.conf .
  2. vi /etc/aliases && newaliases # forward for $myself & root
  3. cd /usr/local/etc && cp /root/reppep/procmailrc . && vi procmailrc
  4. patch /etc/inetd.conf /root/reppep/inetd.conf.diff && killall -HUP inetd # enables unencrypted imap -- I suggest blocking this in your firewall, which leaves it accessible on 127.0.0.1, if using webmail, and disabling the imap port otherwise
  5. echo 'inetd_enable="YES"' >> /etc/rc.conf
    echo 'inetd_flags="-wW -C 60"' >> /etc/rc.conf
  6. Already in rc.conf.append: dracd_enable="YES"; add:
    echo 'rpcbind_enable="YES"' >> /etc/rc.conf
    echo localhost > /usr/local/etc/dracd.host
  7. For FreeBSD 5.x: cd /etc/pam.d && patch < /root/reppep/imap.diff && patch < /root/reppep/pop3.diff
  8. For FreeBSD 4.x: patch /etc/pam.conf /root/reppep/pam.conf.diff
  9. vipw && vi /etc/group && mkdir /home/spamd && chown spamd:spamd ~spamd # Create spamd account
  10. razor-admin -create && razor-admin -register && pyzor discover # configure razor & pyzor
  11. vi /usr/local/etc/mail/spamassassin/local.cf # customize SpamAssassin
  12. echo localhost > /usr/local/etc/dracd.host && /usr/local/etc/rc.d/dracd.sh start
  13. If using Postfix virtual hosts: vi /etc/mail/virtual && postmap /etc/mail/virtual
  14. cd /usr/local/etc/postfix && cat /root/reppep/main.cf.* >> main.cf && vi + /usr/local/etc/postfix/main.cf && postfix stop ; killall sendmail ; postfix check && postfix start && sleep 1 && tail /var/log/maillog
  15. cd /usr/ports/mail/imap-uw && make cert && chmod -x /usr/local/certs/imapd.pem # follow prompts
  16. If desired: portinstall -f mysql-server # -f to get around the hold in pkgtools.conf

Configure Apache & SquirrelMail

# Copy config files and build diffs for <http://www.reppep.com/~pepper/freebsd/install>
diff -u source/httpd.conf.php source/httpd.conf        > reppep/httpd.conf.diff
diff -u source/httpd.conf source/httpd.conf.local > local/reppep/httpd.conf.diff.local
  1. mkdir -p /var/log/httpd /home/httpd && mv /usr/local/www /home/httpd && mv /home/httpd/data /home/httpd/htdocs && cd /usr/local/etc/apache2 && patch httpd.conf /root/reppep/httpd.conf.diff
  2. Either apply a local patch (patch httpd.conf /root/reppep/httpd.conf.diff.local), or vi httpd.conf (set ServerAdmin & ServerName and review security)
  3. mkdir -p ssl.crt ssl.key && ln -s /usr/local/certs/imapd.pem ssl.key/server.key && ln -s /usr/local/certs/imapd.pem ssl.crt/server.crt && touch vhost.conf && vi ssl.???/* vhost.conf && apachectl stop && apachectl configtest && apachectl startssl && apachectl fullstatus # remove cert from server.key & key from server.crt
  4. apachectl configtest && apachectl graceful
  5. cp /usr/local/etc/php.ini-recommended /usr/local/etc/php.ini
  6. cd /usr/local/www/squirrelmail && ./configure
  7. Test https://$hostname/mail/.
  8. Verify SquirrelMail works (it uses unencrypted IMAP to localhost) & telnet $hostname imap fails properly, if blocked by firewall.
  9. Add any desired SquirrelMail plugins.

webmin

  1. cd /usr/local/lib/webmin/ && ./setup.sh
  2. Visit https://$hostname:10000/
  3. Webmin Configuration: IP Access Control: Configure "Only allow from listed addresses" to 127.0.0.1 & trusted IPs.
  4. Webmin Users: Remove unused modules.
  5. If mysql-server is installed, configure under Servers.
  6. /usr/local/etc/rc.d/webmin.sh stop # use start argument later, to bring up webmin as needed

Test Everything!


Not integrated / documented yet

Extras: Postfix SASL2? http://yocum.org/faqs/postfix-tls-sasl.html openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 3650.

Mailman:

httpd.conf:
# Mailman
ScriptAlias /mailman/ /usr/local/mailman/cgi-bin/
Alias /pipermail/ /usr/local/mailman/archives/public/

/usr/local/mailman/Mailman/mm_cfg.py:
MTA = 'Postfix'
DEFAULT_URL_PATTERN = 'https://%s/mailman/'
PUBLIC_ARCHIVE_URL = 'https://%(hostname)s/pipermail/%(listname)s'

/usr/local/etc/postfix/main.cf:
# for Mailman:
owner_request_special = no
recipient_delimiter = +
# CHECKME: alias_maps = hash:/etc/aliases, hash:/usr/local/mailman/data/aliases

chmod g+w data/aliases.db
bin/mmsitepass
# Create private Mailman list

crontab -u mailman -e

Valid XHTML 1.0! Up Updated: Feb 2004