--- Gateway configuration ---
22.9.2003 1.7 Alexander Kühn

--- Gateway configuration ---

00.0000 Preface

This documentation is not intended to give you an introduction to FreeBSD, there is more than sufficient documentation on this subject available in various places in the Internet (check http://www.de.freebsd.org/docproj/doc-set.html for a start). I will just cover the points that were relevant for the setup of our gateway as it is today but I'll try to make many links to available documentation where appropriate.
I have replaced or removed all confidential values such as password and hostnames so that the document does not need to be kept secret from any of our employees or even the world. The domain was renamed to mydomain.org in this documentation.

00.0001 Install

The install didn't went as smooth as expected as the 4.7 install disks (which was the current stable version at that time) stuck at the harddrive recognition for some unknown reason (all self compiled versions didn't have any problems though) so I was forced to install FreeBSD 3.5.1 which I then upgraded to FreeBSD 4.0 following the instructions in /usr/src/UPDATING (see section 21.3 of the FreeBSD Handbook on how to sync your sources and section A7 for which tags to use when checking out) and from 4.0 I upgraded to FreeBSD-Stable (RELENG_4).

The system, a Intel Pentium II 300MHz, came with 2 harddrives, I utilized both completely (see section 2.5.3) making the 4.3 GB SCSI drive my root fs and mount the 14,3GB IDE to /usr/local. Later I moved /usr/home, /usr/src and /usr/ports to this drive, leaving enough space for the years to come on the root fs (32% used currently) but keeping the system working even without /usr/local (except for the ports of cause). After the system was brought up-to-day which required already the install of some ports (namely cvsup(1)) I started with the configuration.

00.0010 Kernel Configuration

One of the first things to do was the kernel configuration, as I had to upgrade the system right after the install what can't be done without rebuilding a kernel. I started with GENERIC and created a new /usr/src/sys/i386/conf/gateway for the kernel configuration and added a KERNCONF=gateway to /etc/make.conf(5) to spare me some typing with each kernel rebuild. But what did I change? I dropped support for older architectures (i386,i486,i586) and the software fpu (MATH_EMULATE), added power management options (CPU_SUSP_HLT), lowered the SCSI delay from 15 to the minimum of 5 second (SCSI_DELAY) added netgraph support (NETGRAPH_*) in case we want to use the kernel pppd, added ipfirewall and ipfilter support (IPFIREWALL, IPDIVERT for nat, IPFILTER, IPFILTER_LOG) along with some security options (ICMP_BANDLIM, RANDOM_IP_ID) and the dummynet driver (DUMMYNET) which can help avoid some troubles when using dial-up links as we do. I dropped support for a plethora of devices that are not installed in our machine and increased the number of Berkeley packet filter devices from 1 to 4 to be able to use ntop.

00.0011 Configuring /etc/rc.conf

This file contains only the changes to the defaults from /etc/defaults/rc.conf. A bit initial setup (keymap, mouse, screensaver) was already done during the install by sysinstall(8) but as the first network card was later to be used as the pppoe card all networking setup had to be redone too. Before configuring the pppoe dialin some decision have to be taken as FreeBSD offers different ways to do things. The first decision was to use either the user pppd(8) or the kernel pppd(8). Although performance considerations would suggest to use the kernel pppd I chose to use the user pppd as the documentation available appears to be more extensive on this one (at least in regards to the use as pppoe driver). The performance is not really a critical point in our situation with a relatively thin link (768kBit/s) and a relatively fast processor (typical CPU usage is about 1-2%). We may consider to switch if the load becomes higher because of a different link or whatsoever, now that the configuration is done this should be pretty easy as I'm also not using any of the user pppd(8) specials like the -nat switch. Comments suggest the use of mpd(8) but I didn't investigate in this any further. There is also a port of the NetBSD1.6 kernel PPPoE (if_pppoe.c) in the works, unfortunately pppoectl(8) has not yet been ported. (Damien Bergamini) The next decision to take was using ipfilter ( ipf(8)/ ipnat(1)) or ipfirewall (ipfw(8)/ natd(8)) for the firewall and nat, pppd's -nat switch would be another alternative but I prefer the one tool for one problem approach, additionally this is unsupported by the kernel pppd in case we ever switch. At first I chose to go with ipfw as it seems to be easier to configure because there are predefined firewall types in /etc/rc.firewall. However it turned out that the predefined firewall types did not suffice our needs and the usual way to make your own ipfw firewall is to modify this script which is something I don't feel really comfortable with. Additionally the logging features of ipf are more advanced and ipf offers stateful packet filtering. As ipf is not FreeBSD specific documentation on ipf usually applies to all plattforms ipf is used (OpenBSD, NetBSD, Solaris,...)
I'll now explain a few (less obvious) options from rc.conf in more detail.

/etc/natd.conf contained our portforwarding configuration, we use only the redirect_port command.

00.0100 Configuring /etc/ppp/ppp.conf

Our configuration is basically a replication of what's written in section 18.4, worth mentioning is the the selected dialmode ddial which has to be set in /etc/rc.conf. Along with the ppp.conf there is also the ppp.linkup which executes certain things each time the link has been established:

MYADDR:				# we got an IP!
 add 0 0 HISADDR		# set new default route
 !bg /usr/local/sbin/ddclient	# update dyndns address
 !bg /etc/ppp/pppip-tx		# run ftp script for ip update
More examples on several configuration files in this directory are available here /usr/src/share/examples/ppp/.

/etc/ppp/pppip-tx hasn't changed except for the grep(1) that extract the IP of the tun0 interface:

#!/usr/local/bin/bash

LOCALIP=""
while [ -z $LOCALIP ]
do
        sleep 5
        LOCALIP=`/sbin/ifconfig tun0|/usr/bin/grep "inet"|/usr/bin/cut -d " " -f 2`
done
echo $LOCALIP > /tmp/pppip

/usr/bin/ftp -n -i our-server.de >/dev/null <<-EOF
user username password
cd redirection/
put /tmp/pppip pppip
chmod a+r pppip
bye
EOF
rm /tmp/pppip

00.0101 Crontab

This is our current crontab(1):

# make sure dyndns and out pppip get updated
*/30 *  * * *   /usr/local/sbin/ddclient && /etc/ppp/pppip-tx
# update /usr/src and /usr/ports + report cvs inconsistencies + check package_db
45 20   * * 6   /usr/local/bin/cvsup /usr/local/etc/cvsup/supfile && \
/root/bin/cvsupchk -d /usr -c /usr/local/etc/cvsup/sup/src-all/checkouts.cvs:RELENG_4 && \
/root/bin/cvsupchk -d /usr -c /usr/local/etc/cvsup/sup/ports-all/checkouts.cvs:. && \
/usr/local/sbin/pkgdb --autofix
* *     * * *   /root/bin/ifmonitor.pl

Here the links to the appropriate documentations: ddclient, cvsup(1), cvsupchk,pkgdb, ifmonitor. If any unresolved dependencies are reported you can use pkgdb -F to fix them.

01 FAQ (gateway)

01.0000 How to setup a new user?

This is what adduser(8) is for, take care when choosing the group, adduser may suggest a new group for each user, we use a group called 'users' (gid 1000) (edit /etc/adduser.conf to change this). adduser will not create the homedirectory, you can do this manually either by mkdir /home/username or cp -pr /etc/skel /home/username. As of the time of writing /etc/skel and /usr/local/share/skel are both empty so it would not really make a difference. After the directory has been created the ownership should be transferred to user, which can be done with chown -R username:users (or username.users for older versions) /home/username .

01.0001 How to setup new pc in LAN?

This can be separated into two points:

The named(8) has it's configuration files in /etc/namedb namely named.conf(8) and the zone files. To add a new workstation to the subnet you'll have to modify the zonefile mydomain.zone and the 192.168.1.zone (depending on which zone you wish to modify obviously).
mydomain.zone: You can basically copy an existing entry and simply alter the IP and hostname, I've kept the hosts ordered by IP to ease finding of an unused one. The last thing to do is to update the serial which simply the date followed by the version number (which restarts every day). For example 2002120901 for the first version at the 9th December 2002.
After modifying the 192.168.1.zone file in a similar manner (don't forget the trailing dot!) we have to make the named to load the new configuration:

	kill -s HUP `cat /var/run/named.pid`
Now we should do a quick test using nslookup(8) and look up the new host by name and by address.

The installed dhcpd(3) is the isc-dhcp3 from /usr/ports/net/isc-dhcp3 which keeps it's configuration file dhcpd.conf(5) in /usr/local/etc/ . At the top of the configuration file we have some genric settings which apply to our subnet and are explained in dhcpd-options(5):

ddns-update-style none;		# this zone is static, no updates
authoritative;			# yes we are the ruler
default-lease-time 1800;
max-lease-time 3600;
get-lease-hostnames true;
use-host-decl-names true;

option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
option domain-name "mydomain.org";
option netbios-name-servers files;
option time-offset -3600;		# CET is GMT-3600sec
option time-servers time;
option ntp-servers time;
option smtp-server mail;
option pop-server pop;
option www-server gateway;
option finger-server gateway;
option irc-server irc.uni-stuttgart.de, irc.fu-berlin.de;

This section is followed by the host definitions. All entries look very similar to another, they all look like this:

host foobar {
	hardware ethernet 01:23:45:67:89:ab;
	fixed-address 192.168.1.123;
}

We simply duplicate an entry and modify it to suit our needs. After adding the new host we do the usual (again I kept it ordered by IP for better usability):

	kill -s HUP `cat /var/run/dhcpd.pid`

After that we should be able to monitor the dhcp requests and responses using the syslogd(8).
At the end of the configuration file you can find the definition for our dynamic range:

subnet 192.168.1.0 netmask 255.255.255.0 {
	range 192.168.1.200 192.168.1.239;
}

01.0010 How to setup/change dial up connection?

The dialup configuration is done by creating a section in the /etc/ppp/ppp.conf and selecting this section/profile in /etc/rc.conf (ppp_profile), see 00.0100 for further details.

01.0011 How to log system information?

Besides the usual syslogd(8) which is configured in /etc/syslogd.conf(5), FreeBSD runs a number of regular cron jobs to do accounting and other security related things. Whether the output is mailed to the admin or not is specified in /etc/periodic.conf(5) (defaults in /etc/defaults/periodic.conf), for further details see periodic(8).

01.0100 How to install printer?

This subject is well covered in chapter 11 of the FreeBSD Handbook.

01.0101 How to install/configure driver for new hardware?

After the hardware has been installed (physically) you will probably have to modify the kernel configuration file and recompile the kernel (the "new" way).

01.0110 How to configure/install tools/services (http, ssh, ...)?

First you have to differentiate between "build-in" services, which come with FreeBSD itself and third-party services installed via the ports or manually. Build-in services include sshd(8),inetd(8),ftpd(8),telnetd(8) and such (/etc/inetd.conf is good place to look) and usually only need to be enable the service in /etc/inetd.conf or rc.conf (see section 6.5). However you should always consult the corresponding manual pages for further configuring the new service (e.g. logging features).
For installing additional services the preferred install method is using the ports tree. A complete description is given in chapter 4, but a usual install session may look like this:

# whereis unrar
unrar: /usr/ports/archivers/unrar
# cd /usr/ports/archivers/unrar
# make install clean
<build and clean output>
If you can't find what you are looking for the following might help too:
# cd /usr/ports
# make search key=CMF
Port:   zope-cmf-1.1
Path:   /usr/ports/www/zope-cmf
Info:   The Zope Content Management Framework (CMF)
Maint:  nbm@FreeBSD.org
Index:  www zope
B-deps: python-2.2.2_2
R-deps: python-2.1.3_2 python-2.2.2_2 zope-2.5.1_2

A listing of the installed applications can be obtained by looking into /var/db/pkg/, to check if they are up-to-date you can use pkg_version -v (assuming the ports tree was recently updated). The easiest way to update all out-of-date packages is probably using portupgrade -a but take care you may break things by updating dependencies but not the main app but thereby breaking the main application, portupgrade -f mainapp\* will rebuild the mainapp and should solve these kind problems (Apache is probably the most obvious candidate for such).
All ports are by default installed to /usr/local so the natural place for the configuration files would be /usr/local/etc plus eventually a subdirectory if the application has several configuration files such as apache: /usr/local/etc/apache . The start scripts are consequently placed below /usr/local/etc/rc.d/ (see section 6.5). They must be called with their complete path (e.g. /usr/local/etc/rc.d/mysql-server.sh) and the desired behaviour as parameter (start|stop). Final word, pay a visit to http://www.freshports.org/ it can do things like notifying you when a certain port was updated or give you a heads up if a dependency of a watched port has changed.. There are plenty of useful things that can be done using the ports system this article explains some of them in greater detail.

01.0111 How to configure/install firewall, ipforward, logging?

Firewall functionality is part of the base system and therefore requires no installation. The firewall start options are set in /etc/rc.conf, we use ipfilter so we leave firewall_enable disabled but set ipfilter_enable="YES". The default option file for ipfilter is set in the /etc/defaults/rc.conf to /etc/ipf.rules, no need to change that just had to create ipf.rules. Our current ruleset consists basically of the following rules:

The nat options are set in /etc/rc.conf as well, we use ipnat so we leave natd_enable (actually it won't be enabled unless firewall_enable="YES") so we just set ipnat_enable="YES". The default option file is set to /etc/ipnat.rules so I used this. I do 3 different mappings and the port redirection here:

  1. enable the ftp proxy mode, this does basically the same as the masq_ftp module under linux.
  2. map outgoing tcp and udp connections to source ports in the range of 30000-65000, it is necessary to do this remapping because the different clients in our network are not aware which port another client may has already used as source port which could lead to a port collision. By remapping all connections to a certain port range the gateway's tcp stack takes care of the port usage and avoids these collisions. The port range itself is rather unconcerned, as long as we don't interfere with any already occupied ports, however it may could become interesting in case the ISP tries to track down all the people using a NAT because most NAT implementations use a specific port range for this mapping. So in theory the ISP could analyse the traffic and if 90% if the traffic is coming from this high port range this could be taken as proof that the machine on the other end of the line is doing NAT.
  3. map outgoing icmp to allow ping, traceroute, et al.

Then follow the redirection options, the whole thing look like this (I included only 3 examples, see ipnat(5) for details):

map tun0 192.168.1.0/24 -> 0/32 proxy port 21 ftp/tcp		# allow active ftp from clients
map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 30000:65000	# remap port to avoid collisions from multiple hosts
map tun0 192.168.1.0/24 -> 0.0.0.0/32 proxy port 500 ipsec/udp	# IPSec 4 all
map tun0 192.168.1.0/24 -> 0/32					# handle ICMP, etc.
rdr tun0 0/0 port 7080 -> 192.168.1.192 port 80			# map to a different port
rdr tun0 0/0 port 2000-2010 -> 192.168.1.123 port 2000		# map a small range
#rdr tun0 0/0 port 500 -> 192.168.1.255 port 500 udp		# even broadcasting is possible,
								# we don't use this anymore though

Finally just a few usage examples for ipf and ipnat:

ipf -Fa -f /etc/ipf.rules		# reload all ipf rules
ipfstat -i				# check if everything has been loaded as expected
ipnat -C -f /etc/ipnat.rules		# reload the redirection and mapping rules

Both commands support the -n parameter which can be used to test the command, this prevents the commands from actually making any ioctl calls or doing anything which would alter the currently running kernel. Also advised is to use -v (verbose switch). ipf also supports a shadowed filter list, that is a filter list that can be modified and tweaked but is not really used until you swap the active filter list against the shadowed by using ipf -s . This is useful for testing new filter lists because if you are not satisfied with the new list you can easily switch back by calling ipf -s again.

ipfstat -t                # display a top(1) like traffic statistic

If you want to do some bandwidth trottling you can use dummynet(4).  Dummynet provides an easy way to do some really flexible traffic shaping, these two commands limit outgoing traffic to 100kbit/s:

ipfw add pipe 1 ip from any to any via tun0 out
ipfw pipe 1 config bw 100Kbit/s queue 5

To remove the pipe you simply do:

ipfw delete pipe 1
Pipes can become really useful in conjunction with Alternate Queueing ALTQ because when having an asymmetric link the normal behaviour of a TCP/IP stack is to equally balance up and downstream which results in a huge bandwidth waste for the downstream channel. There is an excellent article describing the problem and a possible solution using ALTQ available. Unfortunately ALTQ is still not part of the default FreeBSD, you have to fetch and apply the patch to the sources all by yourself.

01.1000 How to configure/install mail services?

This is naturally also one of the subjects that has been addressed in the FreeBSD Handbook, Chapter 20 is the place to look at. The default behaviour is to accept mail only from localhost and to relay it using the standard delivery route. I modified only the delivery method to use our 'smart' relay server mail.mydomain.org by modifying /etc/mail/sendmail.cf, changing the line DS to DSmail . Take care of keeping this modification when using mergemaster after an update!

As we have our own dedicated mailserver in the subnet we should make use of it by forwarding all mail to it using .forward(5). We can still read our mail locally by using pine and setting the following option in the .pinerc: inbox-path={mail.mydomain.org/imap/user=username}INBOX whereby username should be replaced with your loginname at the mailserver.

01.1001 Something is not working, where can I see what's going on?

FreeBSD uses the standard syslogd(8) so /etc/syslog.conf(5) is good place to start looking for logfiles. Everything should reside below /var/log/, I've modified the config so that there is an all.log containing everything syslog receives. It is possible to filter for certain applications when creating logfiles an example is /var/log/ppp.log which contains solely messages from the pppd. So in case the Internet connections is having problems you can either look into /var/log/ppp.log or /var/log/all.log. Speaking of it, here is an example what it looks like when the provider is having problems:

Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: ** Too many ECHO LQR packets lost ** 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: open -> lcp 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: bundle: Terminate 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: Disconnected! 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: lcp -> logout 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: Disconnected! 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: logout -> hangup 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: Connect time: 15094 secs: 9360373 octets in, 3401578 octets out 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: 1878741 packets in, 2297267 packets out 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase:  total 845 bytes/sec, peak 96606 bytes/sec on Sun Jan  5 02:33:59 2003 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: hangup -> opening 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: bundle: Establish 
Jan  5 06:34:01 gateway ppp[66]: tun0: Phase: deflink: Enter pause (3) for redialing. 
Jan  5 06:34:01 gateway ppp[66]: tun0: Chat: deflink: Reconnect try 4 of 0 

after that you will probably see lots of these:

Jan  5 06:50:16 gateway ppp[66]: tun0: Chat: deflink: Redial timer expired. 
Jan  5 06:50:16 gateway ppp[66]: tun0: Phase: deflink: Connected! 
Jan  5 06:50:16 gateway ppp[66]: tun0: Phase: deflink: opening -> dial 
Jan  5 06:50:16 gateway ppp[66]: tun0: Phase: deflink: dial -> carrier 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase: deflink: Disconnected! 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase: deflink: carrier -> hangup 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase: deflink: Connect time: 5 secs: 0 octets in, 0 octets out 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase: deflink: 1878741 packets in, 2297267 packets out 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase:  total 0 bytes/sec, peak 0 bytes/sec on Sun Jan  5 06:50:16 2003 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase: deflink: hangup -> opening 
Jan  5 06:50:21 gateway ppp[66]: tun0: Phase: deflink: Enter pause (30) for redialing. 

and when it's finally working again it will look something like this:

Jan  5 02:22:27 gateway ppp[66]: tun0: Chat: deflink: Redial timer expired. 
Jan  5 02:22:27 gateway ppp[66]: tun0: Phase: deflink: Connected! 
Jan  5 02:22:27 gateway ppp[66]: tun0: Phase: deflink: opening -> dial 
Jan  5 02:22:27 gateway ppp[66]: tun0: Phase: deflink: dial -> carrier 
Jan  5 02:22:28 gateway ppp[66]: tun0: Phase: Received NGM_PPPOE_ACNAME (hook "STGX12-erx") 
Jan  5 02:22:28 gateway ppp[66]: tun0: Phase: Received NGM_PPPOE_SESSIONID 
Jan  5 02:22:28 gateway ppp[66]: tun0: Phase: Received NGM_PPPOE_SUCCESS 
Jan  5 02:22:28 gateway ppp[66]: tun0: Phase: deflink: carrier -> login 
Jan  5 02:22:28 gateway ppp[66]: tun0: Phase: deflink: login -> lcp 
Jan  5 02:22:29 gateway ppp[66]: tun0: Warning: deflink: Reducing configured MRU from 1500 to 1492 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: bundle: Authenticate 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: deflink: his = PAP, mine = none 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: Pap Output: username ******** 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: Pap Input: SUCCESS () 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: deflink: lcp -> open 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: bundle: Network 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: deflink: IPV6CP protocol reject closes IPV6CP ! 
Jan  5 02:22:29 gateway ppp[66]: tun0: Phase: deflink: IPV6CP protocol reject closes IPV6CP ! 
Jan  5 02:22:29 gateway ppp[66]: tun0: Command: MYADDR: add 0 0 HISADDR 
Jan  5 02:22:29 gateway ppp[66]: tun0: Warning: Add route failed: 0.0.0.0/0 already exists 
Jan  5 02:22:29 gateway ppp[66]: tun0: Command: MYADDR: !bg /etc/ppp/nat_update.sh 
Jan  5 02:22:29 gateway ppp[66]: tun0: Command: MYADDR: !bg /usr/local/sbin/ddclient 
Jan  5 02:22:29 gateway ppp[66]: tun0: Command: MYADDR: !bg /etc/ppp/pppip-tx 
Jan  5 02:22:32 gateway ppp[66]: tun0: Phase: deflink: IPV6CP protocol reject closes IPV6CP ! 

The next question that arises is how do we keep the logfiles from growing ad infinitum? Well this is what newsyslog(8) and /etc/newsyslog.conf are for. It rolls over logfile at the specified interval or logfile size.

10.0000 Backup/Restore?

We are using afbackup for the backup. We have 10 tapes used in circle and once a month we do a full backup to tapes which will be stored at another location. So our backup plan looks like this:

Mo-Do: incremental backup to the tapeset
Fr: full backup to the tapeset
once a month: full backup to different tapes not in the tapeset

The tool itself is installed in /usr/local/afbackup and divided into a server and a client. As our backup strategy is not directly supported there are some small things you have to take care of. afbackup will try to prevent you from overwriting so called precious tapes, these are all tapes listed in /usr/local/afbackup/server/var/precious_tapes, so you have edit this file from time to time to enable the reuse of the tapes from the tapeset (labeled 1-10). When doing the monthly backup you should label the tapes before starting the backup (use server/bin/label_tape), if you do it during backup you have to use the -f flag to force the labelling although the drive is in use.

To manually start a full or incremental backup I recommend using the backup login, this will give you a simple menu from which you chose what you want to do.

To restore a file from a backup use client/bin/afrestore the usage is explained in detail in the manpage here is just a simple example:

/usr/local/afbackup/client/bin/afrestore -C /home/restore home/projects/projects/public_html
which would restore home/projects/projects/public_html to /home/restore.

Related links:

  1. The FreeBSD project
  2. The FreeBSD Handbook
  3. FreeBSD Hypertext Man Pages
  4. The CVS Repository
  5. various links to FreeBSD related resources
  6. PPPoE performance under Linux and BSDs
  7. pf - The OpenBSD Packet Filter
  8. ALTQ: Alternate Queueing for BSD UNIX
  9. Prioritizing empty TCP ACKs with pf and ALTQ
  10. afbackup - a client-server backup system
  11. FreeBSD Ports Tricks
  12. portupgrade - a feature-rich port designed to help you get the most out of the ports collection.
  13. A Newbie's Guide to Setting up PF on OpenBSD 3.x
  14. Installing a secure BSD System
  15. Setting Up Squid on FreeBSD