FreeBSD
Basics, Tricks, Tweaks, and other Nifty Stuff.

This page covers things i have figured out...sometimes easily, sometimes from a simple whitepaper, but mostly from compiling a bunch of senseless crap into a (mostly) working solution, which i personally don't want to forget how i accomplished.

If anything throughout the scope of these documents, snippets, etc is of help to you..kewl. if not, please don't kill the messenger..i figured it out eventually, and so too will you with perseverance, caffiene, and little sleep.

Note: Applicable to and tested on FreeBSD 4.x with i386 platform machines. Most files, etc listed in these how-to's require you to be or su to root.
Building a Custom Kernel:
About the most essential, and foremost task to learn...

1. Where to start?

If you installed with the Kernel Developer option you should have the source tree, if you aren't sure look for the directory '/usr/src/sys' ( ls /usr/src/sys ) or more specifically '/usr/src/sys/i386/conf' ( ls /usr/src/sys/i386/conf ). if you have both of these and they are not empty..kewl!

2. How long has this distribution been out? Very long?

How about we update the source tree to current before going off and building a kernel, eh? If this is a nice fresh install from a new .iso or you just don't care you can skip the next part.

3. Since i don't know if the ports tree has been installed on your machine i will tell you both ways to do this.

a. (without ports) execute /stand/sysinstall, select 'configure', 'packages', 'ftp', '<ftp server of choice..i like ftp2.freebsd.org>'. first go to 'net', scroll down and select 'cvsup-without-gui', then 'ok' to return to the previous listing. and select 'install'. wait for it to do it's thing and then exit from the utility.
b. (with ports) cd /usr/ports/net/cvsup-without-gui, then make install clean, wait...
c. Create a cvsup file..i normally do two..one for ports and one for source in the /usr dir. use ee or vi to create the file as follows:

edit cvs.src

#begin file:
*default tag=.
*default host=cvsup2.freebsd.org
*default prefix=/usr
*default base=/usr/local/etc/cvsup/sup
*default cvs delete use-rel-suffix compress

src-all release=cvs tag=RELENG_4_8
#end file

about the only thing to pay attention to here is the 'host', and the 'tag'. 'tag' is the release you want to get, and 'host' is who you want to get it from. Hard, eh?

d. Create the directories that cvsup will want when you run it: mkdir -p /usr/local/etc/cvsup/sup
e. Since you just installed a new program you want to use, you will need to type rehash to get bsd to rescan the paths for new files. once done cd /usr then cvsup cvs.src and wait for it to complete.

4. Ok, now that we have a source tree we want to play with we have to go edit a file.

cd /usr/src/sys/i386/conf to get there, then make a copy of the GENERIC kernel..i normally just call it kern2 for starts. cp GENERIC kern2

5. Now the fun part..

go through the file and read all the nifty little comments. they are extremely helpful in explaining what all those options and devices are. another excellent source is the LINT file in the same directory. PLEASE FOR THE LOVE OF GOD DO NOT BUILD A KERNEL FROM LINT!! Lint helps out mostly in customizing your kernel for your specific CPU, Sound Support, some application tweaks, and if you are so inclined, Firewall options. Some basics i always have:

# Samba Stuff 
options SMBFS# Samba Filesystem Support
options NETSMB# Basic Samba Support
options NETSMBCRYPTO# Windows Encrypted Password Support
options LIBICONV# Needed by NETSMBCRYPTO
options LIBMCHAIN# Needed by NETSMBCRYPTO
options SUIDDIR# Helps Samba with file/directory Permissions
# Sound Stuff 
device pcm# New PCI Sound Driver
device sbc# Soundblaster pcm Audio Bridge Driver
# Video Tweak 
options VESA# Enables Kernel VESA support (makes splash look better)
# Console Tweaks
options SC_DISABLE_DDBKEY# Disables Debugging Keys
options SC_DISABLE_REBOOT# Disables rebooting with Ctrl+Alt+Del
options SC_TWOBUTTON_MOUSE# Enables Console Cut/Paste w/ Mouse
# CPU Tweaks 
options CPU_WT_ALLOC# AMD Cache Tweak
options CPU_ENABLE_SSE# Enable MMX/3dNow! Extensions
options CPU_ATHLON_SSE_HACK# Athlon Hack in case Extensions were not enabled in BIOS
options NO_MEMORY_HOLE# Disables 15-16 MB Memory Hole (non-Intel Systems)
options CPU_FASTER_5X86_FPU# Uses Faster Floating Point Algorithm

6. Build the kern2 kernel..

config -r kern2..if there are no errors then to get on with compiling and automatically reboot when done cd ../../compile/kern2 && make depend && make && make install && reboot now. the && strings the commands together in such a way that if any one fails the next will not be executed.

7. Guess what...you should now have a nice freshly built kernel.

if by chance something has gone awry when booting though, reboot again, when it says 'hit enter to boot or any key..blah blah blah'..hit any other key. at the prompt type unload, then load kernel.GENERIC, then boot. this will boot you with the original GENERIC kernel. that way you can go back in and fix whatever has gone wrong. one note..if you have an ATHLON, you need to specify the cpu type of i686 to correctly identify the processor.


Upgrading from Source:
A time consuming, yet fairly standard way to upgrade. i recommend doing this just before going to bed, especially on an older system.

This is about as easy as it gets. The cvs.src supfile used for upgrading the kernel sources actually updated the entire source tree. so if you have done this recently, just cd /usr/src and type make world. told ya it was hard.

if you are upgrading because a new release has come out i'd recommend updating your sources, doing the make world then going back and rebuilding the kernel from your previous config file. that keeps the kernel in sync with the release, though it is not totally necessary.


Some basic settings in '/etc' files:

rc.conf
the '/etc/rc.conf' file is the main controlling file in the boot process next to the '/boot/loader.conf'. There are tons of options that can be set in the rc.conf. anything set in this file override the defaults in all the other rc.* files. DO NOT mess with any of the other rc.* files. for a listing of the options please refer to man rc.conf.

Really Basic Stuff:
hostname="<name of your server>"# Set the Hostname Of your Machine at Boot. Should be FQDN ie. myserver.mydomain.com
ifconfig_<NicName>="inet <mmm.yyy.iii.ppp> netmask <mmm.aaa.sss.kkk>"# Sets Static IP/Mask at Boot
defaultrouter="<ggg.www.iii.ppp>"# This is your degault Gateway..if you are using a static IP
ifconfig_<NicName>="DHCP"# Tells Machine to use dhclient to recieve an ip from your local DHCP server.
kern_securelevel_enable="NO"# This Enables Setting the Security level of the kernel.
kern_securelevel="2"# This sets the securelevel. a setting of 2 will not allow changing the kernel.
 # NOTE: securelevels may not be decreased once set.
linux_enable="YES"# Enable Linux Compatability Mode (loads a base 7.1 Redhat Kernel for linux emulation)
moused_enable="YES"# Run the Mouse Daemon. If you have a mouse you want this.
usbd_enable="YES"# USB Daemon. Same as above. Especially if the Mouse is USB.
inetd_enable="YES"# Use INETD to enable Network Services. ie: ftp/pop3/telnet/etc
sshd_enable="YES"# Enable the SSH Daemon. Yes!! DO NOT USE TELNET. SSH is at least encrypted.
named_enable="YES"# Enable Bind DNS server. If you aren't running one, set this to NO
update_motd="NO"# Enable BSD to Update the MOTD file at each boot.
clear_tmp_enable="YES"# Enable Clearing the contents of /tmp at boot. Appears to break KDE3.
sendmail_enable="YES"# Enable the Sendmail Mail Server. Setting this to 'NO' only disables SMTP support.
saver="logo"# Sets the Console Screensaver. I like the BSD Daemon Logo personally.
blanktime="300"# Number of seconds before the Console Screensaver Kicks in.

** WARNING **

Take extreme care when editing the rc.conf. if you miss a single quotation mark you could cause yourself a headache as the machine may not boot normally. If this occurs the standard '/' mount will be probably set read-only. makes fixing the problem kinda hard when the filesystem is mounted read-only, eh? one way to solve this is to from the /etc directory run /bin/mount -a. this SHOULD read the 'fstab' file in the '/etc' directory and re-mount '/' as read/write so you can fix the problem. if it doesn't, then type 'mount' take note of the '/' mounting..most likely it will be something similar to /dev/ad0s1a. issue the command mount -w /dev/ad0s1a / and you will be read/write at least on '/' so that you can find/fix the problem.


hosts
The hosts file is just a basic IP-Name resolution file.

pretty straight forward. This file is mainly used to define local loopback (localhost) and machines on your local network if you do not have DNS setup and/or all hosts updated in the DNS database. A personal suggestion from me on HOSTS files in a network is simply this: DON'T DO IT. The administrative headache isn't worth it.

#<ip> <hostname> <FQDN>
127.0.0.1 localhost localhost.localdomain


resolv.conf
This is where your dns server and default search domain is listed, or domain statement, if the machine is the primary DNS server for the domain.

domain=mydomain.com # if this machine is the primary DNS server for the mydomain.com Domain
search=mydomain.com # the local domain of this machine. for searches by hostname only.
server=<DNS Server1>
server=<DNS Server2>


gettytab
this file is used for setting up the consoles on your machine. there is only one fun thing to edit (that i know of so far).

edit /etc/gettytab file. find the line that reads: :cb:ce:ck:lc:fd#1000:im=\r\n%s/%m (%h) (%t)\r\n\r\n:sp#1200:\. you can change the underlined part of this to read whatever you like. what this changes is the message that the consoles display at the login prompt. so make it :cb:ce:ck:lc:fd#1000:im=\r\n<Insert Witty Saying Here.>\r\n\r\n:sp#1200:\ have fun with it.


motd
the 'Message of the Day' file

this is normally the first thing that i go in and edit after an install/upgrade. the contents of this file are shown to you immediately after logging in.



sshd_config
the file is actually '/etc/ssh/sshd_config'. this is the configuration file for your machine's SSH server.

there are really only a couple things that i always do in this file as a good habit. i'm sure there are better ones, but at least i'm making an attempt to be more secure.

Port 22# standard SSH port
Protocol 2# I personally only enable 2, you can also have one enabled by leaving it 2,1.
Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
  # Encryption Algorithms for SSH 2
LoginGraceTime 120# Timeout for Login after connection
PermitRootLogin no# do you really want root to login?
 # keep in mind that if you do, someone already has half of what they need to get in..a username.
StrictModes yes# enable this to allow SSH to keep a little better watch on users
PasswordAuthentication yes# Use this if you don't want to issue an RSA key to all your users
PermitEmptyPasswords no# self-explanitory. mainly for if you have RSA keys setup.
X11Forwarding no# Forwarding for the x server
UsePrivilegeSeparation yes# CHROOT type implementation for SSH
PrintMotd no# Print the Message of the Day after login?
PrintLastLog no# Print the last time the user connected after logging in?
KeepAlive yes# enable session keep-alive?
Compression yes# use data-stream compression? really helps out on slower connections.


Dynamic DNS w/ Bind 8 and ISC-DHCPD 3
Install and configure Bind and the DHCPD daemon for dynamic updates. Warning this one has some spammy seeming files, but oh how much easier it would have been for me the first time if others had done the same with a working configuration.

** Note ** You must set a static IP address on all local interfaces where DHCPD will be active.

1. Installing the daemons.
First you will need to install the packages either from the ports collection or from '/stand/sysinstall'.

Building from ports:
cd /usr/ports/net/bind8 && make install clean
cd /usr/ports/net/isc-dhcpd3 && make install clean

Installing with /stand/sysinstall:
run /stand/sysinstall, select 'configure', select 'packages', choose the source type..typically 'FTP', choose an FTP server (for some reason ftp2.freebsd.org seems more reliable most of the time). choose the 'net' topic, scroll down and select 'Bind-8.3.3' and 'ISC-DHCPD3', install, exit.

2. Configure the Startup Script for DHCPD

cd /usr/local/etc/rc.d, find the sample startup script for dhcpd (isc-dhcpd.sh.sample). copy the sample to a normal startup script

cp isc-dhcpd.sh.sample dhcpd.sh

here is a basic dhcpd.sh example file:
#! /bin/sh
rc_file=${0##*/}
rc_arg=$1
# override these variables in /etc/dhcpd.conf
dhcpd_ifaces=fxp0 # ethernet interface(s)

rcconf_dir=/etc
rcconf_file=rc.conf
rcconf_path=${rcconf_dir}/${rcconf_file}
if [ -f ${rcconf_path} ]; then
. ${rcconf_path}
fi

program_dir=/usr/local/sbin
program_file=dhcpd
program_path=/usr/local/sbin/dhcpd

config_dir=/etc
config_file=dhcpd.conf
config_path=/etc/dhcpd.conf

pid_dir=/var/run
pid_file=dhcpd.pid
pid_path=/var/rub/dhcpd.pid
syslog_facility=daemon.err

case "$rc_arg" in
start)
if [ ! -x ${program_path} ]; then
logger -sp ${syslog_facility} -t ${program_file} \
"unable to start: ${program_path} is missing."
exit 72
fi
if [ ! -f ${config_path} ]; then
logger -sp ${syslog_facility} -t ${program_file} \
"unable to start: ${config_path} is missing."
exit 72
fi
${program_path} ${dhcpd_options} ${dhcpd_ifaces} &&
echo -n " ${program_file}"
;;
stop)
if [ -r ]; then
kill $(cat ${pid_path}) 2> /dev/null
else
killall ${program_file} 2> /dev/null
fi
;;
restart)
$0 stop
$0 start
;;
status)
ps -auxww | egrep ${program_file} | egrep -v "($0|egrep)"
;;
*)
echo "usage: ${rc_file} {start|stop|restart|status}" >&2
exit 64
;;
esac
exit 0

This slightly modified version allows for using the script to start/stop/restart the dhcp server. the normal one unsually bitches.

3. Where to put the dhcpd.conf file?

my script has the dhcpd.conf file being in the '/etc' dir, which by default it is not. the script installed by ISC-DHCPD3 is '/usr/local/etc/rc.isc-dhcpd.conf.sample'. my personal preference is to keep as many .conf files in /etc as i can, so the easy way to do this is to copy the sample to the ISC default, then link it..

cd /usr/local/etc
cp rc.isc-dhcpd.conf.sample rc.isc-dhcpd.conf
ln -s /usr/local/etc/rc.isc-dhcpd.conf /etc/dhcpd.conf

this creates a symbolic link from /etc/dhcpd.conf to the default file. that way you still have both of them. if you decide not to do this you will have to change the config_dir and config_file declarations in the dhcpd.sh example file.

4. Creating a Secret Key.

Before setting up Bind, then making them talk to each other you will need to use the 'dnssec-keygen' utility. this will create an encrypted key pair for dynamic update validation and security between Bind and the updating client (in this case the local DHCP server). my understanding is that as of Bind 8.3.3 and ISC-DHCPD3 only HMAC-MD5 encryption is mutually supported. for more information on 'dnssec-keygen' check the man page. as an example just use a nice simple encryption scheme..

dnssec-keygen -a HMAC-MD5 -b 512 -n HOST <keyname>

<keyname> should be the FQDN of the bind server, remember that a REAL FQDN has the trailing 'dot' on the name..ie "<hostname>.slashdot.org."

* Note * If dnssec-keygen seems to hang while generating the key it is most likely due to a lack of entropy for the random number generator..to fix this simply switch to another console and execute some commands, this should fix the problem.

ok, let's assume we're doing this for ns1.mydomain.com and that this machine is the Primary DNS Server for the domain.

dnssec-keygen -a HMAC-MD5 -b 512 -n HOST ns1.mydomain.com.

this will give you two files as output, the Public Key and the Private Key:
Kns1.mydomain.com.+157+49718.key and Kns1.mydomain.com.+157+49718.private
what you will need for the dhcpd.conf and named.conf files is the value of 'Key:' in the private key.

cat Kns1.mydomain.com.+157+49718.private
Private-key-format: v1.2
Algorithm: 157 (HMAC_MD5)
Key: ophXG56IFTeaOECfiI8F0tHflUCjaoUKgX8+POjmBQYNYqR5p39UUHJOzvNb65xl+48erx5sA+Y8MdrmX2XOYA==

5. Editing named.conf file.
This is the config file for the DNS server. the following should be added to the end of the existing file in the '/etc/namedb' directory.

cd /etc/namedb
edit named.conf
key ns1.mydomain.com. {
algorithm hmac-md5;
secret "ophXG56IFTeaOECfiI8F0tHflUCjaoUKgX8+POjmBQYNYqR5p39UUHJOzvNb65xl+48erx5sA+Y8MdrmX2XOYA==";
};

zone "mydomain.com" {
type master;
file "mydomain.com.hosts";
allow-update {
 key ns1.mydomain.com.;
 };
};

zone "168.192.in-addr.arpa" {
type master;
file "192.168.rev";
allow-update {
 key ns1.mydomain.com.;
 };
};

Take note of the fomatting..for one thing the semicolons and curly-braces, and also the location of the quotation marks. The formatting is different between the dhcpd.conf and the named.conf files.

The key and zone statements set initial values for bind, "file" declarations denote where bind will store and retreive information. "allow-update" enables ddns updates for that zone, and finally the "key" declarations set the security for the ddns update method.

6. Create the initial zone files for bind.
We need to create and setup the initial files for our zones.

edit /etc/namedb/mydomain.com.hosts

Input the basic forward zone defaults

;BIND DUMP V8
$ORIGIN mydomain.com.
38400IN SOAns1.mydomain.com. root.mydomain.com. (
 1038176012 10800 3600 604800 38400 ) ;Cl=3
38400IN NSns1.mydomain.com. ;Cl=3
ns138400IN A192.168.0.1 ;Cl=3

edit /etc/named/192.168.rev

Input the basic reverse zone defaults

;BIND DUMP V8
$ORIGIN 192.in-addr.arpa.
16838400IN SOAns1.mydomain.com. root.mydomain.com.168.192.in-addr.arpa. (
 1038176012 10800 3600 604800 38400 ) ;Cl=4
38400IN NSns1.mydomain.com. ;Cl=4
$ORIGIN 0.168.192.IN-ADDR.ARPA.
138400IN PTRns1.mydomain.com. ;Cl=4

ok, now to see if bind will pick up the new files and run with them. though first we need to make sure that both mydomain.com.hosts and 192.168.rev are writable (funny how they need to be for dynamic updates to work, eh?). do a chmod 640 /etc/namedb/mydomain.com.hosts then chmod 644 /etc/namedb/192.168.rev to set the proper file permissions, then restart bind..ndc restart. fyi, you can also use ndc stop and ndc start. and if you make any manual modifications to the zone files after starting bind be sure to check the file permissions again in case they get changed back to 444 (aka Read-Only).

if you are setting this up from over an ssh session (or god forbid telnet) you won't get any feedback from the daemon on restart, so you'll need to cat /var/log/messages to see whether bind is happy with your files.

one problem you might run into is the initial serial number/time setting for the records. bind requires no more than a 5 minute variance from the current localhost time for ddns updates to work. the serial number is the first number in the SOA record. i personally recommend simply setting the initial value to the current date and hour, then letting bind change it however it wants to when it starts. for instance, instead of 1038176012 in the example set the value to something like 2002010101 for Jan 1, 2002 at 1:00 am.

7. Setting up the dhcpd.conf file.
This is where you define and set options for your dhcp lease pool(s).

if you hadn't guessed i'm using the Class-C Reserved 192.168.0.x range for my example. so long as you made the symbolic link in /etc as i suggested above, edit /etc/dhcpd.conf and define your range, otherwise edit /usr/local/etc/rc.isc-dhcpd.conf.

# dhcpd.conf
authoritative;
use-host-decl-names on;
ddns-updates on;
ddns-update-style interim;
option domain-name "mydomain.com";
option domain-name-servers 192.168.0.1;
# lease times are in seconds
default-lease-time 14400;
max-lease-time 76800;
allow unknown-clients;
log-facility local7;

subnet 192.168.0.0 netmask 255.255.255.0 {
  option subnet-mask 255.255.255.0;
  ddns-updates on;
  ddns-domainname="mydomain.com";
  ddns-rev-domain=".in-addr.arpa";
  range 192.168.0.2 192.168.0.254;
  option broadcast-address 192.168.0.255;
  option routers 192.168.0.1;
  }

key ns1.mydomain.com. {
  algorithm hmac-md5 ;
  secret ophXG56IFTeaOECfiI8F0tHflUCjaoUKgX8+POjmBQYNYqR5p39UUHJOzvNb65xl+48erx5sA+Y8MdrmX2XOYA==;
}

# primary is the IP of the dns server to send updates to

zone mydomain.com. {
  primary 127.0.0.1;
  key ns1.mydomain.com. ;
  }

zone 168.192.in-addr.arpa. {
  primary 127.0.0.1;
  key ns1.mydomain.com. ;
  }

Most of the settings are self explainatory. Only essential basics/standards are shown here. Please note the slight differences in formatting here versus the named.conf file. For more information on dhcp options check man dhcpd.conf and man dhcp options.

8. Time to test it..
The moment of truth.

Now, restart dhcpd using the startup script /usr/local/etc/rc.d/dhcpd.sh restart. so long as everything is set correctly you should now have ddns working between dhcp and bind. to check whether dhcp is handing out leases try to get one. i highly recommend disabling any other dhcp servers on your network at this point as they could create some confusion. kill your remote session (if connected via SSH) and then either set your machine up as a dhcp client, or manually force your machine to renew it's current lease. if you get a new IP and it's in the 192.168.0.x range, odds are dhcp is up and running. now reconnect to the server so we can make sure that the daemons are playing nicely with each other.

execute tail -f /var/db/dhcpd.leases on the server then force your client machine to once again renew it's IP. You should see some happy messages like:

lease 192.168.0.254 {
  starts 1 2001/1/01 08:01:24;
  ends 1 2001/1/01 12:01:24;
  binding state active;
  next binding state free;
  hardware ethernet 00:90:27:17:56:e7;
  uid "\001\000\220'\027V\347";
  set ddns-rev-name = "254.0.168.192.in-addr.arpa.";
  set ddns-txt = "310aa7170c900ab74cd0928d2f78e56d27";
  set ddns-fwd-name = "client.mydomain.com";
  client-hostname "client";
}

You should also see two new *.log files in ls /etc/namedb. if you do not see these two new files, recheck the file permissions on your zone files, restart bind, and try again.


Sendmail: SMTP/POP3/IMAP with Cyrus-SASL, Qpopper, and IMAP-UW

It has come to my attention that I apparently 'don't know shit about sendmail' which, if asked, I would have freely told anyone anyway. So use the next part of this at your own risk. It has been recommended to me to 'just use webmin' so I'll pass that tidbit on to you.

Time for some fun..recompiling Sendmail for SMTP Auth support, and installing and configuring POP3, and later I'll also be adding IMAP and LDAP2. Gotta start somewhere right?

If you have already been screwing with directions found on other peoples pages with no success, I feel your pain. Most everything I ran into in trying to get this to work was if not uninformative, at least irritating enough to make me deem sendmail as the devil's work and those who think highly of it strangely demented. i'm coming around on the latter, but still hold a firm belief on the former. maybe that's where the BSD daemon comes into play, eh?

1. Start off clean.
Uninstall anything that you have installed and undo anything you have changed due to reading whitepapers that did not work. You only have to complete this step if you have been vainly trying to get SMTP AUTH to work with sendmail.

2. Install SASL from ports.
Ok, i personally recommend installing Cyrus-SASL first since this is what Sendmail will need to be recompiled in order to support.

Installing from ports:
cd /usr/ports/security/cyrus-sasl2
make install clean
You will want to enable DB3, OpenLDAP2 (if you plan to add it later), PWCHECK, PAMPWCHECK, and SASLAUTHD.

Installing from /stand/sysinstall:
/stand/sysinstall
select 'Configure', 'Packages', 'Ftp', 'ftp2.freebsd.org' (my preference), then when the Index is loaded..'Security', and finally 'Cyrus-Sasl'. Select the package, 'Install', then exit when done.

Cyrus installs a few files/scripts that need to be edited, but we will get back to those later.

3. Recompiling the default Sendmail from source.
This takes awhile because you need to rebuild the base from the source tree..just warning you.

I am going to assume that you have the source tree installed. if you do not, go back to part 3 (cvsup) of my kernel customization mini-tutorial.
First we need to create a new file: edit /etc/make.conf
Add in these lines:

SENDMAIL_CFLAGS+=   -I/usr/local/include -DSASL=2
SENDMAIL_LDFLAGS+= -L/usr/local/lib
SENDMAIL_LDADD+=    -lsasl2

Anything in this new file will override the default settings in the Makefile when executing a 'make world' in the source tree.

That having been said, you can now either:
-- Rebuild only sendmail: cd /usr/src/usr.sbin/sendmail then make depend && make && make install, and follow the rest of the steps.
-- Rebuild the system: cd /usr/src then make world.

** Note: The FreeBSD 4.x Releases seem to have dependencies which require using make world.

4. Make an Addition to the mc file.

If you already have mail.%lt;hostname%gt;.* files in /etc/mail, then rm /etc/mail/mail.*. Now edit /etc/mail/freebsd.mc and near the end of the file (just above the mailer() statements) add these lines:
define(`confRUN_AS_USER',`root:mail')dnl
TRUST_AUTH_MECH(`DIGEST-MD5 CRAM-MD5 LOGIN')dnl
define(`confAUTH_MECHANISMS',`DIGEST-MD5 CRAM-MD5 LOGIN')dnl
define(`confDONT_BLAME_SENDMAIL',`GroupReadableSASLDBFile')dnl

Save the file, then in the /etc/mail directory type make all install. This will rebuild the config files to incorporate the changes. Next you need to then restart Sendmail. You should be able to either do this by killall -HUP sendmail or sh /etc/rc.sendmail stop, sh /etc/rc.sendmail start. (trying a 'restart' might work, but it didn't for me..).


5. Now to configure and enable saslauthd.

cd /usr/local/lib/sasl then edit Sendmail.conf (case sensitive).

Change the file to read:
#pwcheck_method: saslauthd
pwcheck_method: passwd
This will cause FreeBSD's /etc/passwd file to be used for authentication via Sendmail.

Next, edit /etc/rc.conf and add these lines:
sasl_saslauthd1_enable="YES"
sasl_saslauthd1_flags="-a pam"

At this point i think it is a good idea to go ahead and reboot now so we can see where we stand so far.

6. Test Sendmail
Once you have logged back in (hopefully with no major errors with sendmail starting during boot).

verify that sendmail's smtp is indeed running by checking netstat -a|grep smtp for "tcp4 0 0 *.smtp *.* LISTEN".

If smtp is running telnet localhost 25, you should connect and get a short welcome message.

Now type EHLO localhost and look for a line similar to 250-AUTH LOGIN. Existence of this statement indicates you now have an AUTH enabled Sendmail.

7. Install and Enable POP3
We will be using qpopper for our pop3 server. It works nicely, though it lacks SSL support, so we'll have to use a tcp-wrapper for security.

Installing from ports:
cd /usr/ports/mail/qpopper then make install clean

Installing with /stand/sysinstall /stand/sysinstall, 'configure', 'packages', 'ftp', 'ftp2.freebsd.org' (again, my preference), 'mail', select 'qpopper', 'Install', 'Exit'.

Qpopper has been acting strangely for me running as a daemon, so we'll be running it from inetd for now.

edit /etc/inetd.conf, find the line that begins: #pop3 and change it to read:
pop3 stream tcp nowait root /usr/local/libexec/qpopper qpopper -s -C

Make sure that inetd is enabled in the rc.conf. edit /etc/rc.conf and verify that there is a line that reads: inetd_enable="YES".

See if inetd is already running with ps -aux |grep inetd. if it is kill -HUP the process number. if not just go ahead and execute a simple inetd to start the daemon.

Verify that pop3 is now running by checking the output of netstat -a|grep pop3 for "tcp4 0 0 *.pop3 *.* LISTEN".

If you installed qpopper from /stand/sysinstall instead of installing from ports, a default pop3 access list should have been created. To be sure that the file exists and has a basic user list, cp /etc/ftpusers /usr/local/etc/qpopper/popusers. The popusers file is similar to the ftpusers file in the fact that users listed in this file are denied pop3 access. I highly recommend adding any users who do not need pop3 access and all daemons to this file.

8. Test it.

Fire up and configure your favorite e-mail client. Be sure to set authentication for outgoing e-mail via SMTP. If you are using Outlook Express do not enable Log on using Secure Password Authentication as it doesn't work with sendmail. I have tested it successfully with Outlook Express from a Windows client, and Evolution from a FreeBSD client. Persons who do not know how to configure their own e-mail client should not be reading this.

9. Adding simple IMAP support.
I'm sure there are many others..i tried the 'cyrus-imapd' port with no luck..most likely an SASL/PAM problem. But this is easy and works. In case you are unfamiliar with imap, it's similar to pop, except that all messages are kept on the server until deleted instead of automatically removed each time you check your mail (unless you have your client set to leave a copy on the server).

We will install the 'imap-uw' port for our imap support. The port seems to also install it's own ipop2 and ipop3 daemons for pop support. I haven't tested to see if qpopper breaks imap yet, but since it's known to work that's what we'll stick with for the time being. (Please note that the most current version of imap-uw requires patching in order to allow for plaintext logins over non-encrypted communications. So if you plan on using squirrelmail, etc, especially you might want to get an older version of imap-uw or try another imapd.)

cd /usr/ports/mail/imap-uw && make -DWITH_SSL_AND_PLAINTEXT install clean

Now since this is run from inetd we need to uncomment the imap statement in the inetd.conf: edit /etc/inetd.conf

Find the line that reads:
#imap4 stream tcp nowait root /usr/local/libexec/imapd imapd
and change it to:
imap4 stream tcp nowait root /usr/local/libexec/imapd imapd

Next we will also need configure PAM for IMAP: edit /etc/pam.conf

Find the (most likely) existing Mail settings and change them to read:
# Mail services
#imapauthrequiredpam_unix.sotry_first_pass
#pop3authrequiredpam_unix.sotry_first_pass
imapauthrequiredpam_unix.so
imapaccountrequiredpam_unix.sotry_first_pass
imapsessionrequiredpam_deny.so
pop3authrequiredpam_unix.so
pop3accountrequiredpam_unix.sotry_first_pass
pop3sessionrequiredpam_deny.so

Now as we did with qpopper, see if inetd is already running with ps -aux |grep inetd. if it is kill -HUP the process number. if not just go ahead and execute a simple inetd to start the daemon.

Verify that imap is now running by checking the output of netstat -a|grep imap for "tcp4 0 0 *.imap *.* LISTEN".

So long as imap is running, you should be able to test it with your favorite email client. Setup is the same as pop3 except that you choose IMAP as the server type. SMTP would still be the same, and still requires authentication to send email.

10. Securing your SMTP, POP3, and IMAP access with SSL.
Since the configuration so far uses plain text LOGIN authorization for wider client support and easier installation, configuration, and administration, we now need to think about security. We will use an SSL wrapper to accomplish this. The /usr/ports/security/stunnel port will run out of inetd like pop3 and imap or as a stand-alone daemon and will add an encrypted layer for security.

Install OpenSSL, stunnel requires a valid server certificate to work properly. We are installing OpenSSL in order to issue this certificate ourselves, though if you would like to, and have the money to throw around, you can go buy one from verisign.

Installing from Source: cd /usr/ports/security/openssl && make install clean
- or -
Installing from /stand/sysinstall: /stand/sysinstall, select 'Configure', 'Packages', 'FTP', 'ftp2.freebsd.org' (my preference), 'security', 'openssl...', 'Install'

Setup a new Certificate Authority (CA):
Copy the sample config file to the default location: mkdir /etc/ssl, cd /usr/local/openssl, cp openssl.cnf.sample /etc/ssl/openssl.cnf
Now create your new CA: cd /usr/local/openssl/misc, ./CA.sh -newca, hit 'Enter' to setup a new default CA.

Follow the prompts:
- Enter PEM pass phrase: Enter a password, then enter it a second time to verify. (remember it)
- Country Name (2 letter code) [AU]: US
- State or Province Name (full name) [Some-State]: MyState
- Locality Name (eg, city) []: MyCity
- Organization Name (eg, company) [Internet Widgits Pty Ltd]: MyCompany
- Organizational Unit Name (eg, section) []: Whatever, it's optional
- Common Name (eg, YOUR name) []: Server's FQDN..myserver.mydomain.com
- Email Address []: Contact email address...it's optional

That should have created a new directory called 'demoCA' with our new CA information. Now we need to configure openssl to use the new CA we just created.

First mv demoCA ../CA to move the new CA directory to /usr/local/openssl/CA, then to tell openssl to use the new CA edit ../openssl.cnf, find the line that reads dir = ./demoCA and change it to read dir = /usr/local/openssl/CA

For a slight addition to security it might be a good idea to set the CA private key root read only with chmod -R 600 /usr/local/openssl/CA/private

Ok, with that done we should be ready to create our SSL certificate. sslwrap defaults to looking in the /usr/local/ssl/certs folder, so we'll create one and make the certificate there.

Create the folder: mkdir -p /usr/local/ssl/certs && cd /usr/local/ssl/certs
Then create the new certificate: /usr/local/bin/openssl req -new -x509 -nodes -out server.pem -keyout server.pem -days 365, just follow the prompts as you did for creating the CA.

If you check ls /usr/local/ssl/certs there should be a new file called 'server.pem'.

With that done let's move on to installing stunnel:

Installing from source: cd /usr/ports/security/stunnel && make install clean
- or -
Installing from /stand/sysinstall: /stand/sysinstall, select 'Configure', 'Packages', 'FTP', 'ftp2.freebsd.org' (my preference), 'security', 'stunnel...', 'Install'

With stunnel installed we can now enable it for IMAP, POP3, and SMTP in the /usr/local/etc/stunnel/stunnel.conf.

cp /usr/local/etc/stunnel/stunnel.conf-sample /usr/local/etc/stunnel/stunnel.conf
edit /usr/local/etc/stunnel/stunnel.conf

Modify these lines in the file:
cert = /usr/local/ssl/certs/server.pem
#chroot = /var/tmp/stunnel

Be sure that the cert path is correct for the location of your certificate. I chose not to run stunnel in a chroot because, frankly it was being unhappy and i wasn't in the mood to figure it out. Also in the config you should comment out any services that you do not need to have wrapped.

Next find the process ID for inetd: ps -aux | grep inetd and send a kill -HUP <ID Number> signal to the process to restart inetd.

Check netstat -a for smtps (465), imaps (993), and pop3s (995). If these new ports are showing we just need to test it.

Configure your mail client to use a secure connection for SMTP, POP3, and/or IMAP. In Outlook Express you have to specify the port for SMTP, but POP3/IMAP will automatically change to the default port. You will most likely be prompted for confirmation to use the server's certificate the first time you check your mail with the new settings, but it should be ok afterwards.

** Note **
In Windows, if your client continues to ask for confirmation you can create a new file called 'server.crt', then copy the body of the /usr/local/ssl/certs/server.pem file you created starting with -----BEGIN CERTIFICATE----- and ending with -----END CERTIFICATE-----. Save your new 'server.crt' file, then right click on it and select 'Install Certificate', and follow the prompts. This should take care of the problem.

If you are running a firewall it is advisable to block outside access to pop3 (110) and imap (143) so that your clients will have to use SSL.

** Note ** Changes to this section

-- Setting up a CA was inaccurate and has been corrected: 1/2003.
-- SSLWrap was changed to Stunnel due to OpenSSL incompatabilities: 4/2003.



Installing and Configuring Samba as a Primary Domain Controller (PDC)
Think you have to be a slave to Microsoft just so you can have domain security on your network in a mixed environment? If you said 'no'..you're right! The samba project has been around for quite a long while and is making more and more improvements with each release. You'll never hear this from Microsoft, but a Samba server will actually outperform an NT server as a file server..trust me I tested this, and it's true.

1. Install Samba from either the ports tree or via /stand/sysinstall.
I highly recommend that you do not download the source tarball directly from samba and compile it. FreeBSD already has partial kernel support for the SMB protocol which samba also uses, so the BSD releases are already patched with this in mind.

a. Installing from ports: cd /usr/ports/net/samba, make install clean. There will most likely be a menu with some options that pops up..just ignore it. I won't go into the different options there, just suffice it to say that you don't have to have that stuff to make it all work ok.

b. Installing from /stand/sysinstall: /stand/sysinstall, select configure, packages, ftp, then your server of choice (I still like ftp2.freebsd.org best), net, samba 2.x. I say to install the 2.x version because they are still tweaking a bugfixing the 3.x releases. Select install, then it'll do it's thing and you'll be all done.

2. The smb.conf file
This is the config file for Samba. Like most other daemon .conf files the smb.conf is located in /usr/local/etc. I would recommend looking over the smb.conf.default that comes with the distribution first to acquaint yourself with the format a little.

a. Server Settings aka Global Parameters

Example (with comments):
** Note: Only use the command part of each line. Samba does not like having a comment on a command line.
[global]
null passwords = yes# Enabled for NT/Win2k/WinXP Machine Accounts ONLY
encrypt passwords = yes# Use encrypted passwords: Need this for anything except early Win95 and Win3.x
update encrypted = Yes# Update encrypted passwords
unix password sync = Yes# Syncronize password with unix accounts
log file = /var/log/log.%m# Where to save the log file
max log size = 50# Don't want the log getting too big
 
locking = No# Helps with fileserving
oplocks = yes# Ditto
level2 oplocks = yes# Ditto
 
domain logons = yes# Be a login server for Domain clients
logon script = connect.bat# Logon script for clients to run when logging into the domain
 
preferred master = yes# Make Samba call for Browser election when it starts up
local master = yes# Define if samba server should be a local master browser for the wkgrp
domain master = yes# Define if samba server should be a local master browser for the domain
os level = 65# Announced OS level for Browser elections. An OS level of 65 will beat out Win2k and XP.
 
netbios name = SMB_PDC# Server name
server string = Samba Server# Server Description
announce version = 4.9# Announced windows version
workgroup = WORKGROUP# Either Windows Workgroup or Domain name
security = user# Security level: 'User' for being a PDC, 'Domain' if being a BDC to an Windows PDC
admin users = @wheel# Samba admins. Either names, or use '@' to define a group
 
wins support = yes# Be a WINS server for Netbios name resolution
dns proxy = No# Try to resolve NetBIOS names via DNS nslookups

If you are unfamiliar with the comments made to 'browser elections' etc, here is a basic explaination. In a windows based network machines depend on netbios names for talking to one another. Instead of having every client keep up with it's own listing there is an election held when a machine starts up that thinks it should be the browse master aka the one who knows all and tells anyone who asks. Elections are also held from time to time whenever a machine queries for the browse master or if the master browser is not available. This is somewhat akin to a WINS server which resolves netbios names to IP addresses for clients, except that windows browse lists are maintained on pretty much any network (TCP/IP, IPX/SPX, NetBEUI, etc) with at least one PC on it, and cannot be administrated. The machine with highest OS level always wins, though if they are all running the same OS the machine with the longest uptime wins.

** Note **
Though the Null Passwords option is enabled in the example, do not EVER allow clients to have a blank password. If you do, don't whine when things go very badly, which they eventually will. Think about this..would you leave your keys in your car with the doors unlocked all the time? No? I didn't think so. Not much difference between that and having blank passwords or setting them to things like 'password'. Ok enough of the soapbox, back to samba.

You should also create a couple of basic shares, one being of course the NETLOGON share. There are many options for setting up individual shares for permissions, etc. I won't even begin to cover them, just look through the smb.conf.default to get a decent grasp of what you can do.

Add something like this to your smb.conf
[NETLOGON]
path=/usr/samba/netlogon
writable = No
guest ok = Yes
share modes = No
browseable = Yes
 
[homes]
comment = Home Directories
read only = No
browseable = No
 
[public]
path = /usr/samba/public
read only = No
wide links = No
browseable = Yes
 
[hidden$]
path = /usr/samba/hidden
read only = No
wide links = No
browseable = No
 
[printers]
comment = All Printers
path = /var/spool/samba
browseable = no

NETLOGON: equivalent to the NETLOGON share on a Windows PDC where login scripts are stored.
homes: an internal samba share function for sharing the user's home directory. You do not have to set a separate home share for each user.
public: a basic world accessable share.
hidden$: demonstrates that you can have hidden shares on Samba just like in windows. Note the dollar sign.
printers: another internal samba share function for any locally installed printers. It pulls the list from your /etc/printcap.

Be sure to create the local directories that the share paths point to and set appropriate permissions on them for users.

3. Adding Users to Samba
Samba keeps it's own database of users/passwords for clients. In the example above samba has been configured to syncronize users passwords between the OS and samba. It does not automatically create users for you though, you have to use smbpasswd for that.

Since not all users will require shell access, i recommend installing a psuedo shell first before we start here. Simply cd /usr/ports/sysutils/no-login, and make install clean. Once it has been installed we need to add it to the list of available user shells. edit /etc/shells, and add to the end of the file /sbin/nologin.

With that done we need to first add a 'root' user to samba. This user is the ONLY account with the ability to add machine accounts to the domain. When you add a user there are a few options that should be used with smbpasswd. -a is to add a user, -e is to enable a user, -n sets the user as having a null password, and -x will delete a user. One other option that you need to use, though only once, is -S which gets the Domain SID from a PDC if your machine will be a BDC along with -j <domain> -r <server> -U <AdminAccount>. (For more information on this check man smbpasswd.)

As a PDC:
smbpasswd -a -e root
smbpasswd -


More to Come..