diff --git a/en_US.ISO8859-1/books/handbook/Makefile b/en_US.ISO8859-1/books/handbook/Makefile
index ab5f06952d..60f5dff022 100644
--- a/en_US.ISO8859-1/books/handbook/Makefile
+++ b/en_US.ISO8859-1/books/handbook/Makefile
@@ -1,73 +1,72 @@
#
-# $FreeBSD: doc/en_US.ISO_8859-1/books/handbook/Makefile,v 1.30 2000/12/01 00:58:11 jim Exp $
+# $FreeBSD: doc/en_US.ISO_8859-1/books/handbook/Makefile,v 1.31 2001/02/28 22:50:05 nik Exp $
#
# Build the FreeBSD Handbook.
#
MAINTAINER=nik@FreeBSD.org
DOC?= book
FORMATS?= html-split
INSTALL_COMPRESSED?= gz
INSTALL_ONLY_COMPRESSED?=
#
# SRCS lists the individual SGML files that make up the document. Changes
# to any of these files will force a rebuild
#
# SGML content
SRCS= book.sgml
SRCS+= advanced-networking/chapter.sgml
SRCS+= backups/chapter.sgml
SRCS+= basics/chapter.sgml
SRCS+= bibliography/chapter.sgml
SRCS+= boot/chapter.sgml
SRCS+= contrib/chapter.sgml
SRCS+= cutting-edge/chapter.sgml
SRCS+= disks/chapter.sgml
SRCS+= eresources/chapter.sgml
SRCS+= hw/chapter.sgml
SRCS+= install/chapter.sgml
-SRCS+= internals/chapter.sgml
SRCS+= introduction/chapter.sgml
SRCS+= kernelconfig/chapter.sgml
SRCS+= kerneldebug/chapter.sgml
SRCS+= kernelopts/chapter.sgml
SRCS+= l10n/chapter.sgml
SRCS+= linuxemu/chapter.sgml
SRCS+= mail/chapter.sgml
SRCS+= mirrors/chapter.sgml
SRCS+= pgpkeys/chapter.sgml
SRCS+= policies/chapter.sgml
SRCS+= ppp-and-slip/chapter.sgml
SRCS+= printing/chapter.sgml
SRCS+= security/chapter.sgml
SRCS+= serialcomms/chapter.sgml
SRCS+= sound/chapter.sgml
SRCS+= staff/chapter.sgml
SRCS+= users/chapter.sgml
SRCS+= x11/chapter.sgml
SRCS+= ports/chapter.sgml
# Entities
SRCS+= authors.ent
SRCS+= chapters.ent
SRCS+= mailing-lists.ent
SYMLINKS= ${DESTDIR} index.html handbook.html
# XXX The Handbook build currently overflows some internal, hardcoded
# limits in pdftex. Until we split the Handbook up, build the PDF
# version using ps2pdf instead of pdftex.
book.tex-pdf:
touch book.tex-pdf
book.pdf: book.ps
ps2pdf book.ps book.pdf
DOC_PREFIX?= ${.CURDIR}/../../..
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/en_US.ISO8859-1/books/handbook/book.sgml b/en_US.ISO8859-1/books/handbook/book.sgml
index 66230e5424..dcd4528417 100644
--- a/en_US.ISO8859-1/books/handbook/book.sgml
+++ b/en_US.ISO8859-1/books/handbook/book.sgml
@@ -1,135 +1,134 @@
%man;
%bookinfo;
%chapters;
%authors;
%mailing-lists;
%newsgroups;
]>
FreeBSD Handbook
The FreeBSD Documentation Project
February 1999
1995
1996
1997
1998
1999
2000
2001
The FreeBSD Documentation Project
&bookinfo.legalnotice;
Welcome to FreeBSD! This handbook covers the installation and day
to day use of FreeBSD Release &rel.current;.
This manual is a work in progress and is the work
of many individuals. Many sections do not yet exist and some of those
that do exist need to be updated. If you are interested in helping
with this project, send email to the &a.doc;. The latest version of
this document is always available from the FreeBSD World Wide Web server.
It may also be downloaded in a variety of formats and compression
options from the FreeBSD FTP
server or one of the numerous mirror sites. If you would prefer
to have a hard copy of the handbook, you can purchase one at the
FreeBSD Mall. You
may also want to Search the
Handbook.
Getting Started
&chap.introduction;
&chap.install;
&chap.basics;
&chap.ports;
System Administration
&chap.boot;
&chap.users;
&chap.kernelconfig;
&chap.security;
&chap.printing;
&chap.disks;
&chap.backups;
&chap.x11;
&chap.l10n;
&chap.sound;
Network Communications
&chap.serialcomms;
&chap.ppp-and-slip;
&chap.advanced-networking;
&chap.mail;
Advanced topics
&chap.cutting-edge;
&chap.contrib;
&chap.policies;
&chap.kernelopts;
&chap.kerneldebug;
&chap.linuxemu;
- &chap.internals;
Appendices
&chap.mirrors;
&chap.bibliography;
&chap.eresources;
&chap.staff;
&chap.pgpkeys;
&chap.hw;
diff --git a/en_US.ISO8859-1/books/handbook/chapters.ent b/en_US.ISO8859-1/books/handbook/chapters.ent
index 45d2854904..85d62c57ae 100644
--- a/en_US.ISO8859-1/books/handbook/chapters.ent
+++ b/en_US.ISO8859-1/books/handbook/chapters.ent
@@ -1,51 +1,50 @@
-
diff --git a/en_US.ISO8859-1/books/handbook/security/chapter.sgml b/en_US.ISO8859-1/books/handbook/security/chapter.sgml
index 67fb4a8239..cdbd04568c 100644
--- a/en_US.ISO8859-1/books/handbook/security/chapter.sgml
+++ b/en_US.ISO8859-1/books/handbook/security/chapter.sgml
@@ -1,2848 +1,2850 @@
Security
Much of this chapter has been taken from the
&man.security.7; man page, originally written by
&a.dillon;.
Synopsis
The following chapter will provide a basic introduction to
system security concepts, some general good rules of thumb, and some
advanced topics such as S/Key, OpenSSL, Kerberos, and others.
Introduction
Security is a function that begins and ends with the system
administrator. While all BSD UNIX multi-user systems have some
inherent security, the job of building and maintaining additional
security mechanisms to keep those users honest
is
probably one of the single largest undertakings of the sysadmin.
Machines are only as secure as you make them, and security concerns
are ever competing with the human necessity for convenience. UNIX
systems, in general, are capable of running a huge number of
simultaneous processes and many of these processes operate as
servers – meaning that external entities can connect and talk
to them. As yesterday's mini-computers and mainframes become
today's desktops, and as computers become networked and
internetworked, security becomes an ever bigger issue.
Security is best implemented through a layered
onion
approach. In a nutshell, what you want to do is
to create as many layers of security as are convenient and then
carefully monitor the system for intrusions. You do not want to
overbuild your security or you will interfere with the detection
side, and detection is one of the single most important aspects of
any security mechanism. For example, it makes little sense to set
the schg flags (see &man.chflags.1;) on every system binary because
while this may temporarily protect the binaries, it prevents an
attacker who has broken in from making an easily detectable change
that may result in your security mechanisms not detecting the attacker
at all.
System security also pertains to dealing with various forms of
attack, including attacks that attempt to crash or otherwise make a
system unusable but do not attempt to break root. Security concerns
can be split up into several categories:
Denial of service attacks.
User account compromises.
Root compromise through accessible servers.
Root compromise via user accounts.
Backdoor creation.
A denial of service attack is an action that deprives the
machine of needed resources. Typically, D.O.S. attacks are
brute-force mechanisms that attempt to crash or otherwise make a
machine unusable by overwhelming its servers or network stack. Some
D.O.S. attacks try to take advantages of bugs in the networking
stack to crash a machine with a single packet. The latter can only
be fixed by applying a bug fix to the kernel. Attacks on servers
can often be fixed by properly specifying options to limit the load
the servers incur on the system under adverse conditions.
Brute-force network attacks are harder to deal with. A
spoofed-packet attack, for example, is nearly impossible to stop
short of cutting your system off from the internet. It may not be
able to take your machine down, but it can fill up internet
pipe.
A user account compromise is even more common then a D.O.S.
attack. Many sysadmins still run standard telnetd, rlogind, rshd,
and ftpd servers on their machines. These servers, by default, do
not operate over encrypted connections. The result is that if you
have any moderate-sized user base, one or more of your users logging
into your system from a remote location (which is the most common
and convenient way to login to a system) will have his or her
password sniffed. The attentive system admin will analyze his
remote access logs looking for suspicious source addresses even for
successful logins.
One must always assume that once an attacker has access to a
user account, the attacker can break root. However, the reality is
that in a well secured and maintained system, access to a user
account does not necessarily give the attacker access to root. The
distinction is important because without access to root the attacker
cannot generally hide his tracks and may, at best, be able to do
nothing more then mess with the user's files or crash the machine.
User account compromises are very common because users tend not to
take the precautions that sysadmins take.
System administrators must keep in mind that there are
potentially many ways to break root on a machine. The attacker
may know the root password, the attacker may find a bug in a
root-run server and be able to break root over a network
connection to that server, or the attacker may know of a bug in
an suid-root program that allows the attacker to break root once
he has broken into a user's account. If an attacker has found a
a way to break root on a machine, the attacker may not have a need
to install a backdoor. Many of the root holes
found and closed to date involve a considerable amount of work
by the attacker to cleanup after himself, so most attackers install
backdoors. Backdoors provide the attacker with a way to easily
regain root access to the system, but it also gives the smart
system administrator a convenient way to detect the intrusion.
Making it impossible for an attacker to install a backdoor may
actually be detrimental to your security because it will not
close off the hole the attacker found to break in the first
place.
Security remedies should always be implemented with a
multi-layered onion peel
approach and can be
categorized as follows:
Securing root and staff accounts.
Securing root – root-run servers and suid/sgid
binaries.
Securing user accounts.
Securing the password file.
Securing the kernel core, raw devices, and
filesystems.
Quick detection of inappropriate changes made to the
system.
Paranoia.
The next section of this chapter will cover the above bullet
items in greater depth.
Securing FreeBSD
The sections that follow will cover the methods of securing your
FreeBSD system that were mentioned in the last section of this chapter.
Securing the root account and staff accounts
First off, do not bother securing staff accounts if you have
not secured the root account. Most systems have a password
assigned to the root account. The first thing you do is assume
that the password is always compromised.
This does not mean that you should remove the password. The
password is almost always necessary for console access to the
machine. What it does mean is that you should not make it
possible to use the password outside of the console or possibly
even with the &man.su.1; command. For example, make sure that
your pty's are specified as being unsecure in the
/etc/ttys file so that direct root logins
via telnet or rlogin are
disallowed. If using other login services such as
sshd, make sure that direct root logins
are disabled there as well. Consider every access method –
services such as FTP often fall through the cracks. Direct root
logins should only be allowed via the system console.
Of course, as a sysadmin you have to be able to get to root,
so we open up a few holes. But we make sure these holes require
additional password verification to operate. One way to make root
accessible is to add appropriate staff accounts to the
wheel group (in
/etc/group). The staff members placed in the
wheel group are allowed to
su to root. You should never give staff
members native wheel access by putting them in the
wheel group in their password entry. Staff
accounts should be placed in a staff group, and
then added to the wheel group via the
/etc/group file. Only those staff members
who actually need to have root access should be placed in the
wheel group. It is also possible, when using
an authentication method such as kerberos, to use kerberos'
.k5login file in the root account to allow a
&man.ksu.1; to root without having to place anyone at all in the
wheel group. This may be the better solution
since the wheel mechanism still allows an
intruder to break root if the intruder has gotten hold of your
password file and can break into a staff account. While having
the wheel mechanism is better then having
nothing at all, it is not necessarily the safest option.
An indirect way to secure the root account is to secure your
staff accounts by using an alternative login access method and
*'ing out the crypted password for the staff
accounts. This way an intruder may be able to steal the password
file but will not be able to break into any staff accounts (or,
indirectly, root, even if root has a crypted password associated
with it). Staff members get into their staff accounts through a
secure login mechanism such as &man.kerberos.1; or &man.ssh.1;
using a private/public key pair. When you use something like
kerberos, you generally must secure the machines which run the
kerberos servers and your desktop workstation. When you use a
public/private key pair with ssh, you
must generally secure the machine you are logging in
from (typically your workstation), but you
can also add an additional layer of protection to the key pair by
password protecting the keypair when you create it with
&man.ssh-keygen.1;. Being able to * out the
passwords for staff accounts also guarantees that staff members can
only login through secure access methods that you have setup. You
can thus force all staff members to use secure, encrypted
connections for all of their sessions which closes an important
hole used by many intruders: That of sniffing the network from an
unrelated, less secure machine.
The more indirect security mechanisms also assume that you are
logging in from a more restrictive server to a less restrictive
server. For example, if your main box is running all sorts of
servers, your workstation should not be running any. In order for
your workstation to be reasonably secure you should run as few
servers as possible, up to and including no servers at all, and
you should run a password-protected screen blanker. Of course,
given physical access to a workstation an attacker can break any
sort of security you put on it. This is definitely a problem that
you should consider but you should also consider the fact that the
vast majority of break-ins occur remotely, over a network, from
people who do not have physical access to your workstation or
servers.
Using something like kerberos also gives you the ability to
disable or change the password for a staff account in one place
and have it immediately effect all the machine the staff member
may have an account on. If a staff member's account gets
compromised, the ability to instantly change his password on all
machines should not be underrated. With discrete passwords,
changing a password on N machines can be a mess. You can also
impose re-passwording restrictions with kerberos: not only can a
kerberos ticket be made to timeout after a while, but the kerberos
system can require that the user choose a new password after a
certain period of time (say, once a month).
Securing Root-run Servers and SUID/SGID Binaries
The prudent sysadmin only runs the servers he needs to, no
more, no less. Be aware that third party servers are often the
most bug-prone. For example, running an old version of imapd or
popper is like giving a universal root ticket out to the entire
world. Never run a server that you have not checked out
carefully. Many servers do not need to be run as root. For
example, the ntalk,
comsat, and
finger daemons can be run in special
user sandboxes. A sandbox isn't perfect unless
you go to a large amount of trouble, but the onion approach to
security still stands: If someone is able to break in through
a server running in a sandbox, they still have to break out of the
sandbox. The more layers the attacker must break through, the
lower the likelihood of his success. Root holes have historically
been found in virtually every server ever run as root, including
basic system servers. If you are running a machine through which
people only login via sshd and never
login via telnetd or
rshd or
rlogind, then turn off those
services!
FreeBSD now defaults to running
ntalkd,
comsat, and
finger in a sandbox. Another program
which may be a candidate for running in a sandbox is &man.named.8;.
/etc/defaults/rc.conf includes the arguments
necessary to run named in a sandbox in a
commented-out form. Depending on whether you are installing a new
system or upgrading an existing system, the special user accounts
used by these sandboxes may not be installed. The prudent
sysadmin would research and implement sandboxes for servers
whenever possible.
There are a number of other servers that typically do not run
in sandboxes: sendmail,
popper,
imapd, ftpd,
and others. There are alternatives to some of these, but
installing them may require more work then you are willing to
perform (the convenience factor strikes again). You may have to
run these servers as root and rely on other mechanisms to detect
break-ins that might occur through them.
The other big potential root hole in a system are the
suid-root and sgid binaries installed on the system. Most of
these binaries, such as rlogin, reside
in /bin, /sbin,
/usr/bin, or /usr/sbin.
While nothing is 100% safe, the system-default suid and sgid
binaries can be considered reasonably safe. Still, root holes are
occasionally found in these binaries. A root hole was found in
Xlib in 1998 that made
xterm (which is typically suid)
vulnerable. It is better to be safe then sorry and the prudent
sysadmin will restrict suid binaries that only staff should run to
a special group that only staff can access, and get rid of
(chmod 000) any suid binaries that nobody uses.
A server with no display generally does not need an
xterm binary. Sgid binaries can be
almost as dangerous. If an intruder can break an sgid-kmem binary
the intruder might be able to read /dev/kmem
and thus read the crypted password file, potentially compromising
any passworded account. Alternatively an intruder who breaks
group kmem can monitor keystrokes sent through
pty's, including pty's used by users who login through secure
methods. An intruder that breaks the tty group can write to
almost any user's tty. If a user is running a terminal program or
emulator with a keyboard-simulation feature, the intruder can
potentially generate a data stream that causes the user's terminal
to echo a command, which is then run as that user.
Securing User Accounts
User accounts are usually the most difficult to secure. While
you can impose Draconian access restrictions on your staff and
* out their passwords, you may not be able to
do so with any general user accounts you might have. If you do
have sufficient control then you may win out and be able to secure
the user accounts properly. If not, you simply have to be more
vigilant in your monitoring of those accounts. Use of
ssh and kerberos for user accounts is
more problematic due to the extra administration and technical
support required, but still a very good solution compared to a
crypted password file.
Securing the Password File
The only sure fire way is to * out as many
passwords as you can and use ssh or
kerberos for access to those accounts. Even though the crypted
password file (/etc/spwd.db) can only be read
by root, it may be possible for an intruder to obtain read access
to that file even if the attacker cannot obtain root-write
access.
Your security scripts should always check for and report
changes to the password file (see Checking file integrity
below).
Securing the Kernel Core, Raw Devices, and
Filesystems
If an attacker breaks root he can do just about anything, but
there are certain conveniences. For example, most modern kernels
have a packet sniffing device driver built in. Under FreeBSD it
is called the bpf device. An intruder
will commonly attempt to run a packet sniffer on a compromised
machine. You do not need to give the intruder the capability and
most systems should not have the bpf device compiled in.
But even if you turn off the bpf device, you still have
/dev/mem and /dev/kmem
to worry about. For that matter, the intruder can still write to
raw disk devices. Also, there is another kernel feature called
the module loader, &man.kldload.8;. An enterprising intruder can
use a KLD module to install his own bpf device or other sniffing
device on a running kernel. To avoid these problems you have to
run the kernel at a higher secure level, at least securelevel 1.
The securelevel can be set with a sysctl on
the kern.securelevel variable. Once you have
set the securelevel to 1, write access to raw devices will be
denied and special chflags flags, such as schg,
will be enforced. You must also ensure that the
schg flag is set on critical startup binaries,
directories, and script files – everything that gets run up
to the point where the securelevel is set. This might be overdoing
it, and upgrading the system is much more difficult when you
operate at a higher secure level. You may compromise and run the
system at a higher secure level but not set the
schg flag for every system file and directory
under the sun. Another possibility is to simply mount
/ and /usr read-only.
It should be noted that being too draconian in what you attempt to
protect may prevent the all-important detection of an
intrusion.
Checking File Integrity: Binaries, Configuration Files,
Etc.
When it comes right down to it, you can only protect your core
system configuration and control files so much before the
convenience factor rears its ugly head. For example, using
chflags to set the schg bit
on most of the files in / and
/usr is probably counterproductive because
while it may protect the files, it also closes a detection window.
The last layer of your security onion is perhaps the most
important – detection. The rest of your security is pretty
much useless (or, worse, presents you with a false sense of
safety) if you cannot detect potential incursions. Half the job
of the onion is to slow down the attacker rather then stop him in
order to give the detection side of the equation a chance to catch
him in the act.
The best way to detect an incursion is to look for modified,
missing, or unexpected files. The best way to look for modified
files is from another (often centralized) limited-access system.
Writing your security scripts on the extra-secure limited-access
system makes them mostly invisible to potential attackers, and this
is important. In order to take maximum advantage you generally
have to give the limited-access box significant access to the
other machines in the business, usually either by doing a
read-only NFS export of the other machines to the limited-access
box, or by setting up ssh keypairs to
allow the limit-access box to ssh to
the other machines. Except for its network traffic, NFS is the
least visible method – allowing you to monitor the
filesystems on each client box virtually undetected. If your
limited-access server is connected to the client boxes through a
switch, the NFS method is often the better choice. If your
limited-access server is connected to the client boxes through a
hub or through several layers of routing, the NFS method may be
too insecure (network-wise) and using
ssh may be the better choice even with
the audit-trail tracks that ssh
lays.
Once you give a limit-access box at least read access to the
client systems it is supposed to monitor, you must write scripts
to do the actual monitoring. Given an NFS mount, you can write
scripts out of simple system utilities such as &man.find.1; and
&man.md5.1;. It is best to physically md5 the client-box files
boxes at least once a day, and to test control files such as those
found in /etc and
/usr/local/etc even more often. When
mismatches are found relative to the base md5 information the
limited-access machine knows is valid, it should scream at a
sysadmin to go check it out. A good security script will also
check for inappropriate suid binaries and for new or deleted files
on system partitions such as / and
/usr.
When using ssh rather then NFS,
writing the security script is much more difficult. You
essentially have to scp the scripts to the client box in order to
run them, making them visible, and for safety you also need to
scp the binaries (such as find) that those
scripts use. The ssh daemon on the
client box may already be compromised. All in all, using
ssh may be necessary when running over
unsecure links, but it's also a lot harder to deal with.
A good security script will also check for changes to user and
staff members access configuration files:
.rhosts, .shosts,
.ssh/authorized_keys and so forth…
files that might fall outside the purview of the
MD5 check.
If you have a huge amount of user disk space it may take too
long to run through every file on those partitions. In this case,
setting mount flags to disallow suid binaries and devices on those
partitions is a good idea. The nodev and
nosuid options (see &man.mount.8;) are what you
want to look into. You should probably scan them anyway at least
once a week, since the object of this layer is to detect a break-in
whether or not the break-in is effective.
Process accounting (see &man.accton.8;) is a relatively
low-overhead feature of the operating system which might help
as a post-break-in evaluation mechanism. It is especially
useful in tracking down how an intruder has actually broken into
a system, assuming the file is still intact after the break-in
occurs.
Finally, security scripts should process the log files and the
logs themselves should be generated in as secure a manner as
possible – remote syslog can be very useful. An intruder
tries to cover his tracks, and log files are critical to the
sysadmin trying to track down the time and method of the initial
break-in. One way to keep a permanent record of the log files is
to run the system console to a serial port and collect the
information on a continuing basis through a secure machine
monitoring the consoles.
Paranoia
A little paranoia never hurts. As a rule, a sysadmin can add
any number of security features as long as they do not effect
convenience, and can add security features that do effect
convenience with some added thought. Even more importantly, a
security administrator should mix it up a bit – if you use
recommendations such as those given by this document verbatim, you
give away your methodologies to the prospective attacker who also
has access to this document.
Denial of Service Attacks
This section covers Denial of Service attacks. A DOS attack
is typically a packet attack. While there is not much you can do
about modern spoofed packet attacks that saturate your network,
you can generally limit the damage by ensuring that the attacks
cannot take down your servers.
Limiting server forks.
Limiting springboard attacks (ICMP response attacks, ping
broadcast, etc.).
Kernel Route Cache.
A common DOS attack is against a forking server that attempts
to cause the server to eat processes, file descriptors, and memory
until the machine dies. Inetd (see &man.inetd.8;) has several
options to limit this sort of attack. It should be noted that
while it is possible to prevent a machine from going down it is
not generally possible to prevent a service from being disrupted
by the attack. Read the inetd manual page carefully and pay
specific attention to the , ,
and options. Note that spoofed-IP attacks
will circumvent the option to inetd, so
typically a combination of options must be used. Some standalone
servers have self-fork-limitation parameters.
Sendmail has its
option which tends to work
much better than trying to use sendmail's load limiting options
due to the load lag. You should specify a
MaxDaemonChildren parameter when you start
sendmail high enough to handle your
expected load but no so high that the computer cannot handle that
number of sendmails without falling on
its face. It is also prudent to run sendmail in queued mode
() and to run the daemon
(sendmail -bd) separate from the queue-runs
(sendmail -q15m). If you still want real-time
delivery you can run the queue at a much lower interval, such as
, but be sure to specify a reasonable
MaxDaemonChildren option for that sendmail to
prevent cascade failures.
Syslogd can be attacked directly
and it is strongly recommended that you use the
option whenever possible, and the option
otherwise.
You should also be fairly careful with connect-back services
such as tcpwrapper's reverse-identd,
which can be attacked directly. You generally do not want to use
the reverse-ident feature of
tcpwrappers for this reason.
It is a very good idea to protect internal services from
external access by firewalling them off at your border routers.
The idea here is to prevent saturation attacks from outside your
LAN, not so much to protect internal services from network-based
root compromise. Always configure an exclusive firewall, i.e.,
firewall everything except ports A, B,
C, D, and M-Z
. This way you can firewall off all of your
low ports except for certain specific services such as
named (if you are primary for a zone),
ntalkd,
sendmail, and other internet-accessible
services. If you try to configure the firewall the other way
– as an inclusive or permissive firewall, there is a good
chance that you will forget to close
a couple of
services or that you will add a new internal service and forget
to update the firewall. You can still open up the high-numbered
port range on the firewall to allow permissive-like operation
without compromising your low ports. Also take note that FreeBSD
allows you to control the range of port numbers used for dynamic
binding via the various net.inet.ip.portrange
sysctl's (sysctl -a | fgrep
portrange), which can also ease the complexity of your
firewall's configuration. For example, you might use a normal
first/last range of 4000 to 5000, and a hiport range of 49152 to
65535, then block everything under 4000 off in your firewall
(except for certain specific internet-accessible ports, of
course).
Another common DOS attack is called a springboard attack
– to attack a server in a manner that causes the server to
generate responses which then overload the server, the local
network, or some other machine. The most common attack of this
nature is the ICMP ping broadcast attack.
The attacker spoofs ping packets sent to your LAN's broadcast
address with the source IP address set to the actual machine they
wish to attack. If your border routers are not configured to
stomp on ping's to broadcast addresses, your LAN winds up
generating sufficient responses to the spoofed source address to
saturate the victim, especially when the attacker uses the same
trick on several dozen broadcast addresses over several dozen
different networks at once. Broadcast attacks of over a hundred
and twenty megabits have been measured. A second common
springboard attack is against the ICMP error reporting system.
By constructing packets that generate ICMP error responses, an
attacker can saturate a server's incoming network and cause the
server to saturate its outgoing network with ICMP responses. This
type of attack can also crash the server by running it out of
mbuf's, especially if the server cannot drain the ICMP responses
it generates fast enough. The FreeBSD kernel has a new kernel
compile option called ICMP_BANDLIM which limits the effectiveness
of these sorts of attacks. The last major class of springboard
attacks is related to certain internal inetd services such as the
udp echo service. An attacker simply spoofs a UDP packet with the
source address being server A's echo port, and the destination
address being server B's echo port, where server A and B are both
on your LAN. The two servers then bounce this one packet back and
forth between each other. The attacker can overload both servers
and their LANs simply by injecting a few packets in this manner.
Similar problems exist with the internal chargen port. A
competent sysadmin will turn off all of these inetd-internal test
services.
Spoofed packet attacks may also be used to overload the kernel
route cache. Refer to the net.inet.ip.rtexpire,
rtminexpire, and rtmaxcache
sysctl parameters. A spoofed packet attack
that uses a random source IP will cause the kernel to generate a
temporary cached route in the route table, viewable with
netstat -rna | fgrep W3. These routes
typically timeout in 1600 seconds or so. If the kernel detects
that the cached route table has gotten too big it will dynamically
reduce the rtexpire but will never decrease it to less then
rtminexpire. There are two problems:
The kernel does not react quickly enough when a lightly
loaded server is suddenly attacked.
The rtminexpire is not low enough for
the kernel to survive a sustained attack.
If your servers are connected to the internet via a T3 or
better it may be prudent to manually override both
rtexpire and rtminexpire
via &man.sysctl.8;. Never set either parameter to zero (unless
you want to crash the machine :-). Setting both
parameters to 2 seconds should be sufficient to protect the route
table from attack.
Access Issues with Kerberos and SSH
There are a few issues with both kerberos and
ssh that need to be addressed if
you intend to use them. Kerberos V is an excellent
authentication protocol but there are bugs in the kerberized
telnet and
rlogin applications that make them
unsuitable for dealing with binary streams. Also, by default
kerberos does not encrypt a session unless you use the
option. ssh
encrypts everything by default.
ssh works quite well in every
respect except that it forwards encryption keys by default. What
this means is that if you have a secure workstation holding keys
that give you access to the rest of the system, and you
ssh to an unsecure machine, your keys
becomes exposed. The actual keys themselves are not exposed, but
ssh installs a forwarding port for the
duration of your login and if a attacker has broken root on the
unsecure machine he can utilize that port to use your keys to gain
access to any other machine that your keys unlock.
We recommend that you use ssh in
combination with kerberos whenever possible for staff logins.
ssh can be compiled with kerberos
support. This reduces your reliance on potentially exposable
ssh keys while at the same time
protecting passwords via kerberos. ssh
keys should only be used for automated tasks from secure machines
(something that kerberos is unsuited to). We also recommend that
you either turn off key-forwarding in the
ssh configuration, or that you make use
of the from=IP/DOMAIN option that
ssh allows in its
authorized_keys file to make the key only
usable to entities logging in from specific machines.
DES, MD5, and Crypt
Parts rewritten and updated by &a.unfurl;, 21 March
2000.
Every user on a UNIX system has a password associated with
their account. It seems obvious that these passwords need to be
known only to the user and the actual operating system. In
order to keep these passwords secret, they are encrypted with
what is known as a one-way hash
, that is, they can
only be easily encrypted but not decrypted. In other words, what
we told you a moment ago was obvious is not even true: the
operating system itself does not really know
the password. It only knows the encrypted
form of the password. The only way to get the
plain-text
password is by a brute force search of the
space of possible passwords.
Unfortunately the only secure way to encrypt passwords when
UNIX came into being was based on DES, the Data Encryption
Standard. This is not such a problem for users that live in
the US, but since the source code for DES could not be exported
outside the US, FreeBSD had to find a way to both comply with
US law and retain compatibility with all the other UNIX
variants that still use DES.
The solution was to divide up the encryption libraries
so that US users could install the DES libraries and use
DES but international users still had an encryption method
that could be exported abroad. This is how FreeBSD came to
use MD5 as its default encryption method. MD5 is believed to
be more secure than DES, so installing DES is offered primarily
for compatibility reasons.
Recognizing your crypt mechanism
It is pretty easy to identify which encryption method
FreeBSD is set up to use. Examining the encrypted passwords in
the /etc/master.passwd file is one way.
Passwords encrypted with the MD5 hash are longer than those with
encrypted with the DES hash and also begin with the characters
$1$. DES password strings do not
have any particular identifying characteristics, but they are
shorter than MD5 passwords, and are coded in a 64-character
alphabet which does not include the $
character, so a relatively short string which does not begin with
a dollar sign is very likely a DES password.
The libraries can identify the passwords this way as well.
As a result, the DES libraries are able to identify MD5
passwords, and use MD5 to check passwords that were encrypted
that way, and DES for the rest. They are able to do this
because the DES libraries also contain MD5. Unfortunately, the
reverse is not true, so the MD5 libraries cannot authenticate
passwords that were encrypted with DES.
Identifying which library is being used by the programs on
your system is easy as well. Any program that uses crypt is linked
against libcrypt which for each type of library is a symbolic link
to the appropriate implementation. For example, on a system using
the DES versions:
&prompt.user; ls -l /usr/lib/libcrypt*
lrwxr-xr-x 1 root wheel 13 Mar 19 06:56 libcrypt.a -> libdescrypt.a
lrwxr-xr-x 1 root wheel 18 Mar 19 06:56 libcrypt.so.2.0 -> libdescrypt.so.2.0
lrwxr-xr-x 1 root wheel 15 Mar 19 06:56 libcrypt_p.a -> libdescrypt_p.a
On a system using the MD5-based libraries, the same links will
be present, but the target will be libscrypt
rather than libdescrypt.
If you have installed the DES-capable crypt library
libdescrypt (e.g. by installing the
"crypto" distribution), then which password format will be used
for new passwords is controlled by the
passwd_format
login capability in
/etc/login.conf, which takes values of
either des
or md5
. See the
login.conf(5) manpage for more information about login
capabilities.
S/Key
S/Key is a one-time password scheme based on a one-way hash
function. FreeBSD uses the MD4 hash for compatibility but other
systems have used MD5 and DES-MAC. S/Key has been part of the
FreeBSD base system since version 1.1.5 and is also used on a
growing number of other operating systems. S/Key is a registered
trademark of Bell Communications Research, Inc.
There are three different sorts of passwords which we will talk
about in the discussion below. The first is your usual UNIX-style or
Kerberos password; we will call this a UNIX password
.
The second sort is the one-time password which is generated by the
S/Key key program and accepted by the
keyinit program and the login prompt; we will
call this a one-time password
. The final sort of
password is the secret password which you give to the
key program (and sometimes the
keyinit program) which it uses to generate
one-time passwords; we will call it a secret password
or just unqualified password
.
The secret password does not have anything to do with your UNIX
password; they can be the same but this is not recommended. S/Key
secret passwords are not limited to 8 characters like UNIX passwords,
they can be as long as you like. Passwords of six or seven word
long phrases are fairly common. For the most part, the S/Key system
operates completely independently of the UNIX password
system.
Besides the password, there are two other pieces of data that
are important to S/Key. One is what is known as the
seed
or key
and consists of two letters
and five digits. The other is what is called the iteration
count
and is a number between 1 and 100. S/Key creates the
one-time password by concatenating the seed and the secret password,
then applying the MD4 hash as many times as specified by the
iteration count and turning the result into six short English words.
These six English words are your one-time password. The
login and su programs keep
track of the last one-time password used, and the user is
authenticated if the hash of the user-provided password is equal to
the previous password. Because a one-way hash is used it is
impossible to generate future one-time passwords if a successfully
used password is captured; the iteration count is decremented after
each successful login to keep the user and the login program in
sync. When the iteration count gets down to 1 S/Key must be
reinitialized.
There are four programs involved in the S/Key system which we
will discuss below. The key program accepts an
iteration count, a seed, and a secret password, and generates a
one-time password. The keyinit program is used
to initialized S/Key, and to change passwords, iteration counts, or
seeds; it takes either a secret password, or an iteration count,
seed, and one-time password. The keyinfo program
examines the /etc/skeykeys file and prints out
the invoking user's current iteration count and seed. Finally, the
login and su programs contain
the necessary logic to accept S/Key one-time passwords for
authentication. The login program is also
capable of disallowing the use of UNIX passwords on connections
coming from specified addresses.
There are four different sorts of operations we will cover. The
first is using the keyinit program over a secure
connection to set up S/Key for the first time, or to change your
password or seed. The second operation is using the
keyinit program over an insecure connection, in
conjunction with the key program over a secure
connection, to do the same. The third is using the
key program to log in over an insecure
connection. The fourth is using the key program
to generate a number of keys which can be written down or printed
out to carry with you when going to some location without secure
connections to anywhere.
Secure connection initialization
To initialize S/Key for the first time, change your password,
or change your seed while logged in over a secure connection
(e.g., on the console of a machine or via ssh), use the
keyinit command without any parameters while
logged in as yourself:
&prompt.user; keyinit
Adding unfurl:
Reminder - Only use this method if you are directly connected.
If you are using telnet or rlogin exit with no password and use keyinit -s.
Enter secret password:
Again secret password:
ID unfurl s/key is 99 to17757
DEFY CLUB PRO NASH LACE SOFT
At the Enter secret password: prompt you
should enter a password or phrase. Remember, this is not the
password that you will use to login with, this is used to generate
your one-time login keys. The ID
line gives the
parameters of your particular S/Key instance; your login name, the
iteration count, and seed. When logging in with S/Key, the system
will remember these parameters and present them back to you so you
do not have to remember them. The last line gives the particular
one-time password which corresponds to those parameters and your
secret password; if you were to re-login immediately, this
one-time password is the one you would use.
Insecure connection initialization
To initialize S/Key or change your secret password over an
insecure connection, you will need to already have a secure
connection to some place where you can run the
key program; this might be in the form of a
desk accessory on a Macintosh, or a shell prompt on a machine you
trust. You will also need to make up an iteration count (100 is
probably a good value), and you may make up your own seed or use a
randomly-generated one. Over on the insecure connection (to the
machine you are initializing), use the keyinit
-s command:
&prompt.user; keyinit -s
Updating unfurl:
Old key: to17758
Reminder you need the 6 English words from the key command.
Enter sequence count from 1 to 9999: 100
Enter new key [default to17759]:
s/key 100 to 17759
s/key access password:
To accept the default seed (which the
keyinit program confusingly calls a
key), press return. Then before entering an
access password, move over to your secure connection or S/Key desk
accessory, and give it the same parameters:
&prompt.user; key 100 to17759
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: <secret password>
CURE MIKE BANE HIM RACY GORE
Now switch back over to the insecure connection, and copy the
one-time password generated by key over to the
keyinit program:
s/key access password:CURE MIKE BANE HIM RACY GORE
ID unfurl s/key is 100 to17759
CURE MIKE BANE HIM RACY GORE
The rest of the description from the previous section applies
here as well.
Generating a single one-time password
Once you've initialized S/Key, when you login you will be
presented with a prompt like this:
&prompt.user; telnet example.com
Trying 10.0.0.1...
Connected to example.com
Escape character is '^]'.
FreeBSD/i386 (example.com) (ttypa)
login: <username>
s/key 97 fw13894
Password:
As a side note, the S/Key prompt has a useful feature
(not shown here): if you press return at the password prompt, the
login program will turn echo on, so you can see what you are
typing. This can be extremely useful if you are attempting to
type in an S/Key by hand, such as from a printout. Also, if this
machine were configured to disallow UNIX passwords over a
connection from the source machine, the prompt would have also included
the annotation (s/key required), indicating
that only S/Key one-time passwords will be accepted.
At this point you need to generate your one-time password to
answer this login prompt. This must be done on a trusted system
that you can run the key command on. (There
are versions of the key program from DOS,
Windows and MacOS as well.) The key program
needs both the iteration count and the seed as command line
options. You can cut-and-paste these right from the login prompt
on the machine that you are logging in to.
On the trusted system:
&prompt.user; key 97 fw13894
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password:
WELD LIP ACTS ENDS ME HAAG
Now that you have your one-time password you can continue
logging in:
login: <username>
s/key 97 fw13894
Password: <return to enable echo>
s/key 97 fw13894
Password [echo on]: WELD LIP ACTS ENDS ME HAAG
Last login: Tue Mar 21 11:56:41 from 10.0.0.2 ...
This is the easiest mechanism if you have
a trusted machine. There is a Java S/Key key
applet, The Java OTP
Calculator, that you can download and run locally on any
Java supporting browser.
Generating multiple one-time passwords
Sometimes you have have to go places where you do not have
access to a trusted machine or secure connection. In this case,
it is possible to use the key command to
generate a number of one-time passwords before hand to be printed
out and taken with you. For example:
&prompt.user; key -n 5 30 zz99999
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: <secret password>
26: SODA RUDE LEA LIND BUDD SILT
27: JILT SPY DUTY GLOW COWL ROT
28: THEM OW COLA RUNT BONG SCOT
29: COT MASH BARR BRIM NAN FLAG
30: CAN KNEE CAST NAME FOLK BILK
The requests five keys in sequence, the
specifies what the last iteration number
should be. Note that these are printed out in
reverse order of eventual use. If you are
really paranoid, you might want to write the results down by hand;
otherwise you can cut-and-paste into lpr. Note
that each line shows both the iteration count and the one-time
password; you may still find it handy to scratch off passwords as
you use them.
Restricting use of UNIX passwords
Restrictions can be placed on the use of UNIX passwords based
on the host name, user name, terminal port, or IP address of a
login session. These restrictions can be found in the
configuration file /etc/skey.access. The
&man.skey.access.5; manual page has more info on the complete
format of the file and also details some security cautions to be
aware of before depending on this file for security.
If there is no /etc/skey.access file
(this is the FreeBSD default), then all users will be allowed to
use UNIX passwords. If the file exists, however, then all users
will be required to use S/Key unless explicitly permitted to do
otherwise by configuration statements in the
skey.access file. In all cases, UNIX
passwords are permitted on the console.
Here is a sample configuration file which illustrates the
three most common sorts of configuration statements:
permit internet 192.168.0.0 255.255.0.0
permit user fnord
permit port ttyd0
The first line (permit internet) allows
users whose IP source address (which is vulnerable to spoofing)
matches the specified value and mask, to use UNIX passwords. This
should not be considered a security mechanism, but rather, a means
to remind authorized users that they are using an insecure network
and need to use S/Key for authentication.
The second line (permit user) allows the
specified username, in this case fnord, to use
UNIX passwords at any time. Generally speaking, this should only
be used for people who are either unable to use the
key program, like those with dumb terminals, or
those who are uneducable.
The third line (permit port) allows all
users logging in on the specified terminal line to use UNIX
passwords; this would be used for dial-ups.
Kerberos
Contributed by &a.markm; (based on contribution by
&a.md;).
Kerberos is a network add-on system/protocol that allows users to
authenticate themselves through the services of a secure server.
Services such as remote login, remote copy, secure inter-system file
copying and other high-risk tasks are made considerably safer and more
controllable.
The following instructions can be used as a guide on how to set up
Kerberos as distributed for FreeBSD. However, you should refer to the
relevant manual pages for a complete description.
In FreeBSD, the Kerberos is not that from the original 4.4BSD-Lite,
distribution, but eBones, which had been previously ported to FreeBSD
1.1.5.1, and was sourced from outside the USA/Canada, and was thus
available to system owners outside those countries during the era
of restrictive export controls on cryptographic code from the USA.
Creating the initial database
This is done on the Kerberos server only. First make sure that
you do not have any old Kerberos databases around. You should change
to the directory /etc/kerberosIV and check that
only the following files are present:
&prompt.root; cd /etc/kerberosIV
&prompt.root; ls
README krb.conf krb.realms
If any additional files (such as principal.*
or master_key) exist, then use the
kdb_destroy command to destroy the old Kerberos
database, of if Kerberos is not running, simply delete the extra
files.
You should now edit the krb.conf and
krb.realms files to define your Kerberos realm.
In this case the realm will be GRONDAR.ZA and the
server is grunt.grondar.za. We edit or create
the krb.conf file:
&prompt.root; cat krb.conf
GRONDAR.ZA
GRONDAR.ZA grunt.grondar.za admin server
CS.BERKELEY.EDU okeeffe.berkeley.edu
ATHENA.MIT.EDU kerberos.mit.edu
ATHENA.MIT.EDU kerberos-1.mit.edu
ATHENA.MIT.EDU kerberos-2.mit.edu
ATHENA.MIT.EDU kerberos-3.mit.edu
LCS.MIT.EDU kerberos.lcs.mit.edu
TELECOM.MIT.EDU bitsy.mit.edu
ARC.NASA.GOV trident.arc.nasa.gov
In this case, the other realms do not need to be there. They are
here as an example of how a machine may be made aware of multiple
realms. You may wish to not include them for simplicity.
The first line names the realm in which this system works. The
other lines contain realm/host entries. The first item on a line is a
realm, and the second is a host in that realm that is acting as a
key distribution center
. The words admin
server following a hosts name means that host also
provides an administrative database server. For further explanation
of these terms, please consult the Kerberos man pages.
Now we have to add grunt.grondar.za
to the GRONDAR.ZA realm and also add an entry to
put all hosts in the .grondar.za
domain in the GRONDAR.ZA realm. The
krb.realms file would be updated as
follows:
&prompt.root; cat krb.realms
grunt.grondar.za GRONDAR.ZA
.grondar.za GRONDAR.ZA
.berkeley.edu CS.BERKELEY.EDU
.MIT.EDU ATHENA.MIT.EDU
.mit.edu ATHENA.MIT.EDU
Again, the other realms do not need to be there. They are here as
an example of how a machine may be made aware of multiple realms. You
may wish to remove them to simplify things.
The first line puts the specific system into
the named realm. The rest of the lines show how to default systems of
a particular subdomain to a named realm.
Now we are ready to create the database. This only needs to run
on the Kerberos server (or Key Distribution Center). Issue the
kdb_init command to do this:
&prompt.root; kdb_init
Realm name [default ATHENA.MIT.EDU ]: GRONDAR.ZA
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter Kerberos master key:
Now we have to save the key so that servers on the local machine
can pick it up. Use the kstash command to do
this.
&prompt.root; kstash
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
This saves the encrypted master password in
/etc/kerberosIV/master_key.
Making it all run
Two principals need to be added to the database for
each system that will be secured with Kerberos.
Their names are kpasswd and rcmd
These two principals are made for each system, with the instance being
the name of the individual system.
These daemons, kpasswd and
rcmd allow other systems to change Kerberos
passwords and run commands like rcp,
rlogin and rsh.
Now let's add these entries:
&prompt.root; kdb_edit
Opening database...
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Previous or default values are in [brackets] ,
enter return to leave the same, or new value.
Principal name: passwd
Instance: grunt
<Not found>, Create [y] ? y
Principal: passwd, Instance: grunt, kdc_key_ver: 1
New Password: <---- enter RANDOM here
Verifying password
New Password: <---- enter RANDOM here
Random password [y] ? y
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ?
Attributes [ 0 ] ?
Edit O.K.
Principal name: rcmd
Instance: grunt
<Not found>, Create [y] ?
Principal: rcmd, Instance: grunt, kdc_key_ver: 1
New Password: <---- enter RANDOM here
Verifying password
New Password: <---- enter RANDOM here
Random password [y] ?
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ?
Attributes [ 0 ] ?
Edit O.K.
Principal name: <---- null entry here will cause an exit
Creating the server file
We now have to extract all the instances which define the services
on each machine. For this we use the ext_srvtab
command. This will create a file which must be copied or moved
by secure means to each Kerberos client's
/etc/kerberosIV directory. This file must be present on each server
and client, and is crucial to the operation of Kerberos.
&prompt.root; ext_srvtab grunt
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Generating 'grunt-new-srvtab'....
Now, this command only generates a temporary file which must be
renamed to srvtab so that all the server can pick
it up. Use the mv command to move it into place on
the original system:
&prompt.root; mv grunt-new-srvtab srvtab
If the file is for a client system, and the network is not deemed
safe, then copy the
client-new-srvtab to
removable media and transport it by secure physical means. Be sure to
rename it to srvtab in the client's
/etc/kerberosIV directory, and make sure it is
mode 600:
&prompt.root; mv grumble-new-srvtab srvtab
&prompt.root; chmod 600 srvtab
Populating the database
We now have to add some user entries into the database. First
let's create an entry for the user jane. Use the
kdb_edit command to do this:
&prompt.root; kdb_edit
Opening database...
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Previous or default values are in [brackets] ,
enter return to leave the same, or new value.
Principal name: jane
Instance:
<Not found>, Create [y] ? y
Principal: jane, Instance: , kdc_key_ver: 1
New Password: <---- enter a secure password here
Verifying password
New Password: <---- re-enter the password here
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ?
Attributes [ 0 ] ?
Edit O.K.
Principal name: <---- null entry here will cause an exit
Testing it all out
First we have to start the Kerberos daemons. NOTE that if you
have correctly edited your /etc/rc.conf then this
will happen automatically when you reboot. This is only necessary on
the Kerberos server. Kerberos clients will automagically get what
they need from the /etc/kerberosIV
directory.
&prompt.root; kerberos &
Kerberos server starting
Sleep forever on error
Log file is /var/log/kerberos.log
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Current Kerberos master key version is 1
Local realm: GRONDAR.ZA
&prompt.root; kadmind -n &
KADM Server KADM0.0A initializing
Please do not use 'kill -9' to kill this job, use a
regular kill instead
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Now we can try using the kinit command to get a
ticket for the id jane that we created
above:
&prompt.user; kinit jane
MIT Project Athena (grunt.grondar.za)
Kerberos Initialization for "jane"
Password:
Try listing the tokens using klist to see if we
really have them:
&prompt.user; klist
Ticket file: /tmp/tkt245
Principal: jane@GRONDAR.ZA
Issued Expires Principal
Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.GRONDAR.ZA@GRONDAR.ZA
Now try changing the password using passwd to
check if the kpasswd daemon can get authorization to the Kerberos
database:
&prompt.user; passwd
realm GRONDAR.ZA
Old password for jane:
New Password for jane:
Verifying password
New Password for jane:
Password changed.
Adding su privileges
Kerberos allows us to give each user who
needs root privileges their own separate
supassword. We could now add an id which is
authorized to su to root.
This is controlled by having an instance of root
associated with a principal. Using kdb_edit we can
create the entry jane.root in the Kerberos
database:
&prompt.root; kdb_edit
Opening database...
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Previous or default values are in [brackets] ,
enter return to leave the same, or new value.
Principal name: jane
Instance: root
<Not found>, Create [y] ? y
Principal: jane, Instance: root, kdc_key_ver: 1
New Password: <---- enter a SECURE password here
Verifying password
New Password: <---- re-enter the password here
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ? 12 <--- Keep this short!
Attributes [ 0 ] ?
Edit O.K.
Principal name: <---- null entry here will cause an exit
Now try getting tokens for it to make sure it works:
&prompt.root; kinit jane.root
MIT Project Athena (grunt.grondar.za)
Kerberos Initialization for "jane.root"
Password:
Now we need to add the user to root's .klogin
file:
&prompt.root; cat /root/.klogin
jane.root@GRONDAR.ZA
Now try doing the su:
&prompt.user; su
Password:
and take a look at what tokens we have:
&prompt.root; klist
Ticket file: /tmp/tkt_root_245
Principal: jane.root@GRONDAR.ZA
Issued Expires Principal
May 2 20:43:12 May 3 04:43:12 krbtgt.GRONDAR.ZA@GRONDAR.ZA
Using other commands
In an earlier example, we created a principal called
jane with an instance root.
This was based on a user with the same name as the principal, and this
is a Kerberos default; that a
<principal>.<instance> of the form
<username>.root will allow
that <username> to su to
root if the necessary entries are in the .klogin
file in root's home directory:
&prompt.root; cat /root/.klogin
jane.root@GRONDAR.ZA
Likewise, if a user has in their own home directory lines of the
form:
&prompt.user; cat ~/.klogin
jane@GRONDAR.ZA
jack@GRONDAR.ZA
This allows anyone in the GRONDAR.ZA realm
who has authenticated themselves to jane or
jack (via kinit, see above)
access to rlogin to jane's
account or files on this system (grunt) via
rlogin, rsh or
rcp.
For example, Jane now logs into another system, using
Kerberos:
&prompt.user; kinit
MIT Project Athena (grunt.grondar.za)
Password:
%prompt.user; rlogin grunt
Last login: Mon May 1 21:14:47 from grumble
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995
Or Jack logs into Jane's account on the same machine (Jane having
set up the .klogin file as above, and the person
in charge of Kerberos having set up principal
jack with a null instance:
&prompt.user; kinit
&prompt.user; rlogin grunt -l jane
MIT Project Athena (grunt.grondar.za)
Password:
Last login: Mon May 1 21:16:55 from grumble
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995
Firewalls
Contributed by &a.gpalmer; and Alex Nash.
Firewalls are an area of increasing interest for people who are
connected to the Internet, and are even finding applications on private
networks to provide enhanced security. This section will hopefully
explain what firewalls are, how to use them, and how to use the
facilities provided in the FreeBSD kernel to implement them.
People often think that having a firewall between your
internal network and the Big Bad Internet
will solve all
your security problems. It may help, but a poorly setup firewall
system is more of a security risk than not having one at all. A
firewall can add another layer of security to your systems, but it
cannot stop a really determined cracker from penetrating your internal
network. If you let internal security lapse because you believe your
firewall to be impenetrable, you have just made the crackers job that
much easier.
What is a firewall?
There are currently two distinct types of firewalls in common use
on the Internet today. The first type is more properly called a
packet filtering router, where the kernel on a
multi-homed machine chooses whether to forward or block packets based
on a set of rules. The second type, known as a proxy
server, relies on daemons to provide authentication and to
forward packets, possibly on a multi-homed machine which has kernel
packet forwarding disabled.
Sometimes sites combine the two types of firewalls, so that only a
certain machine (known as a bastion host) is
allowed to send packets through a packet filtering router onto an
internal network. Proxy services are run on the bastion host, which
are generally more secure than normal authentication
mechanisms.
FreeBSD comes with a kernel packet filter (known as
IPFW), which is what the rest of this
section will concentrate on. Proxy servers can be built on FreeBSD
from third party software, but there is such a variety of proxy
servers available that it would be impossible to cover them in this
document.
Packet filtering routers
A router is a machine which forwards packets between two or more
networks. A packet filtering router has an extra piece of code in
its kernel which compares each packet to a list of rules before
deciding if it should be forwarded or not. Most modern IP routing
software has packet filtering code within it that defaults to
forwarding all packets. To enable the filters, you need to define a
set of rules for the filtering code so it can decide if the
packet should be allowed to pass or not.
To decide whether a packet should be passed on, the code looks
through its set of rules for a rule which matches the contents of
this packets headers. Once a match is found, the rule action is
obeyed. The rule action could be to drop the packet, to forward the
packet, or even to send an ICMP message back to the originator.
Only the first match counts, as the rules are searched in order.
Hence, the list of rules can be referred to as a rule
chain
.
The packet matching criteria varies depending on the software
used, but typically you can specify rules which depend on the source
IP address of the packet, the destination IP address, the source
port number, the destination port number (for protocols which
support ports), or even the packet type (UDP, TCP, ICMP,
etc).
Proxy servers
Proxy servers are machines which have had the normal system
daemons (telnetd, ftpd, etc) replaced with special servers. These
servers are called proxy servers as they
normally only allow onward connections to be made. This enables you
to run (for example) a proxy telnet server on your firewall host,
and people can telnet in to your firewall from the outside, go
through some authentication mechanism, and then gain access to the
internal network (alternatively, proxy servers can be used for
signals coming from the internal network and heading out).
Proxy servers are normally more secure than normal servers, and
often have a wider variety of authentication mechanisms available,
including one-shot
password systems so that even if
someone manages to discover what password you used, they will not be
able to use it to gain access to your systems as the password
instantly expires. As they do not actually give users access to the
host machine, it becomes a lot more difficult for someone to install
backdoors around your security system.
Proxy servers often have ways of restricting access further, so
that only certain hosts can gain access to the servers, and often
they can be set up so that you can limit which users can talk to
which destination machine. Again, what facilities are available
depends largely on what proxy software you choose.
What does IPFW allow me to do?
IPFW, the software supplied with
FreeBSD, is a packet filtering and accounting system which resides in
the kernel, and has a user-land control utility,
&man.ipfw.8;. Together, they allow you to define and query the
rules currently used by the kernel in its routing decisions.
There are two related parts to IPFW.
The firewall section allows you to perform packet filtering. There is
also an IP accounting section which allows you to track usage of your
router, based on similar rules to the firewall section. This allows
you to see (for example) how much traffic your router is getting from
a certain machine, or how much WWW (World Wide Web) traffic it is
forwarding.
As a result of the way that IPFW is
designed, you can use IPFW on non-router
machines to perform packet filtering on incoming and outgoing
connections. This is a special case of the more general use of
IPFW, and the same commands and techniques
should be used in this situation.
Enabling IPFW on FreeBSD
As the main part of the IPFW system
lives in the kernel, you will need to add one or more options to your
kernel configuration file, depending on what facilities you want, and
recompile your kernel. See reconfiguring
the kernel for more details on how to recompile your
kernel.
There are currently three kernel configuration options relevant to
IPFW:
options IPFIREWALL
Compiles into the kernel the code for packet
filtering.
options IPFIREWALL_VERBOSE
Enables code to allow logging of packets through
&man.syslogd.8;. Without this option, even if you specify
that packets should be logged in the filter rules, nothing will
happen.
options IPFIREWALL_VERBOSE_LIMIT=10
Limits the number of packets logged through
&man.syslogd.8; on a per entry basis. You may wish to use
this option in hostile environments in which you want to log
firewall activity, but do not want to be open to a denial of
service attack via syslog flooding.
When a chain entry reaches the packet limit specified,
logging is turned off for that particular entry. To resume
logging, you will need to reset the associated counter using the
&man.ipfw.8; utility:
&prompt.root; ipfw zero 4500
Where 4500 is the chain entry you wish to continue
logging.
Previous versions of FreeBSD contained an
IPFIREWALL_ACCT option. This is now obsolete as
the firewall code automatically includes accounting
facilities.
Configuring IPFW
The configuration of the IPFW software
is done through the &man.ipfw.8; utility. The syntax for this
command looks quite complicated, but it is relatively simple once you
understand its structure.
There are currently four different command categories used by the
utility: addition/deletion, listing, flushing, and clearing.
Addition/deletion is used to build the rules that control how packets
are accepted, rejected, and logged. Listing is used to examine the
contents of your rule set (otherwise known as the chain) and packet
counters (accounting). Flushing is used to remove all entries from
the chain. Clearing is used to zero out one or more accounting
entries.
Altering the IPFW rules
The syntax for this form of the command is:
ipfw
-N
command
index
action
log
protocol
addresses
options
There is one valid flag when using this form of the
command:
-N
Resolve addresses and service names in output.
The command given can be shortened to the
shortest unique form. The valid commands
are:
add
Add an entry to the firewall/accounting rule list
delete
Delete an entry from the firewall/accounting rule
list
Previous versions of IPFW used
separate firewall and accounting entries. The present version
provides packet accounting with each firewall entry.
If an index value is supplied, it used to
place the entry at a specific point in the chain. Otherwise, the
entry is placed at the end of the chain at an index 100 greater than
the last chain entry (this does not include the default policy, rule
65535, deny).
The log option causes matching rules to be
output to the system console if the kernel was compiled with
IPFIREWALL_VERBOSE.
Valid actions are:
reject
Drop the packet, and send an ICMP host or port unreachable
(as appropriate) packet to the source.
allow
Pass the packet on as normal. (aliases:
pass and
accept)
deny
Drop the packet. The source is not notified via an
ICMP message (thus it appears that the packet never
arrived at the destination).
count
Update packet counters but do not allow/deny the packet
based on this rule. The search continues with the next chain
entry.
Each action will be recognized by the
shortest unambiguous prefix.
The protocols which can be specified
are:
all
Matches any IP packet
icmp
Matches ICMP packets
tcp
Matches TCP packets
udp
Matches UDP packets
The address specification is:
from
address/maskport
to
address/maskport
via interface
You can only specify port in
conjunction with protocols which support ports
(UDP and TCP).
The is optional and may specify the IP
address or domain name of a local IP interface, or an interface name
(e.g. ed0) to match only packets coming
through this interface. Interface unit numbers can be specified
with an optional wildcard. For example, ppp*
would match all kernel PPP interfaces.
The syntax used to specify an
address/mask is:
address
or
address/mask-bits
or
address:mask-pattern
A valid hostname may be specified in place of the IP address.
is a decimal
number representing how many bits in the address mask should be set.
e.g. specifying 192.216.222.1/24 will create a
mask which will allow any address in a class C subnet (in this case,
192.216.222) to be matched.
is an IP
address which will be logically AND'ed with the address given. The
keyword any may be used to specify any IP
address
.
The port numbers to be blocked are specified as:
port,port,port…
to specify either a single port or a list of ports, or
port-port
to specify a range of ports. You may also combine a single range
with a list, but the range must always be specified first.
The options available are:
frag
Matches if the packet is not the first fragment of the
datagram.
in
Matches if the packet is on the way in.
out
Matches if the packet is on the way out.
ipoptions spec
Matches if the IP header contains the comma separated list
of options specified in spec. The
supported list of IP options are: ssrr
(strict source route), lsrr (loose source
route), rr (record packet route), and
ts (time stamp). The absence of a
particular option may be denoted with a leading
!.
established
Matches if the packet is part of an already established
TCP connection (i.e. it has the RST or ACK bits set). You can
optimize the performance of the firewall by placing
established rules early in the
chain.
setup
Matches if the packet is an attempt to establish a TCP
connection (the SYN bit set is set but the ACK bit is
not).
tcpflags flags
Matches if the TCP header contains the comma separated
list of flags. The supported flags
are fin, syn,
rst, psh,
ack, and urg. The
absence of a particular flag may be indicated by a leading
!.
icmptypes types
Matches if the ICMP type is present in the list
types. The list may be specified
as any combination of ranges and/or individual types separated
by commas. Commonly used ICMP types are: 0
echo reply (ping reply), 3 destination
unreachable, 5 redirect,
8 echo request (ping request), and
11 time exceeded (used to indicate TTL
expiration as with &man.traceroute.8;).
Listing the IPFW rules
The syntax for this form of the command is:
ipfw
-a
-t
-N
l
There are three valid flags when using this form of the
command:
-a
While listing, show counter values. This option is the
only way to see accounting counters.
-t
Display the last match times for each chain entry. The
time listing is incompatible with the input syntax used by the
&man.ipfw.8; utility.
-N
Attempt to resolve given addresses and service
names.
Flushing the IPFW rules
The syntax for flushing the chain is:
ipfw
flush
This causes all entries in the firewall chain to be removed
except the fixed default policy enforced by the kernel (index
65535). Use caution when flushing rules, the default deny policy
will leave your system cut off from the network until allow entries
are added to the chain.
Clearing the IPFW packet counters
The syntax for clearing one or more packet counters is:
ipfw
zero
index
When used without an index argument,
all packet counters are cleared. If an
index is supplied, the clearing operation
only affects a specific chain entry.
Example commands for ipfw
This command will deny all packets from the host evil.crackers.org to the telnet port of the
host nice.people.org:
&prompt.root ipfw add deny tcp from evil.crackers.org to nice.people.org 23
The next example denies and logs any TCP traffic from the entire
crackers.org network (a class C) to
the nice.people.org machine (any
port).
&prompt.root; ipfw add deny log tcp from evil.crackers.org/24 to nice.people.org
If you do not want people sending X sessions to your internal
network (a subnet of a class C), the following command will do the
necessary filtering:
&prompt.root; ipfw add deny tcp from any to my.org/28 6000 setup
To see the accounting records:
&prompt.root; ipfw -a list
or in the short form
&prompt.root; ipfw -a l
You can also see the last time a chain entry was matched
with:
&prompt.root; ipfw -at l
Building a packet filtering firewall
The following suggestions are just that: suggestions. The
requirements of each firewall are different and we cannot tell you
how to build a firewall to meet your particular requirements.
When initially setting up your firewall, unless you have a test
bench setup where you can configure your firewall host in a controlled
environment, it is strongly recommend you use the logging version of the
commands and enable logging in the kernel. This will allow you to
quickly identify problem areas and cure them without too much
disruption. Even after the initial setup phase is complete, I
recommend using the logging for `deny' as it allows tracing of
possible attacks and also modification of the firewall rules if your
requirements alter.
If you use the logging versions of the accept
command, it can generate large amounts of log
data as one log line will be generated for every packet that passes
through the firewall, so large ftp/http transfers, etc, will really
slow the system down. It also increases the latencies on those
packets as it requires more work to be done by the kernel before the
packet can be passed on. syslogd with also start using up a lot
more processor time as it logs all the extra data to disk, and it
could quite easily fill the partition /var/log
is located on.
You should enable your firewall from
/etc/rc.conf.local or
/etc/rc.conf. The associated man page explains
which knobs to fiddle and lists some preset firewall configurations.
If you do not use a preset configuration, ipfw list
will output the current ruleset into a file that you can
pass to rc.conf. If you do not use
/etc/rc.conf.local or
/etc/rc.conf to enable your firewall,
it is important to make sure your firewall is enabled before
any IP interfaces are configured.
The next problem is what your firewall should actually
do! This is largely dependent on what access to
your network you want to allow from the outside, and how much access
to the outside world you want to allow from the inside. Some general
rules are:
Block all incoming access to ports below 1024 for TCP. This is
where most of the security sensitive services are, like finger,
SMTP (mail) and telnet.
Block all incoming UDP traffic. There
are very few useful services that travel over UDP, and what useful
traffic there is is normally a security threat (e.g. Suns RPC and
NFS protocols). This has its disadvantages also, since UDP is a
connectionless protocol, denying incoming UDP traffic also blocks
the replies to outgoing UDP traffic. This can cause a problem for
people (on the inside) using external archie (prospero) servers.
If you want to allow access to archie, you'll have to allow
packets coming from ports 191 and 1525 to any internal UDP port
through the firewall. ntp is another service you may consider
allowing through, which comes from port 123.
Block traffic to port 6000 from the outside. Port 6000 is the
port used for access to X11 servers, and can be a security threat
(especially if people are in the habit of doing xhost
+ on their workstations). X11 can actually use a
range of ports starting at 6000, the upper limit being how many X
displays you can run on the machine. The upper limit as defined
by RFC 1700 (Assigned Numbers) is 6063.
Check what ports any internal servers use (e.g. SQL servers,
etc). It is probably a good idea to block those as well, as they
normally fall outside the 1-1024 range specified above.
Another checklist for firewall configuration is available from
CERT at http://www.cert.org/tech_tips/packet_filtering.html
As stated above, these are only guidelines.
You will have to decide what filter rules you want to use on your
firewall yourself. We cannot accept ANY responsibility if someone
breaks into your network, even if you follow the advice given
above.
OpenSSL
As of FreeBSD 4.0, the OpenSSL toolkit is a part of the base
system. OpenSSL
provides a general-purpose cryptography library, as well as the
Secure Sockets Layer v2/v3 (SSLv2/SSLv3) and Transport Layer
Security v1 (TLSv1) network security protocols.
However, one of the algorithms (specifically IDEA)
included in OpenSSL is protected by patents in the USA and
elsewhere, and is not available for unrestricted use.
IDEA is included in the OpenSSL sources in FreeBSD, but it is not
built by default. If you wish to use it, and you comply with the
license terms, enable the MAKE_IDEA switch in /etc/make.conf and
rebuild your sources using 'make world'.
Today, the RSA algorithm is free for use in USA and other
countries. In the past it was protected by a patent.
Source Code Installations
OpenSSL is part of the src-crypto and
src-secure cvsup collections. See the Obtaining FreeBSD section for more
information about obtaining and updating FreeBSD source
code.
IPsec
Contributed by &a.shin;, 5 March
2000.
- IPsec mechanism provides secure communication either for IP
+ The IPsec mechanism provides secure communication either for IP
layer and socket layer communication. This section should
- explain how to use them. About IPsec implementation, please
- refer section 23.5.4.
+ explain how to use them. For implementation details, please
+ refer to The
+ Developers' Handbook.
The current IPsec implementation supports both transport mode
and tunnel mode. However, tunnel mode comes with some restrictions.
http://www.kame.net/newsletter/
has more comprehensive examples.
Please be aware that in order to use this functionality, you
must have the following options compiled into your kernel:
options IPSEC #IP security
options IPSEC_ESP #IP security (crypto; define w/IPSEC)
Transport mode example with IPv4
Let's setup security association to deploy a secure channel
between HOST A (10.2.3.4) and HOST B (10.6.7.8). Here we show a little
complicated example. From HOST A to HOST B, only old AH is used.
From HOST B to HOST A, new AH and new ESP are combined.
Now we should choose algorithm to be used corresponding to
"AH"/"new AH"/"ESP"/"new ESP". Please refer to the &man.setkey.8; man
page to know algorithm names. Our choice is MD5 for AH, new-HMAC-SHA1
for new AH, and new-DES-expIV with 8 byte IV for new ESP.
Key length highly depends on each algorithm. For example, key
length must be equal to 16 bytes for MD5, 20 for new-HMAC-SHA1,
and 8 for new-DES-expIV. Now we choose "MYSECRETMYSECRET",
"KAMEKAMEKAMEKAMEKAME", "PASSWORD", respectively.
OK, let's assign SPI (Security Parameter Index) for each protocol.
Please note that we need 3 SPIs for this secure channel since three
security headers are produced (one for from HOST A to HOST B, two for
from HOST B to HOST A). Please also note that SPI MUST be greater
than or equal to 256. We choose, 1000, 2000, and 3000, respectively.
(1)
HOST A ------> HOST B
(1)PROTO=AH
ALG=MD5(RFC1826)
KEY=MYSECRETMYSECRET
SPI=1000
(2.1)
HOST A <------ HOST B
<------
(2.2)
(2.1)
PROTO=AH
ALG=new-HMAC-SHA1(new AH)
KEY=KAMEKAMEKAMEKAMEKAME
SPI=2000
(2.2)
PROTO=ESP
ALG=new-DES-expIV(new ESP)
IV length = 8
KEY=PASSWORD
SPI=3000
Now, let's setup security association. Execute &man.setkey.8;
on both HOST A and B:
&prompt.root; setkey -c
add 10.2.3.4 10.6.7.8 ah-old 1000 -m transport -A keyed-md5 "MYSECRETMYSECRET" ;
add 10.6.7.8 10.2.3.4 ah 2000 -m transport -A hmac-sha1 "KAMEKAMEKAMEKAMEKAME" ;
add 10.6.7.8 10.2.3.4 esp 3000 -m transport -E des-cbc "PASSWORD" ;
^D
Actually, IPsec communication doesn't process until security policy
entries will be defined. In this case, you must setup each host.
At A:
&prompt.root; setkey -c
spdadd 10.2.3.4 10.6.7.8 any -P out ipsec
ah/transport/10.2.3.4-10.6.7.8/require ;
^D
At B:
&prompt.root; setkey -c
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
esp/transport/10.6.7.8-10.2.3.4/require ;
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
ah/transport/10.6.7.8-10.2.3.4/require ;
^D
HOST A --------------------------------------> HOST E
10.2.3.4 10.6.7.8
| |
========== old AH keyed-md5 ==========>
<========= new AH hmac-sha1 ===========
<========= new ESP des-cbc ============
Transport mode example with IPv6
Another example using IPv6.
ESP transport mode is recommended for TCP port number 110 between
Host-A and Host-B.
============ ESP ============
| |
Host-A Host-B
fec0::10 -------------------- fec0::11
Encryption algorithm is blowfish-cbc whose key is "kamekame", and
authentication algorithm is hmac-sha1 whose key is "this is the test
key". Configuration at Host-A:
&prompt.root; setkey -c <<EOF
spdadd fec0::10[any] fec0::11[110] tcp -P out ipsec
esp/transport/fec0::10-fec0::11/use ;
spdadd fec0::11[110] fec0::10[any] tcp -P in ipsec
esp/transport/fec0::11-fec0::10/use ;
add fec0::10 fec0::11 esp 0x10001
-m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
add fec0::11 fec0::10 esp 0x10002
-m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
EOF
and at Host-B:
&prompt.root; setkey -c <<EOF
spdadd fec0::11[110] fec0::10[any] tcp -P out ipsec
esp/transport/fec0::11-fec0::10/use ;
spdadd fec0::10[any] fec0::11[110] tcp -P in ipsec
esp/transport/fec0::10-fec0::11/use ;
add fec0::10 fec0::11 esp 0x10001 -m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
add fec0::11 fec0::10 esp 0x10002 -m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
EOF
Note the direction of SP.
Tunnel mode example with IPv4
Tunnel mode between two security gateways
Security protocol is old AH tunnel mode, i.e. specified by
RFC1826, with keyed-md5 whose key is "this is the test" as
authentication algorithm.
======= AH =======
| |
Network-A Gateway-A Gateway-B Network-B
10.0.1.0/24 ---- 172.16.0.1 ----- 172.16.0.2 ---- 10.0.2.0/24
Configuration at Gateway-A:
&prompt.root; setkey -c <<EOF
spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec
ah/tunnel/172.16.0.1-172.16.0.2/require ;
spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec
ah/tunnel/172.16.0.2-172.16.0.1/require ;
add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any
-A keyed-md5 "this is the test" ;
add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any
-A keyed-md5 "this is the test" ;
EOF
If port number field is omitted such above then "[any]" is
employed. `-m' specifies the mode of SA to be used. "-m any" means
wild-card of mode of security protocol. You can use this SA for both
tunnel and transport mode.
and at Gateway-B:
&prompt.root; setkey -c <<EOF
spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec
ah/tunnel/172.16.0.2-172.16.0.1/require ;
spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec
ah/tunnel/172.16.0.1-172.16.0.2/require ;
add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any
-A keyed-md5 "this is the test" ;
add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any
-A keyed-md5 "this is the test" ;
EOF
Making SA bundle between two security gateways
AH transport mode and ESP tunnel mode is required between
Gateway-A and Gateway-B. In this case, ESP tunnel mode is applied first,
and AH transport mode is next.
========== AH =========
| ======= ESP ===== |
| | | |
Network-A Gateway-A Gateway-B Network-B
fec0:0:0:1::/64 --- fec0:0:0:1::1 ---- fec0:0:0:2::1 --- fec0:0:0:2::/64
Tunnel mode example with IPv6
Encryption algorithm is 3des-cbc, and authentication algorithm
for ESP is hmac-sha1. Authentication algorithm for AH is hmac-md5.
Configuration at Gateway-A:
&prompt.root; setkey -c <<EOF
spdadd fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out ipsec
esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require
ah/transport/fec0:0:0:1::1-fec0:0:0:2::1/require ;
spdadd fec0:0:0:2::/64 fec0:0:0:1::/64 any -P in ipsec
esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require
ah/transport/fec0:0:0:2::1-fec0:0:0:1::1/require ;
add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10001 -m tunnel
-E 3des-cbc "kamekame12341234kame1234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:1::1 fec0:0:0:2::1 ah 0x10001 -m transport
-A hmac-md5 "this is the test" ;
add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10001 -m tunnel
-E 3des-cbc "kamekame12341234kame1234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:2::1 fec0:0:0:1::1 ah 0x10001 -m transport
-A hmac-md5 "this is the test" ;
EOF
Making SAs with the different end
ESP tunnel mode is required between Host-A and Gateway-A. Encryption
algorithm is cast128-cbc, and authentication algorithm for ESP is
hmac-sha1. ESP transport mode is recommended between Host-A and Host-B.
Encryption algorithm is rc5-cbc, and authentication algorithm for ESP is
hmac-md5.
================== ESP =================
| ======= ESP ======= |
| | | |
Host-A Gateway-A Host-B
fec0:0:0:1::1 ---- fec0:0:0:2::1 ---- fec0:0:0:2::2
Configuration at Host-A:
&prompt.root; setkey -c <<EOF
spdadd fec0:0:0:1::1[any] fec0:0:0:2::2[80] tcp -P out ipsec
esp/transport/fec0:0:0:1::1-fec0:0:0:2::2/use
esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ;
spdadd fec0:0:0:2::1[80] fec0:0:0:1::1[any] tcp -P in ipsec
esp/transport/fec0:0:0:2::2-fec0:0:0:l::1/use
esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ;
add fec0:0:0:1::1 fec0:0:0:2::2 esp 0x10001
-m transport
-E cast128-cbc "12341234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10002
-E rc5-cbc "kamekame"
-A hmac-md5 "this is the test" ;
add fec0:0:0:2::2 fec0:0:0:1::1 esp 0x10003
-m transport
-E cast128-cbc "12341234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004
-E rc5-cbc "kamekame"
-A hmac-md5 "this is the test" ;
EOF
OpenSSH
Contributed by &a.chern;, April 21,
2001.
Secure shell is a secure set of programs used to access a remote
machine. It can be used as a secure medium in place of rlogin, rsh,
rcp, etc. X11 connections, as well as other TCP/IP connections can
be tunnelled/forwarded securely through OpenSSH. Utilizing, RSA
public key cryptography, OpenSSH is a powerful secure alternative
over traditional utilities.
The package provides secure alternatives to many r*
*nix commands. Namely, rlogin, rcp, and
rsh.
OpenSSH is maintained by the OpenBSD project, and is based upon
SSH v1.2.12 with all the recent bug fixes and updates.
The OpenSSH client is compatible with both SSH protocols 1 and
2.
Advantages of using OpenSSH
Normally, when using telnet or
rlogin, data is sent over the network in an clear,
un-encrypted form. Network sniffers on either side, the server
or the client, or any route in between, can steal your
user/password information, and data transferred in your session.
Attackers can even hijack an existing TCP/IP connection and gain
control of your login session.
With the SSH protocol, all this data is sent encrypted,
making the above impossible.
Enabling sshd
Be sure to make the following additions to your
rc.conf file:
sshd_enable="YES"
This will load the ssh daemon the next time your system inits.
SSH client
The ssh utility works similarly to
rlogin.
&prompt.root ssh user@foobardomain.com
Host key not found from the list of known hosts.
Are you sure you want to continue connecting (yes/no)? yes
Host 'foobardomain.com' added to the list of known hosts.
user@foobardomain.com's password: *******
The login will continue just as it would have if a session was
created using rlogin or telnet. SSH utilizes a key fingerprint
system for verifying the authenticity of the server when the
client connects. The user is prompted to enter 'yes' only during
the first time connecting. Future attempts to login are all
verified against the saved fingerprint key. The SSH client
will alert you if the saved fingerprint differs from the
received fingerprint on future login attempts. The fingerprints
are saved in ~/.ssh/known_hosts
Secure copy
The scp command works similarly to rcp; it copies a
file off a remote machine, except in a secure fashion.
&prompt.root scp user@foobardomain.com:/COPYRIGHT COPYRIGHT
user@foobardomain.com's password:
COPYRIGHT 100% |*****************************| 4735
00:00
&prompt.root
Since the fingerprint was already saved for this host in the
previous example, it is verified when using scp
here.
Configuration
The system-wide configuration files for both the OpenSSH
daemon and client reside within the /etc/ssh
directory.
ssh_config configures the client
settings, while sshd_config configures the
daemon.
ssh-keygen
Instead of using passwords, ssh-keygen can
be used to generate RSA keys to authenticate a user.
&prompt.user ssh-keygen
Initializing random number generator...
Generating p: .++ (distance 66)
Generating q: ..............................++ (distance 498)
Computing the keys...
Key generation complete.
Enter file in which to save the key (/home/user/.ssh/identity):
Enter passphrase:
Enter the same passphrase again:
Your identification has been saved in /home/user/.ssh/identity.
...
ssh-keygen will create a public and private
key pair for use in authentication. The private key is stored in
~/.ssh/identity, whereas the public key is
stored in ~/.ssh/identity.pub. The public
key must be placed in ~/.ssh/authorized_keys
of the remote machine in order for the setup to work.
This will allow connection to the remote machine based upon
RSA authentication, not password.
If a passphrase is used in ssh-keygen, the user
will be prompted for a password each time in order to use the private
key.
ssh-agent and ssh-add are
utilities used in managing multiple passworded private keys.
Further Reading
OpenSSH
&man.ssh.1 &man.scp.1 &man.ssh-keygen.1
&man.ssh-agent.1 &man.ssh-add.1
&man.sshd.8 &man.sftp-server.8
diff --git a/en_US.ISO_8859-1/books/handbook/Makefile b/en_US.ISO_8859-1/books/handbook/Makefile
index ab5f06952d..60f5dff022 100644
--- a/en_US.ISO_8859-1/books/handbook/Makefile
+++ b/en_US.ISO_8859-1/books/handbook/Makefile
@@ -1,73 +1,72 @@
#
-# $FreeBSD: doc/en_US.ISO_8859-1/books/handbook/Makefile,v 1.30 2000/12/01 00:58:11 jim Exp $
+# $FreeBSD: doc/en_US.ISO_8859-1/books/handbook/Makefile,v 1.31 2001/02/28 22:50:05 nik Exp $
#
# Build the FreeBSD Handbook.
#
MAINTAINER=nik@FreeBSD.org
DOC?= book
FORMATS?= html-split
INSTALL_COMPRESSED?= gz
INSTALL_ONLY_COMPRESSED?=
#
# SRCS lists the individual SGML files that make up the document. Changes
# to any of these files will force a rebuild
#
# SGML content
SRCS= book.sgml
SRCS+= advanced-networking/chapter.sgml
SRCS+= backups/chapter.sgml
SRCS+= basics/chapter.sgml
SRCS+= bibliography/chapter.sgml
SRCS+= boot/chapter.sgml
SRCS+= contrib/chapter.sgml
SRCS+= cutting-edge/chapter.sgml
SRCS+= disks/chapter.sgml
SRCS+= eresources/chapter.sgml
SRCS+= hw/chapter.sgml
SRCS+= install/chapter.sgml
-SRCS+= internals/chapter.sgml
SRCS+= introduction/chapter.sgml
SRCS+= kernelconfig/chapter.sgml
SRCS+= kerneldebug/chapter.sgml
SRCS+= kernelopts/chapter.sgml
SRCS+= l10n/chapter.sgml
SRCS+= linuxemu/chapter.sgml
SRCS+= mail/chapter.sgml
SRCS+= mirrors/chapter.sgml
SRCS+= pgpkeys/chapter.sgml
SRCS+= policies/chapter.sgml
SRCS+= ppp-and-slip/chapter.sgml
SRCS+= printing/chapter.sgml
SRCS+= security/chapter.sgml
SRCS+= serialcomms/chapter.sgml
SRCS+= sound/chapter.sgml
SRCS+= staff/chapter.sgml
SRCS+= users/chapter.sgml
SRCS+= x11/chapter.sgml
SRCS+= ports/chapter.sgml
# Entities
SRCS+= authors.ent
SRCS+= chapters.ent
SRCS+= mailing-lists.ent
SYMLINKS= ${DESTDIR} index.html handbook.html
# XXX The Handbook build currently overflows some internal, hardcoded
# limits in pdftex. Until we split the Handbook up, build the PDF
# version using ps2pdf instead of pdftex.
book.tex-pdf:
touch book.tex-pdf
book.pdf: book.ps
ps2pdf book.ps book.pdf
DOC_PREFIX?= ${.CURDIR}/../../..
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/en_US.ISO_8859-1/books/handbook/book.sgml b/en_US.ISO_8859-1/books/handbook/book.sgml
index 66230e5424..dcd4528417 100644
--- a/en_US.ISO_8859-1/books/handbook/book.sgml
+++ b/en_US.ISO_8859-1/books/handbook/book.sgml
@@ -1,135 +1,134 @@
%man;
%bookinfo;
%chapters;
%authors;
%mailing-lists;
%newsgroups;
]>
FreeBSD Handbook
The FreeBSD Documentation Project
February 1999
1995
1996
1997
1998
1999
2000
2001
The FreeBSD Documentation Project
&bookinfo.legalnotice;
Welcome to FreeBSD! This handbook covers the installation and day
to day use of FreeBSD Release &rel.current;.
This manual is a work in progress and is the work
of many individuals. Many sections do not yet exist and some of those
that do exist need to be updated. If you are interested in helping
with this project, send email to the &a.doc;. The latest version of
this document is always available from the FreeBSD World Wide Web server.
It may also be downloaded in a variety of formats and compression
options from the FreeBSD FTP
server or one of the numerous mirror sites. If you would prefer
to have a hard copy of the handbook, you can purchase one at the
FreeBSD Mall. You
may also want to Search the
Handbook.
Getting Started
&chap.introduction;
&chap.install;
&chap.basics;
&chap.ports;
System Administration
&chap.boot;
&chap.users;
&chap.kernelconfig;
&chap.security;
&chap.printing;
&chap.disks;
&chap.backups;
&chap.x11;
&chap.l10n;
&chap.sound;
Network Communications
&chap.serialcomms;
&chap.ppp-and-slip;
&chap.advanced-networking;
&chap.mail;
Advanced topics
&chap.cutting-edge;
&chap.contrib;
&chap.policies;
&chap.kernelopts;
&chap.kerneldebug;
&chap.linuxemu;
- &chap.internals;
Appendices
&chap.mirrors;
&chap.bibliography;
&chap.eresources;
&chap.staff;
&chap.pgpkeys;
&chap.hw;
diff --git a/en_US.ISO_8859-1/books/handbook/chapters.ent b/en_US.ISO_8859-1/books/handbook/chapters.ent
index 45d2854904..85d62c57ae 100644
--- a/en_US.ISO_8859-1/books/handbook/chapters.ent
+++ b/en_US.ISO_8859-1/books/handbook/chapters.ent
@@ -1,51 +1,50 @@
-
diff --git a/en_US.ISO_8859-1/books/handbook/internals/chapter.sgml b/en_US.ISO_8859-1/books/handbook/internals/chapter.sgml
deleted file mode 100644
index 88ca079857..0000000000
--- a/en_US.ISO_8859-1/books/handbook/internals/chapter.sgml
+++ /dev/null
@@ -1,3222 +0,0 @@
-
-
-
- FreeBSD Internals
-
-
-
-
- DMA: What it is and How it Works
-
- Copyright © 1995,1997 &a.uhclem;, All Rights
- Reserved. 10 December 1996. Last Update 8 October
- 1997.
-
- Direct Memory Access (DMA) is a method of allowing data to be moved
- from one location to another in a computer without intervention from the
- central processor (CPU).
-
- The way that the DMA function is implemented varies between computer
- architectures, so this discussion will limit itself to the
- implementation and workings of the DMA subsystem on the IBM Personal
- Computer (PC), the IBM PC/AT and all of its successors and
- clones.
-
- The PC DMA subsystem is based on the Intel 8237 DMA controller. The
- 8237 contains four DMA channels that can be programmed independently and
- any one of the channels may be active at any moment. These channels are
- numbered 0, 1, 2 and 3. Starting with the PC/AT, IBM added a second
- 8237 chip, and numbered those channels 4, 5, 6 and 7.
-
- The original DMA controller (0, 1, 2 and 3) moves one byte in each
- transfer. The second DMA controller (4, 5, 6, and 7) moves 16-bits from
- two adjacent memory locations in each transfer, with the first byte
- always coming from an even-numbered address. The two controllers are
- identical components and the difference in transfer size is caused by
- the way the second controller is wired into the system.
-
- The 8237 has two electrical signals for each channel, named DRQ and
- -DACK. There are additional signals with the names HRQ (Hold Request),
- HLDA (Hold Acknowledge), -EOP (End of Process), and the bus control
- signals -MEMR (Memory Read), -MEMW (Memory Write), -IOR (I/O Read), and
- -IOW (I/O Write).
-
- The 8237 DMA is known as a fly-by
DMA controller.
- This means that the data being moved from one location to another does
- not pass through the DMA chip and is not stored in the DMA chip.
- Subsequently, the DMA can only transfer data between an I/O port and a
- memory address, but not between two I/O ports or two memory
- locations.
-
-
- The 8237 does allow two channels to be connected together to allow
- memory-to-memory DMA operations in a non-fly-by
mode,
- but nobody in the PC industry uses this scarce resource this way since
- it is faster to move data between memory locations using the
- CPU.
-
-
- In the PC architecture, each DMA channel is normally activated only
- when the hardware that uses a given DMA channel requests a transfer by
- asserting the DRQ line for that channel.
-
-
- A Sample DMA transfer
-
- Here is an example of the steps that occur to cause and perform a
- DMA transfer. In this example, the floppy disk controller (FDC) has
- just read a byte from a diskette and wants the DMA to place it in
- memory at location 0x00123456. The process begins by the FDC
- asserting the DRQ2 signal (the DRQ line for DMA channel 2) to alert
- the DMA controller.
-
- The DMA controller will note that the DRQ2 signal is asserted. The
- DMA controller will then make sure that DMA channel 2 has been
- programmed and is unmasked (enabled). The DMA controller also makes
- sure that none of the other DMA channels are active or want to be
- active and have a higher priority. Once these checks are complete,
- the DMA asks the CPU to release the bus so that the DMA may use the
- bus. The DMA requests the bus by asserting the HRQ signal which goes
- to the CPU.
-
- The CPU detects the HRQ signal, and will complete executing the
- current instruction. Once the processor has reached a state where it
- can release the bus, it will. Now all of the signals normally
- generated by the CPU (-MEMR, -MEMW, -IOR, -IOW and a few others) are
- placed in a tri-stated condition (neither high or low) and then the
- CPU asserts the HLDA signal which tells the DMA controller that it is
- now in charge of the bus.
-
- Depending on the processor, the CPU may be able to execute a few
- additional instructions now that it no longer has the bus, but the CPU
- will eventually have to wait when it reaches an instruction that must
- read something from memory that is not in the internal processor cache
- or pipeline.
-
- Now that the DMA is in charge
, the DMA activates its
- -MEMR, -MEMW, -IOR, -IOW output signals, and the address outputs from
- the DMA are set to 0x3456, which will be used to direct the byte that
- is about to transferred to a specific memory location.
-
- The DMA will then let the device that requested the DMA transfer
- know that the transfer is commencing. This is done by asserting the
- -DACK signal, or in the case of the floppy disk controller, -DACK2 is
- asserted.
-
- The floppy disk controller is now responsible for placing the byte
- to be transferred on the bus Data lines. Unless the floppy controller
- needs more time to get the data byte on the bus (and if the peripheral
- does need more time it alerts the DMA via the READY signal), the DMA
- will wait one DMA clock, and then de-assert the -MEMW and -IOR signals
- so that the memory will latch and store the byte that was on the bus,
- and the FDC will know that the byte has been transferred.
-
- Since the DMA cycle only transfers a single byte at a time, the
- FDC now drops the DRQ2 signal, so the DMA knows that it is no longer
- needed. The DMA will de-assert the -DACK2 signal, so that the FDC
- knows it must stop placing data on the bus.
-
- The DMA will now check to see if any of the other DMA channels
- have any work to do. If none of the channels have their DRQ lines
- asserted, the DMA controller has completed its work and will now
- tri-state the -MEMR, -MEMW, -IOR, -IOW and address signals.
-
- Finally, the DMA will de-assert the HRQ signal. The CPU sees
- this, and de-asserts the HOLDA signal. Now the CPU activates its
- -MEMR, -MEMW, -IOR, -IOW and address lines, and it resumes executing
- instructions and accessing main memory and the peripherals.
-
- For a typical floppy disk sector, the above process is repeated
- 512 times, once for each byte. Each time a byte is transferred, the
- address register in the DMA is incremented and the counter in the DMA
- that shows how many bytes are to be transferred is decremented.
-
- When the counter reaches zero, the DMA asserts the EOP signal,
- which indicates that the counter has reached zero and no more data
- will be transferred until the DMA controller is reprogrammed by the
- CPU. This event is also called the Terminal Count (TC). There is only
- one EOP signal, and since only DMA channel can be active at any
- instant, the DMA channel that is currently active must be the DMA
- channel that just completed its task.
-
- If a peripheral wants to generate an interrupt when the transfer
- of a buffer is complete, it can test for its -DACKn signal and the EOP
- signal both being asserted at the same time. When that happens, it
- means the DMA will not transfer any more information for that
- peripheral without intervention by the CPU. The peripheral can then
- assert one of the interrupt signals to get the processors' attention.
- In the PC architecture, the DMA chip itself is not capable of
- generating an interrupt. The peripheral and its associated hardware
- is responsible for generating any interrupt that occurs.
- Subsequently, it is possible to have a peripheral that uses DMA but
- does not use interrupts.
-
- It is important to understand that although the CPU always
- releases the bus to the DMA when the DMA makes the request, this
- action is invisible to both applications and the operating systems,
- except for slight changes in the amount of time the processor takes to
- execute instructions when the DMA is active. Subsequently, the
- processor must poll the peripheral, poll the registers in the DMA
- chip, or receive an interrupt from the peripheral to know for certain
- when a DMA transfer has completed.
-
-
-
- DMA Page Registers and 16Meg address space limitations
-
- You may have noticed earlier that instead of the DMA setting the
- address lines to 0x00123456 as we said earlier, the DMA only set
- 0x3456. The reason for this takes a bit of explaining.
-
- When the original IBM PC was designed, IBM elected to use both DMA
- and interrupt controller chips that were designed for use with the
- 8085, an 8-bit processor with an address space of 16 bits (64K).
- Since the IBM PC supported more than 64K of memory, something had to
- be done to allow the DMA to read or write memory locations above the
- 64K mark. What IBM did to solve this problem was to add an external
- data latch for each DMA channel that holds the upper bits of the
- address to be read to or written from. Whenever a DMA channel is
- active, the contents of that latch are written to the address bus and
- kept there until the DMA operation for the channel ends. IBM called
- these latches Page Registers
.
-
- So for our example above, the DMA would put the 0x3456 part of the
- address on the bus, and the Page Register for DMA channel 2 would put
- 0x0012xxxx on the bus. Together, these two values form the complete
- address in memory that is to be accessed.
-
- Because the Page Register latch is independent of the DMA chip,
- the area of memory to be read or written must not span a 64K physical
- boundary. For example, if the DMA accesses memory location 0xffff,
- after that transfer the DMA will then increment the address register
- and the DMA will access the next byte at location 0x0000, not 0x10000.
- The results of letting this happen are probably not intended.
-
-
- Physical
64K boundaries should not be confused
- with 8086-mode 64K Segments
, which are created by
- mathematically adding a segment register with an offset register.
- Page Registers have no address overlap and are mathematically OR-ed
- together.
-
-
- To further complicate matters, the external DMA address latches on
- the PC/AT hold only eight bits, so that gives us 8+16=24 bits, which
- means that the DMA can only point at memory locations between 0 and
- 16Meg. For newer computers that allow more than 16Meg of memory, the
- standard PC-compatible DMA cannot access memory locations above
- 16Meg.
-
- To get around this restriction, operating systems will reserve a
- RAM buffer in an area below 16Meg that also does not span a physical
- 64K boundary. Then the DMA will be programmed to transfer data from
- the peripheral and into that buffer. Once the DMA has moved the data
- into this buffer, the operating system will then copy the data from
- the buffer to the address where the data is really supposed to be
- stored.
-
- When writing data from an address above 16Meg to a DMA-based
- peripheral, the data must be first copied from where it resides into a
- buffer located below 16Meg, and then the DMA can copy the data from
- the buffer to the hardware. In FreeBSD, these reserved buffers are
- called Bounce Buffers
. In the MS-DOS world, they are
- sometimes called Smart Buffers
.
-
-
- A new implementation of the 8237, called the 82374, allows 16
- bits of page register to be specified, allows access to the entire
- 32 bit address space, without the use of bounce buffers.
-
-
-
-
- DMA Operational Modes and Settings
-
- The 8237 DMA can be operated in several modes. The main ones
- are:
-
-
-
- Single
-
-
- A single byte (or word) is transferred. The DMA must
- release and re-acquire the bus for each additional byte. This is
- commonly-used by devices that cannot transfer the entire block
- of data immediately. The peripheral will request the DMA each
- time it is ready for another transfer.
-
- The standard PC-compatible floppy disk controller (NEC 765)
- only has a one-byte buffer, so it uses this mode.
-
-
-
-
- Block/Demand
-
-
- Once the DMA acquires the system bus, an entire block of
- data is transferred, up to a maximum of 64K. If the peripheral
- needs additional time, it can assert the READY signal to suspend
- the transfer briefly. READY should not be used excessively, and
- for slow peripheral transfers, the Single Transfer Mode should
- be used instead.
-
- The difference between Block and Demand is that once a Block
- transfer is started, it runs until the transfer count reaches
- zero. DRQ only needs to be asserted until -DACK is asserted.
- Demand Mode will transfer one more bytes until DRQ is
- de-asserted, at which point the DMA suspends the transfer and
- releases the bus back to the CPU. When DRQ is asserted later,
- the transfer resumes where it was suspended.
-
- Older hard disk controllers used Demand Mode until CPU
- speeds increased to the point that it was more efficient to
- transfer the data using the CPU, particularly if the memory
- locations used in the transfer were above the 16Meg mark.
-
-
-
-
- Cascade
-
-
- This mechanism allows a DMA channel to request the bus, but
- then the attached peripheral device is responsible for placing
- the addressing information on the bus instead of the DMA. This
- is also used to implement a technique known as Bus
- Mastering
.
-
- When a DMA channel in Cascade Mode receives control of the
- bus, the DMA does not place addresses and I/O control signals on
- the bus like the DMA normally does when it is active. Instead,
- the DMA only asserts the -DACK signal for the active DMA
- channel.
-
- At this point it is up to the peripheral connected to that
- DMA channel to provide address and bus control signals. The
- peripheral has complete control over the system bus, and can do
- reads and/or writes to any address below 16Meg. When the
- peripheral is finished with the bus, it de-asserts the DRQ line,
- and the DMA controller can then return control to the CPU or to
- some other DMA channel.
-
- Cascade Mode can be used to chain multiple DMA controllers
- together, and this is exactly what DMA Channel 4 is used for in
- the PC architecture. When a peripheral requests the bus on DMA
- channels 0, 1, 2 or 3, the slave DMA controller asserts HLDREQ,
- but this wire is actually connected to DRQ4 on the primary DMA
- controller instead of to the CPU. The primary DMA controller,
- thinking it has work to do on Channel 4, requests the bus from
- the CPU using HLDREQ signal. Once the CPU grants the bus to the
- primary DMA controller, -DACK4 is asserted, and that wire is
- actually connected to the HLDA signal on the slave DMA
- controller. The slave DMA controller then transfers data for
- the DMA channel that requested it (0, 1, 2 or 3), or the slave
- DMA may grant the bus to a peripheral that wants to perform its
- own bus-mastering, such as a SCSI controller.
-
- Because of this wiring arrangement, only DMA channels 0, 1,
- 2, 3, 5, 6 and 7 are usable with peripherals on PC/AT
- systems.
-
-
- DMA channel 0 was reserved for refresh operations in early
- IBM PC computers, but is generally available for use by
- peripherals in modern systems.
-
-
- When a peripheral is performing Bus Mastering, it is
- important that the peripheral transmit data to or from memory
- constantly while it holds the system bus. If the peripheral
- cannot do this, it must release the bus frequently so that the
- system can perform refresh operations on main memory.
-
- The Dynamic RAM used in all PCs for main memory must be
- accessed frequently to keep the bits stored in the components
- charged
. Dynamic RAM essentially consists of
- millions of capacitors with each one holding one bit of data.
- These capacitors are charged with power to represent a
- 1 or drained to represent a
- 0. Because all capacitors leak, power must
- be added at regular intervals to keep the 1
- values intact. The RAM chips actually handle the task of
- pumping power back into all of the appropriate locations in RAM,
- but they must be told when to do it by the rest of the computer
- so that the refresh activity won't interfere with the computer
- wanting to access RAM normally. If the computer is unable to
- refresh memory, the contents of memory will become corrupted in
- just a few milliseconds.
-
- Since memory read and write cycles count
as
- refresh cycles (a dynamic RAM refresh cycle is actually an
- incomplete memory read cycle), as long as the peripheral
- controller continues reading or writing data to sequential
- memory locations, that action will refresh all of memory.
-
- Bus-mastering is found in some SCSI host interfaces and
- other high-performance peripheral controllers.
-
-
-
-
- Autoinitialize
-
-
- This mode causes the DMA to perform Byte, Block or Demand
- transfers, but when the DMA transfer counter reaches zero, the
- counter and address are set back to where they were when the DMA
- channel was originally programmed. This means that as long as
- the peripheral requests transfers, they will be granted. It is
- up to the CPU to move new data into the fixed buffer ahead of
- where the DMA is about to transfer it when doing output
- operations, and read new data out of the buffer behind where the
- DMA is writing when doing input operations.
-
- This technique is frequently used on audio devices that have
- small or no hardware sample
buffers. There is
- additional CPU overhead to manage this circular
- buffer, but in some cases this may be the only way to eliminate
- the latency that occurs when the DMA counter reaches zero and
- the DMA stops transfers until it is reprogrammed.
-
-
-
-
-
-
- Programming the DMA
-
- The DMA channel that is to be programmed should always be
- masked
before loading any settings. This is because the
- hardware might unexpectedly assert the DRQ for that channel, and the
- DMA might respond, even though not all of the parameters have been
- loaded or updated.
-
- Once masked, the host must specify the direction of the transfer
- (memory-to-I/O or I/O-to-memory), what mode of DMA operation is to be
- used for the transfer (Single, Block, Demand, Cascade, etc), and
- finally the address and length of the transfer are loaded. The length
- that is loaded is one less than the amount you expect the DMA to
- transfer. The LSB and MSB of the address and length are written to
- the same 8-bit I/O port, so another port must be written to first to
- guarantee that the DMA accepts the first byte as the LSB and the
- second byte as the MSB of the length and address.
-
- Then, be sure to update the Page Register, which is external to
- the DMA and is accessed through a different set of I/O ports.
-
- Once all the settings are ready, the DMA channel can be un-masked.
- That DMA channel is now considered to be armed
, and will
- respond when the DRQ line for that channel is asserted.
-
- Refer to a hardware data book for precise programming details for
- the 8237. You will also need to refer to the I/O port map for the PC
- system, which describes where the DMA and Page Register ports are
- located. A complete port map table is located below.
-
-
-
- DMA Port Map
-
- All systems based on the IBM-PC and PC/AT have the DMA hardware
- located at the same I/O ports. The complete list is provided below.
- Ports assigned to DMA Controller #2 are undefined on non-AT
- designs.
-
-
- 0x00–0x1f DMA Controller #1 (Channels 0, 1, 2 and
- 3)
-
- DMA Address and Count Registers
-
-
-
-
-
- 0x00
- write
- Channel 0 starting address
-
-
-
- 0x00
- read
- Channel 0 current address
-
-
-
- 0x01
- write
- Channel 0 starting word count
-
-
-
- 0x01
- read
- Channel 0 remaining word count
-
-
-
- 0x02
- write
- Channel 1 starting address
-
-
-
- 0x02
- read
- Channel 1 current address
-
-
-
- 0x03
- write
- Channel 1 starting word count
-
-
-
- 0x03
- read
- Channel 1 remaining word count
-
-
-
- 0x04
- write
- Channel 2 starting address
-
-
-
- 0x04
- read
- Channel 2 current address
-
-
-
- 0x05
- write
- Channel 2 starting word count
-
-
-
- 0x05
- read
- Channel 2 remaining word count
-
-
-
- 0x06
- write
- Channel 3 starting address
-
-
-
- 0x06
- read
- Channel 3 current address
-
-
-
- 0x07
- write
- Channel 3 starting word count
-
-
-
- 0x07
- read
- Channel 3 remaining word count
-
-
-
-
-
- DMA Command Registers
-
-
-
-
-
- 0x08
- write
- Command Register
-
-
-
- 0x08
- read
- Status Register
-
-
-
- 0x09
- write
- Request Register
-
-
-
- 0x09
- read
- -
-
-
-
- 0x0a
- write
- Single Mask Register Bit
-
-
-
- 0x0a
- read
- -
-
-
-
- 0x0b
- write
- Mode Register
-
-
-
- 0x0b
- read
- -
-
-
-
- 0x0c
- write
- Clear LSB/MSB Flip-Flop
-
-
-
- 0x0c
- read
- -
-
-
-
- 0x0d
- write
- Master Clear/Reset
-
-
-
- 0x0d
- read
- Temporary Register (not available on newer
- versions)
-
-
- 0x0e
- write
- Clear Mask Register
-
-
-
- 0x0e
- read
- -
-
-
-
- 0x0f
- write
- Write All Mask Register Bits
-
-
-
- 0x0f
- read
- Read All Mask Register Bits (only in Intel
- 82374)
-
-
-
-
-
-
-
- 0xc0–0xdf DMA Controller #2 (Channels 4, 5, 6 and
- 7)
-
- DMA Address and Count Registers
-
-
-
-
-
- 0xc0
- write
- Channel 4 starting address
-
-
-
- 0xc0
- read
- Channel 4 current address
-
-
-
- 0xc2
- write
- Channel 4 starting word count
-
-
-
- 0xc2
- read
- Channel 4 remaining word count
-
-
-
- 0xc4
- write
- Channel 5 starting address
-
-
-
- 0xc4
- read
- Channel 5 current address
-
-
-
- 0xc6
- write
- Channel 5 starting word count
-
-
-
- 0xc6
- read
- Channel 5 remaining word count
-
-
-
- 0xc8
- write
- Channel 6 starting address
-
-
-
- 0xc8
- read
- Channel 6 current address
-
-
-
- 0xca
- write
- Channel 6 starting word count
-
-
-
- 0xca
- read
- Channel 6 remaining word count
-
-
-
- 0xcc
- write
- Channel 7 starting address
-
-
-
- 0xcc
- read
- Channel 7 current address
-
-
-
- 0xce
- write
- Channel 7 starting word count
-
-
-
- 0xce
- read
- Channel 7 remaining word count
-
-
-
-
-
- DMA Command Registers
-
-
-
-
-
- 0xd0
- write
- Command Register
-
-
-
- 0xd0
- read
- Status Register
-
-
-
- 0xd2
- write
- Request Register
-
-
-
- 0xd2
- read
- -
-
-
-
- 0xd4
- write
- Single Mask Register Bit
-
-
-
- 0xd4
- read
- -
-
-
-
- 0xd6
- write
- Mode Register
-
-
-
- 0xd6
- read
- -
-
-
-
- 0xd8
- write
- Clear LSB/MSB Flip-Flop
-
-
-
- 0xd8
- read
- -
-
-
-
- 0xda
- write
- Master Clear/Reset
-
-
-
- 0xda
- read
- Temporary Register (not present in Intel
- 82374)
-
-
-
- 0xdc
- write
- Clear Mask Register
-
-
-
- 0xdc
- read
- -
-
-
-
- 0xde
- write
- Write All Mask Register Bits
-
-
-
- 0xdf
- read
- Read All Mask Register Bits (only in Intel
- 82374)
-
-
-
-
-
-
-
- 0x80–0x9f DMA Page Registers
-
-
-
-
-
- 0x87
- r/w
- Channel 0 Low byte (23-16) page Register
-
-
-
- 0x83
- r/w
- Channel 1 Low byte (23-16) page Register
-
-
-
- 0x81
- r/w
- Channel 2 Low byte (23-16) page Register
-
-
-
- 0x82
- r/w
- Channel 3 Low byte (23-16) page Register
-
-
-
- 0x8b
- r/w
- Channel 5 Low byte (23-16) page Register
-
-
-
- 0x89
- r/w
- Channel 6 Low byte (23-16) page Register
-
-
-
- 0x8a
- r/w
- Channel 7 Low byte (23-16) page Register
-
-
-
- 0x8f
- r/w
- Low byte page Refresh
-
-
-
-
-
-
-
- 0x400–0x4ff 82374 Enhanced DMA Registers
-
- The Intel 82374 EISA System Component (ESC) was introduced in
- early 1996 and includes a DMA controller that provides a superset of
- 8237 functionality as well as other PC-compatible core peripheral
- components in a single package. This chip is targeted at both EISA
- and PCI platforms, and provides modern DMA features like
- scatter-gather, ring buffers as well as direct access by the system
- DMA to all 32 bits of address space.
-
- If these features are used, code should also be included to
- provide similar functionality in the previous 16 years worth of
- PC-compatible computers. For compatibility reasons, some of the
- 82374 registers must be programmed after
- programming the traditional 8237 registers for each transfer.
- Writing to a traditional 8237 register forces the contents of some
- of the 82374 enhanced registers to zero to provide backward software
- compatibility.
-
-
-
-
-
- 0x401
- r/w
- Channel 0 High byte (bits 23-16) word count
-
-
-
- 0x403
- r/w
- Channel 1 High byte (bits 23-16) word count
-
-
-
- 0x405
- r/w
- Channel 2 High byte (bits 23-16) word count
-
-
-
- 0x407
- r/w
- Channel 3 High byte (bits 23-16) word count
-
-
-
- 0x4c6
- r/w
- Channel 5 High byte (bits 23-16) word count
-
-
-
- 0x4ca
- r/w
- Channel 6 High byte (bits 23-16) word count
-
-
-
- 0x4ce
- r/w
- Channel 7 High byte (bits 23-16) word count
-
-
-
- 0x487
- r/w
- Channel 0 High byte (bits 31-24) page Register
-
-
-
- 0x483
- r/w
- Channel 1 High byte (bits 31-24) page Register
-
-
-
- 0x481
- r/w
- Channel 2 High byte (bits 31-24) page Register
-
-
-
- 0x482
- r/w
- Channel 3 High byte (bits 31-24) page Register
-
-
-
- 0x48b
- r/w
- Channel 5 High byte (bits 31-24) page Register
-
-
-
- 0x489
- r/w
- Channel 6 High byte (bits 31-24) page Register
-
-
-
- 0x48a
- r/w
- Channel 6 High byte (bits 31-24) page Register
-
-
-
- 0x48f
- r/w
- High byte page Refresh
-
-
-
- 0x4e0
- r/w
- Channel 0 Stop Register (bits 7-2)
-
-
-
- 0x4e1
- r/w
- Channel 0 Stop Register (bits 15-8)
-
-
-
- 0x4e2
- r/w
- Channel 0 Stop Register (bits 23-16)
-
-
-
- 0x4e4
- r/w
- Channel 1 Stop Register (bits 7-2)
-
-
-
- 0x4e5
- r/w
- Channel 1 Stop Register (bits 15-8)
-
-
-
- 0x4e6
- r/w
- Channel 1 Stop Register (bits 23-16)
-
-
-
- 0x4e8
- r/w
- Channel 2 Stop Register (bits 7-2)
-
-
-
- 0x4e9
- r/w
- Channel 2 Stop Register (bits 15-8)
-
-
-
- 0x4ea
- r/w
- Channel 2 Stop Register (bits 23-16)
-
-
-
- 0x4ec
- r/w
- Channel 3 Stop Register (bits 7-2)
-
-
-
- 0x4ed
- r/w
- Channel 3 Stop Register (bits 15-8)
-
-
-
- 0x4ee
- r/w
- Channel 3 Stop Register (bits 23-16)
-
-
-
- 0x4f4
- r/w
- Channel 5 Stop Register (bits 7-2)
-
-
-
- 0x4f5
- r/w
- Channel 5 Stop Register (bits 15-8)
-
-
-
- 0x4f6
- r/w
- Channel 5 Stop Register (bits 23-16)
-
-
-
- 0x4f8
- r/w
- Channel 6 Stop Register (bits 7-2)
-
-
-
- 0x4f9
- r/w
- Channel 6 Stop Register (bits 15-8)
-
-
-
- 0x4fa
- r/w
- Channel 6 Stop Register (bits 23-16)
-
-
-
- 0x4fc
- r/w
- Channel 7 Stop Register (bits 7-2)
-
-
-
- 0x4fd
- r/w
- Channel 7 Stop Register (bits 15-8)
-
-
-
- 0x4fe
- r/w
- Channel 7 Stop Register (bits 23-16)
-
-
-
- 0x40a
- write
- Channels 0-3 Chaining Mode Register
-
-
-
- 0x40a
- read
- Channel Interrupt Status Register
-
-
-
- 0x4d4
- write
- Channels 4-7 Chaining Mode Register
-
-
-
- 0x4d4
- read
- Chaining Mode Status
-
-
-
- 0x40c
- read
- Chain Buffer Expiration Control Register
-
-
-
- 0x410
- write
- Channel 0 Scatter-Gather Command Register
-
-
-
- 0x411
- write
- Channel 1 Scatter-Gather Command Register
-
-
-
- 0x412
- write
- Channel 2 Scatter-Gather Command Register
-
-
-
- 0x413
- write
- Channel 3 Scatter-Gather Command Register
-
-
-
- 0x415
- write
- Channel 5 Scatter-Gather Command Register
-
-
-
- 0x416
- write
- Channel 6 Scatter-Gather Command Register
-
-
-
- 0x417
- write
- Channel 7 Scatter-Gather Command Register
-
-
-
- 0x418
- read
- Channel 0 Scatter-Gather Status Register
-
-
-
- 0x419
- read
- Channel 1 Scatter-Gather Status Register
-
-
-
- 0x41a
- read
- Channel 2 Scatter-Gather Status Register
-
-
-
- 0x41b
- read
- Channel 3 Scatter-Gather Status Register
-
-
-
- 0x41d
- read
- Channel 5 Scatter-Gather Status Register
-
-
-
- 0x41e
- read
- Channel 5 Scatter-Gather Status Register
-
-
-
- 0x41f
- read
- Channel 7 Scatter-Gather Status Register
-
-
-
- 0x420-0x423
- r/w
- Channel 0 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
- 0x424-0x427
- r/w
- Channel 1 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
- 0x428-0x42b
- r/w
- Channel 2 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
- 0x42c-0x42f
- r/w
- Channel 3 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
- 0x434-0x437
- r/w
- Channel 5 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
- 0x438-0x43b
- r/w
- Channel 6 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
- 0x43c-0x43f
- r/w
- Channel 7 Scatter-Gather Descriptor Table Pointer
- Register
-
-
-
-
-
-
-
-
-
- The FreeBSD VM System
-
- Contributed by &a.dillon;. 6 Feb 1999
-
-
- Management of physical
- memory—vm_page_t
-
- Physical memory is managed on a page-by-page basis through the
- vm_page_t structure. Pages of physical memory are
- categorized through the placement of their respective
- vm_page_t structures on one of several paging
- queues.
-
- A page can be in a wired, active, inactive, cache, or free state.
- Except for the wired state, the page is typically placed in a doubly
- link list queue representing the state that it is in. Wired pages
- are not placed on any queue.
-
- FreeBSD implements a more involved paging queue for cached and
- free pages in order to implement page coloring. Each of these states
- involves multiple queues arranged according to the size of the
- processor's L1 and L2 caches. When a new page needs to be allocated,
- FreeBSD attempts to obtain one that is reasonably well aligned from
- the point of view of the L1 and L2 caches relative to the VM object
- the page is being allocated for.
-
- Additionally, a page may be held with a reference count or locked
- with a busy count. The VM system also implements an ultimate
- locked
state for a page using the PG_BUSY bit in the page's
- flags.
-
- In general terms, each of the paging queues operates in a LRU
- fashion. A page is typically placed in a wired or active state
- initially. When wired, the page is usually associated with a page
- table somewhere. The VM system ages the page by scanning pages in a
- more active paging queue (LRU) in order to move them to a less-active
- paging queue. Pages that get moved into the cache are still
- associated with a VM object but are candidates for immediate reuse.
- Pages in the free queue are truly free. FreeBSD attempts to minimize
- the number of pages in the free queue, but a certain minimum number of
- truly free pages must be maintained in order to accommodate page
- allocation at interrupt time.
-
- If a process attempts to access a page that does not exist in its
- page table but does exist in one of the paging queues ( such as the
- inactive or cache queues), a relatively inexpensive page reactivation
- fault occurs which causes the page to be reactivated. If the page
- does not exist in system memory at all, the process must block while
- the page is brought in from disk.
-
- FreeBSD dynamically tunes its paging queues and attempts to
- maintain reasonable ratios of pages in the various queues as well as
- attempts to maintain a reasonable breakdown of clean v.s. dirty pages.
- The amount of rebalancing that occurs depends on the system's memory
- load. This rebalancing is implemented by the pageout daemon and
- involves laundering dirty pages (syncing them with their backing
- store), noticing when pages are activity referenced (resetting their
- position in the LRU queues or moving them between queues), migrating
- pages between queues when the queues are out of balance, and so forth.
- FreeBSD's VM system is willing to take a reasonable number of
- reactivation page faults to determine how active or how idle a page
- actually is. This leads to better decisions being made as to when to
- launder or swap-out a page.
-
-
-
- The unified buffer
- cache—vm_object_t
-
- FreeBSD implements the idea of a generic VM object
.
- VM objects can be associated with backing store of various
- types—unbacked, swap-backed, physical device-backed, or
- file-backed storage. Since the filesystem uses the same VM objects to
- manage in-core data relating to files, the result is a unified buffer
- cache.
-
- VM objects can be shadowed. That is, they
- can be stacked on top of each other. For example, you might have a
- swap-backed VM object stacked on top of a file-backed VM object in
- order to implement a MAP_PRIVATE mmap()ing. This stacking is also
- used to implement various sharing properties, including,
- copy-on-write, for forked address spaces.
-
- It should be noted that a vm_page_t can only be
- associated with one VM object at a time. The VM object shadowing
- implements the perceived sharing of the same page across multiple
- instances.
-
-
-
- Filesystem I/O—struct buf
-
- vnode-backed VM objects, such as file-backed objects, generally
- need to maintain their own clean/dirty info independent from the VM
- system's idea of clean/dirty. For example, when the VM system decides
- to synchronize a physical page to its backing store, the VM system
- needs to mark the page clean before the page is actually written to
- its backing s tore. Additionally, filesystems need to be able to map
- portions of a file or file metadata into KVM in order to operate on
- it.
-
- The entities used to manage this are known as filesystem buffers,
- struct buf's, and also known as
- bp's. When a filesystem needs to operate on a
- portion of a VM object, it typically maps part of the object into a
- struct buf and the maps the pages in the struct buf into KVM. In the
- same manner, disk I/O is typically issued by mapping portions of
- objects into buffer structures and then issuing the I/O on the buffer
- structures. The underlying vm_page_t's are typically busied for the
- duration of the I/O. Filesystem buffers also have their own notion of
- being busy, which is useful to filesystem driver code which would
- rather operate on filesystem buffers instead of hard VM pages.
-
- FreeBSD reserves a limited amount of KVM to hold mappings from
- struct bufs, but it should be made clear that this KVM is used solely
- to hold mappings and does not limit the ability to cache data.
- Physical data caching is strictly a function of
- vm_page_t's, not filesystem buffers. However,
- since filesystem buffers are used placehold I/O, they do inherently
- limit the amount of concurrent I/O possible. As there are usually a
- few thousand filesystem buffers available, this is not usually a
- problem.
-
-
-
- Mapping Page Tables - vm_map_t, vm_entry_t
-
- FreeBSD separates the physical page table topology from the VM
- system. All hard per-process page tables can be reconstructed on the
- fly and are usually considered throwaway. Special page tables such as
- those managing KVM are typically permanently preallocated. These page
- tables are not throwaway.
-
- FreeBSD associates portions of vm_objects with address ranges in
- virtual memory through vm_map_t and
- vm_entry_t structures. Page tables are directly
- synthesized from the
- vm_map_t/vm_entry_t/
- vm_object_t hierarchy. Remember when I mentioned
- that physical pages are only directly associated with a
- vm_object. Well, that isn't quite true.
- vm_page_t's are also linked into page tables that
- they are actively associated with. One vm_page_t
- can be linked into several pmaps, as page tables
- are called. However, the hierarchical association holds so all
- references to the same page in the same object reference the same
- vm_page_t and thus give us buffer cache unification
- across the board.
-
-
-
- KVM Memory Mapping
-
- FreeBSD uses KVM to hold various kernel structures. The single
- largest entity held in KVM is the filesystem buffer cache. That is,
- mappings relating to struct buf entities.
-
- Unlike Linux, FreeBSD does NOT map all of physical memory into
- KVM. This means that FreeBSD can handle memory configurations up to
- 4G on 32 bit platforms. In fact, if the mmu were capable of it,
- FreeBSD could theoretically handle memory configurations up to 8TB on
- a 32 bit platform. However, since most 32 bit platforms are only
- capable of mapping 4GB of ram, this is a moot point.
-
- KVM is managed through several mechanisms. The main mechanism
- used to manage KVM is the zone allocator. The
- zone allocator takes a chunk of KVM and splits it up into
- constant-sized blocks of memory in order to allocate a specific type
- of structure. You can use vmstat -m to get an
- overview of current KVM utilization broken down by zone.
-
-
-
- Tuning the FreeBSD VM system
-
- A concerted effort has been made to make the FreeBSD kernel
- dynamically tune itself. Typically you do not need to mess with
- anything beyond the maxusers and
- NMBCLUSTERS kernel config options. That is, kernel
- compilation options specified in (typically)
- /usr/src/sys/i386/conf/CONFIG_FILE.
- A description of all available kernel configuration options can be
- found in /usr/src/sys/i386/conf/LINT.
-
- In a large system configuration you may wish to increase
- maxusers. Values typically range from 10 to 128.
- Note that raising maxusers too high can cause the
- system to overflow available KVM resulting in unpredictable operation.
- It is better to leave maxusers at some reasonable number and add other
- options, such as NMBCLUSTERS, to increase specific
- resources.
-
- If your system is going to use the network heavily, you may want
- to increase NMBCLUSTERS. Typical values range from
- 1024 to 4096.
-
- The NBUF parameter is also traditionally used
- to scale the system. This parameter determines the amount of KVA the
- system can use to map filesystem buffers for I/O. Note that this
- parameter has nothing whatsoever to do with the unified buffer cache!
- This parameter is dynamically tuned in 3.0-CURRENT and later kernels
- and should generally not be adjusted manually. We recommend that you
- not try to specify an NBUF
- parameter. Let the system pick it. Too small a value can result in
- extremely inefficient filesystem operation while too large a value can
- starve the page queues by causing too many pages to become wired
- down.
-
- By default, FreeBSD kernels are not optimized. You can set
- debugging and optimization flags with the
- makeoptions directive in the kernel configuration.
- Note that you should not use unless you can
- accommodate the large (typically 7 MB+) kernels that result.
-
- makeoptions DEBUG="-g"
-makeoptions COPTFLAGS="-O -pipe"
-
- Sysctl provides a way to tune kernel parameters at run-time. You
- typically do not need to mess with any of the sysctl variables,
- especially the VM related ones.
-
- Run time VM and system tuning is relatively straightforward.
- First, use softupdates on your UFS/FFS filesystems whenever possible.
- /usr/src/contrib/sys/softupdates/README contains
- instructions (and restrictions) on how to configure it up.
-
- Second, configure sufficient swap. You should have a swap
- partition configured on each physical disk, up to four, even on your
- work
disks. You should have at least 2x the swap space
- as you have main memory, and possibly even more if you do not have a
- lot of memory. You should also size your swap partition based on the
- maximum memory configuration you ever intend to put on the machine so
- you do not have to repartition your disks later on. If you want to be
- able to accommodate a crash dump, your first swap partition must be at
- least as large as main memory and /var/crash must
- have sufficient free space to hold the dump.
-
- NFS-based swap is perfectly acceptable on -4.x or later systems,
- but you must be aware that the NFS server will take the brunt of the
- paging load.
-
-
-
-
- IPv6/IPsec Implementation
-
- Contributed by &a.shin;, 5 March
- 2000.
-
- This section should explain IPv6 and IPsec related implementation
- internals. These functionalities are derived from KAME project
-
-
- IPv6
-
-
- Conformance
-
- The IPv6 related functions conforms, or tries to conform to
- the latest set of IPv6 specifications. For future reference we list
- some of the relevant documents below (NOTE: this
- is not a complete list - this is too hard to maintain...).
-
- For details please refer to specific chapter in the document,
- RFCs, manpages, or comments in the source code.
-
- Conformance tests have been performed on the KAME STABLE kit
- at TAHI project. Results can be viewed at http://www.tahi.org/report/KAME/
- . We also attended Univ. of New Hampshire IOL tests (http://www.iol.unh.edu/) in the
- past, with our past snapshots.
-
-
-
- RFC1639: FTP Operation Over Big Address Records
- (FOOBAR)
-
-
- RFC2428 is preferred over RFC1639. FTP clients will
- first try RFC2428, then RFC1639 if failed.
-
-
-
-
-
- RFC1886: DNS Extensions to support IPv6
-
-
-
- RFC1933: Transition Mechanisms for IPv6 Hosts and
- Routers
-
-
- IPv4 compatible address is not supported.
-
-
- automatic tunneling (described in 4.3 of this RFC) is not
- supported.
-
-
- &man.gif.4; interface implements IPv[46]-over-IPv[46]
- tunnel in a generic way, and it covers "configured tunnel"
- described in the spec. See 23.5.1.5
- in this document for details.
-
-
-
-
-
- RFC1981: Path MTU Discovery for IPv6
-
-
-
- RFC2080: RIPng for IPv6
-
-
- usr.sbin/route6d support this.
-
-
-
-
-
- RFC2292: Advanced Sockets API for IPv6
-
-
- For supported library functions/kernel APIs, see
- sys/netinet6/ADVAPI.
-
-
-
-
-
- RFC2362: Protocol Independent Multicast-Sparse
- Mode (PIM-SM)
-
-
- RFC2362 defines packet formats for PIM-SM.
- draft-ietf-pim-ipv6-01.txt is
- written based on this.
-
-
-
-
-
- RFC2373: IPv6 Addressing Architecture
-
-
- supports node required addresses, and conforms to
- the scope requirement.
-
-
-
-
-
- RFC2374: An IPv6 Aggregatable Global Unicast Address
- Format
-
-
- supports 64-bit length of Interface ID.
-
-
-
-
-
- RFC2375: IPv6 Multicast Address Assignments
-
-
- Userland applications use the well-known addresses
- assigned in the RFC.
-
-
-
-
-
- RFC2428: FTP Extensions for IPv6 and NATs
-
-
- RFC2428 is preferred over RFC1639. FTP clients will
- first try RFC2428, then RFC1639 if failed.
-
-
-
-
-
- RFC2460: IPv6 specification
-
-
-
- RFC2461: Neighbor discovery for IPv6
-
-
- See 23.5.1.2
- in this document for details.
-
-
-
-
-
- RFC2462: IPv6 Stateless Address Autoconfiguration
-
-
- See 23.5.1.4 in this
- document for details.
-
-
-
-
-
- RFC2463: ICMPv6 for IPv6 specification
-
-
- See 23.5.1.9 in this
- document for details.
-
-
-
-
-
- RFC2464: Transmission of IPv6 Packets over Ethernet
- Networks
-
-
-
- RFC2465: MIB for IPv6: Textual Conventions and General
- Group
-
-
- Necessary statistics are gathered by the kernel. Actual
- IPv6 MIB support is provided as a patchkit for ucd-snmp.
-
-
-
-
-
- RFC2466: MIB for IPv6: ICMPv6 group
-
-
- Necessary statistics are gathered by the kernel. Actual
- IPv6 MIB support is provided as patchkit for ucd-snmp.
-
-
-
-
-
- RFC2467: Transmission of IPv6 Packets over FDDI
- Networks
-
-
-
- RFC2497: Transmission of IPv6 packet over ARCnet
- Networks
-
-
-
- RFC2553: Basic Socket Interface Extensions for IPv6
-
-
- IPv4 mapped address (3.7) and special behavior of IPv6
- wildcard bind socket (3.8) are supported. See 23.5.1.12
- in this document for details.
-
-
-
-
-
- RFC2675: IPv6 Jumbograms
-
-
- See 23.5.1.7 in
- this document for details.
-
-
-
-
-
- RFC2710: Multicast Listener Discovery for IPv6
-
-
-
- RFC2711: IPv6 router alert option
-
-
-
- draft-ietf-ipngwg-router-renum-08: Router
- renumbering for IPv6
-
-
-
- draft-ietf-ipngwg-icmp-namelookups-02:
- IPv6 Name Lookups Through ICMP
-
-
-
- draft-ietf-ipngwg-icmp-name-lookups-03:
- IPv6 Name Lookups Through ICMP
-
-
-
- draft-ietf-pim-ipv6-01.txt:
- PIM for IPv6
-
-
- &man.pim6dd.8; implements dense mode. &man.pim6sd.8;
- implements sparse mode.
-
-
-
-
-
- draft-itojun-ipv6-tcp-to-anycast-00:
- Disconnecting TCP connection toward IPv6 anycast address
-
-
-
- draft-yamamoto-wideipv6-comm-model-00
-
-
-
- See 23.5.1.6 in this
- document for details.
-
-
-
-
-
- draft-ietf-ipngwg-scopedaddr-format-00.txt
- : An Extension of Format for IPv6 Scoped
- Addresses
-
-
-
-
-
- Neighbor Discovery
-
- Neighbor Discovery is fairly stable. Currently Address
- Resolution, Duplicated Address Detection, and Neighbor Unreachability
- Detection are supported. In the near future we will be adding Proxy
- Neighbor Advertisement support in the kernel and Unsolicited Neighbor
- Advertisement transmission command as admin tool.
-
- If DAD fails, the address will be marked "duplicated" and
- message will be generated to syslog (and usually to console). The
- "duplicated" mark can be checked with &man.ifconfig.8;. It is
- administrators' responsibility to check for and recover from DAD
- failures. The behavior should be improved in the near future.
-
- Some of the network driver loops multicast packets back to itself,
- even if instructed not to do so (especially in promiscuous mode).
- In such cases DAD may fail, because DAD engine sees inbound NS packet
- (actually from the node itself) and considers it as a sign of duplicate.
- You may want to look at #if condition marked "heuristics" in
- sys/netinet6/nd6_nbr.c:nd6_dad_timer() as workaround (note that the code
- fragment in "heuristics" section is not spec conformant).
-
- Neighbor Discovery specification (RFC2461) does not talk about
- neighbor cache handling in the following cases:
-
-
-
- when there was no neighbor cache entry, node
- received unsolicited RS/NS/NA/redirect packet without
- link-layer address
-
-
- neighbor cache handling on medium without link-layer
- address (we need a neighbor cache entry for IsRouter bit)
-
-
-
- For first case, we implemented workaround based on discussions
- on IETF ipngwg mailing list. For more details, see the comments in
- the source code and email thread started from (IPng 7155), dated
- Feb 6 1999.
-
- IPv6 on-link determination rule (RFC2461) is quite different
- from assumptions in BSD network code. At this moment, no on-link
- determination rule is supported where default router list is empty
- (RFC2461, section 5.2, last sentence in 2nd paragraph - note that
- the spec misuse the word "host" and "node" in several places in
- the section).
-
- To avoid possible DoS attacks and infinite loops, only 10
- options on ND packet is accepted now. Therefore, if you have 20
- prefix options attached to RA, only the first 10 prefixes will be
- recognized. If this troubles you, please ask it on FREEBSD-CURRENT
- mailing list and/or modify nd6_maxndopt in
- sys/netinet6/nd6.c. If there are high demands
- we may provide sysctl knob for the variable.
-
-
-
- Scope Index
-
- IPv6 uses scoped addresses. Therefore, it is very important to
- specify scope index (interface index for link-local address, or
- site index for site-local address) with an IPv6 address. Without
- scope index, scoped IPv6 address is ambiguous to the kernel, and
- kernel will not be able to determine the outbound interface for a
- packet.
-
- Ordinary userland applications should use advanced API
- (RFC2292) to specify scope index, or interface index. For similar
- purpose, sin6_scope_id member in sockaddr_in6 structure is defined
- in RFC2553. However, the semantics for sin6_scope_id is rather vague.
- If you care about portability of your application, we suggest you to
- use advanced API rather than sin6_scope_id.
-
- In the kernel, an interface index for link-local scoped address is
- embedded into 2nd 16bit-word (3rd and 4th byte) in IPv6 address. For
- example, you may see something like:
-
-
-
- fe80:1::200:f8ff:fe01:6317
-
-
- in the routing table and interface address structure (struct
- in6_ifaddr). The address above is a link-local unicast address
- which belongs to a network interface whose interface identifier is 1.
- The embedded index enables us to identify IPv6 link local
- addresses over multiple interfaces effectively and with only a
- little code change.
-
- Routing daemons and configuration programs, like &man.route6d.8;
- and &man.ifconfig.8;, will need to manipulate the "embedded" scope
- index. These programs use routing sockets and ioctls (like
- SIOCGIFADDR_IN6) and the kernel API will return IPv6 addresses with
- 2nd 16bit-word filled in. The APIs are for manipulating kernel
- internal structure. Programs that use these APIs have to be prepared
- about differences in kernels anyway.
-
- When you specify scoped address to the command line, NEVER write
- the embedded form (such as ff02:1::1 or fe80:2::fedc). This is not
- supposed to work. Always use standard form, like ff02::1 or
- fe80::fedc, with command line option for specifying interface (like
- ping6 -I ne0 ff02::1). In general, if a command
- does not have command line option to specify outgoing interface, that
- command is not ready to accept scoped address. This may seem to be
- opposite from IPv6's premise to support "dentist office" situation.
- We believe that specifications need some improvements for this.
-
- Some of the userland tools support extended numeric IPv6 syntax,
- as documented in
- draft-ietf-ipngwg-scopedaddr-format-00.txt. You
- can specify outgoing link, by using name of the outgoing interface
- like "fe80::1%ne0". This way you will be able to specify link-local
- scoped address without much trouble.
-
- To use this extension in your program, you'll need to use
- &man.getaddrinfo.3;, and &man.getnameinfo.3; with NI_WITHSCOPEID.
- The implementation currently assumes 1-to-1 relationship between a
- link and an interface, which is stronger than what specs say.
-
-
-
- Plug and Play
-
- Most of the IPv6 stateless address autoconfiguration is implemented
- in the kernel. Neighbor Discovery functions are implemented in the
- kernel as a whole. Router Advertisement (RA) input for hosts is
- implemented in the kernel. Router Solicitation (RS) output for
- endhosts, RS input for routers, and RA output for routers are
- implemented in the userland.
-
-
- Assignment of link-local, and special addresses
-
- IPv6 link-local address is generated from IEEE802 address
- (ethernet MAC address). Each of interface is assigned an IPv6
- link-local address automatically, when the interface becomes up
- (IFF_UP). Also, direct route for the link-local address is added
- to routing table.
-
- Here is an output of netstat command:
-
-
-Internet6:
-Destination Gateway Flags Netif Expire
-fe80:1::%ed0/64 link#1 UC ed0
-fe80:2::%ep0/64 link#2 UC ep0
-
-
- Interfaces that has no IEEE802 address (pseudo interfaces
- like tunnel interfaces, or ppp interfaces) will borrow IEEE802
- address from other interfaces, such as ethernet interfaces,
- whenever possible. If there is no IEEE802 hardware attached,
- last-resort pseudorandom value, which is from MD5(hostname), will
- be used as source of link-local address. If it is not suitable
- for your usage, you will need to configure the link-local address
- manually.
-
- If an interface is not capable of handling IPv6 (such as
- lack of multicast support), link-local address will not be
- assigned to that interface. See section 2 for details.
-
- Each interface joins the solicited multicast address and the
- link-local all-nodes multicast addresses (e.g. fe80::1:ff01:6317
- and ff02::1, respectively, on the link the interface is attached).
- In addition to a link-local address, the loopback address (::1)
- will be assigned to the loopback interface. Also, ::1/128 and
- ff01::/32 are automatically added to routing table, and loopback
- interface joins node-local multicast group ff01::1.
-
-
-
- Stateless address autoconfiguration on hosts
-
- In IPv6 specification, nodes are separated into two categories:
- routers and hosts. Routers
- forward packets addressed to others, hosts does not forward the
- packets. net.inet6.ip6.forwarding defines whether this node is
- router or host (router if it is 1, host if it is 0).
-
- When a host hears Router Advertisement from the router, a host
- may autoconfigure itself by stateless address autoconfiguration.
- This behavior can be controlled by net.inet6.ip6.accept_rtadv (host
- autoconfigures itself if it is set to 1). By autoconfiguration,
- network address prefix for the receiving interface (usually global
- address prefix) is added. Default route is also configured.
- Routers periodically generate Router Advertisement packets. To
- request an adjacent router to generate RA packet, a host can
- transmit Router Solicitation. To generate a RS packet at any time,
- use the rtsol command. &man.rtsold.8; daemon is
- also available. &man.rtsold.8; generates Router Solicitation whenever
- necessary, and it works great for nomadic usage (notebooks/laptops).
- If one wishes to ignore Router Advertisements, use sysctl to set
- net.inet6.ip6.accept_rtadv to 0.
-
- To generate Router Advertisement from a router, use the
- &man.rtadvd.8 daemon.
-
- Note that, IPv6 specification assumes the following items, and
- nonconforming cases are left unspecified:
-
-
-
- Only hosts will listen to router advertisements
-
-
- Hosts have single network interface (except loopback)
-
-
-
- Therefore, this is unwise to enable net.inet6.ip6.accept_rtadv
- on routers, or multi-interface host. A misconfigured node can
- behave strange (nonconforming configuration allowed for those who
- would like to do some experiments).
-
- To summarize the sysctl knob:
-
-
- accept_rtadv forwarding role of the node
- --- --- ---
- 0 0 host (to be manually configured)
- 0 1 router
- 1 0 autoconfigured host
- (spec assumes that host has single
- interface only, autoconfigured host
- with multiple interface is
- out-of-scope)
- 1 1 invalid, or experimental
- (out-of-scope of spec)
-
-
- RFC2462 has validation rule against incoming RA prefix
- information option, in 5.5.3 (e). This is to protect hosts from
- malicious (or misconfigured) routers that advertise very short
- prefix lifetime. There was an update from Jim Bound to ipngwg
- mailing list (look for "(ipng 6712)" in the archive) and it is
- implemented Jim's update.
-
- See 23.5.1.2 in
- the document for relationship between DAD and
- autoconfiguration.
-
-
-
-
- Generic tunnel interface
-
- GIF (Generic InterFace) is a pseudo interface for configured
- tunnel. Details are described in &man.gif.4;. Currently
-
-
-
- v6 in v6
-
-
- v6 in v4
-
-
- v4 in v6
-
-
- v4 in v4
-
-
-
- are available. Use &man.gifconfig.8; to assign physical (outer)
- source and destination address to gif interfaces. Configuration that
- uses same address family for inner and outer IP header (v4 in v4, or
- v6 in v6) is dangerous. It is very easy to configure interfaces and
- routing tables to perform infinite level of tunneling.
- Please be warned.
-
- gif can be configured to be ECN-friendly. See 23.5.4.5 for ECN-friendliness of
- tunnels, and &man.gif.4; for how to configure.
-
- If you would like to configure an IPv4-in-IPv6 tunnel with gif
- interface, read &man.gif.4; carefully. You will need to
- remove IPv6 link-local address automatically assigned to the gif
- interface.
-
-
-
- Source Address Selection
-
- Current source selection rule is scope oriented (there are some
- exceptions - see below). For a given destination, a source IPv6
- address is selected by the following rule:
-
-
-
- If the source address is explicitly specified by
- the user (e.g. via the advanced API), the specified address
- is used.
-
-
-
- If there is an address assigned to the outgoing
- interface (which is usually determined by looking up the
- routing table) that has the same scope as the destination
- address, the address is used.
-
- This is the most typical case.
-
-
-
- If there is no address that satisfies the above
- condition, choose a global address assigned to one of
- the interfaces on the sending node.
-
-
-
- If there is no address that satisfies the above condition,
- and destination address is site local scope, choose a site local
- address assigned to one of the interfaces on the sending node.
-
-
-
-
- If there is no address that satisfies the above condition,
- choose the address associated with the routing table entry for the
- destination. This is the last resort, which may cause scope
- violation.
-
-
-
- For instance, ::1 is selected for ff01::1,
- fe80:1::200:f8ff:fe01:6317 for fe80:1::2a0:24ff:feab:839b (note
- that embedded interface index - described in 23.5.1.3 - helps us
- choose the right source address. Those embedded indices will not
- be on the wire). If the outgoing interface has multiple address for
- the scope, a source is selected longest match basis (rule 3). Suppose
- 3ffe:501:808:1:200:f8ff:fe01:6317 and 3ffe:2001:9:124:200:f8ff:fe01:6317
- are given to the outgoing interface. 3ffe:501:808:1:200:f8ff:fe01:6317
- is chosen as the source for the destination 3ffe:501:800::1.
-
- Note that the above rule is not documented in the IPv6 spec.
- It is considered "up to implementation" item. There are some cases
- where we do not use the above rule. One example is connected TCP
- session, and we use the address kept in tcb as the source. Another
- example is source address for Neighbor Advertisement. Under the spec
- (RFC2461 7.2.2) NA's source should be the target address of the
- corresponding NS's target. In this case we follow the spec rather
- than the above longest-match rule.
-
- For new connections (when rule 1 does not apply), deprecated
- addresses (addresses with preferred lifetime = 0) will not be chosen
- as source address if other choices are available. If no other choices
- are available, deprecated address will be used as a last resort. If
- there are multiple choice of deprecated addresses, the above scope
- rule will be used to choose from those deprecated addresses. If you
- would like to prohibit the use of deprecated address for some reason,
- configure net.inet6.ip6.use_deprecated to 0. The issue related to
- deprecated address is described in RFC2462 5.5.4 (NOTE: there is
- some debate underway in IETF ipngwg on how to use "deprecated"
- address).
-
-
-
- Jumbo Payload
-
- The Jumbo Payload hop-by-hop option is implemented and can
- be used to send IPv6 packets with payloads longer than 65,535 octets.
- But currently no physical interface whose MTU is more than 65,535 is
- supported, so such payloads can be seen only on the loopback
- interface (i.e. lo0).
-
- If you want to try jumbo payloads, you first have to reconfigure
- the kernel so that the MTU of the loopback interface is more than
- 65,535 bytes; add the following to the kernel configuration file:
-
-
- options "LARGE_LOMTU" #To test jumbo payload
-
-
- and recompile the new kernel.
-
- Then you can test jumbo payloads by the &man.ping6.8; command
- with -b and -s options. The -b option must be specified to enlarge
- the size of the socket buffer and the -s option specifies the length
- of the packet, which should be more than 65,535. For example,
- type as follows:
-
-
- &prompt.user; ping6 -b 70000 -s 68000 ::1
-
-
- The IPv6 specification requires that the Jumbo Payload option
- must not be used in a packet that carries a fragment header. If
- this condition is broken, an ICMPv6 Parameter Problem message must
- be sent to the sender. specification is followed, but you cannot
- usually see an ICMPv6 error caused by this requirement.
-
- When an IPv6 packet is received, the frame length is checked and
- compared to the length specified in the payload length field of the
- IPv6 header or in the value of the Jumbo Payload option, if any. If
- the former is shorter than the latter, the packet is discarded and
- statistics are incremented. You can see the statistics as output of
- &man.netstat.8; command with `-s -p ip6' option:
-
-
- &prompt.user; netstat -s -p ip6
- ip6:
- (snip)
- 1 with data size < data length
-
-
- So, kernel does not send an ICMPv6 error unless the erroneous
- packet is an actual Jumbo Payload, that is, its packet size is more
- than 65,535 bytes. As described above, currently no physical interface
- with such a huge MTU is supported, so it rarely returns an
- ICMPv6 error.
-
- TCP/UDP over jumbogram is not supported at this moment. This
- is because we have no medium (other than loopback) to test this.
- Contact us if you need this.
-
- IPsec does not work on jumbograms. This is due to some
- specification twists in supporting AH with jumbograms (AH header
- size influences payload length, and this makes it real hard to
- authenticate inbound packet with jumbo payload option as well as AH).
-
-
- There are fundamental issues in *BSD support for jumbograms.
- We would like to address those, but we need more time to finalize
- these. To name a few:
-
-
-
- mbuf pkthdr.len field is typed as "int" in 4.4BSD, so
- it will not hold jumbogram with len > 2G on 32bit architecture
- CPUs. If we would like to support jumbogram properly, the field
- must be expanded to hold 4G + IPv6 header + link-layer header.
- Therefore, it must be expanded to at least int64_t
- (u_int32_t is NOT enough).
-
-
-
- We mistakingly use "int" to hold packet length in many
- places. We need to convert them into larger integral type.
- It needs a great care, as we may experience overflow during
- packet length computation.
-
-
-
- We mistakingly check for ip6_plen field of IPv6 header
- for packet payload length in various places. We should be
- checking mbuf pkthdr.len instead. ip6_input() will perform
- sanity check on jumbo payload option on input, and we can
- safely use mbuf pkthdr.len afterwards.
-
-
-
- TCP code needs a careful update in bunch of places, of
- course.
-
-
-
-
-
- Loop prevention in header processing
-
- IPv6 specification allows arbitrary number of extension headers
- to be placed onto packets. If we implement IPv6 packet processing
- code in the way BSD IPv4 code is implemented, kernel stack may
- overflow due to long function call chain. sys/netinet6 code
- is carefully designed to avoid kernel stack overflow. Because of
- this, sys/netinet6 code defines its own protocol switch
- structure, as "struct ip6protosw" (see
- netinet6/ip6protosw.h). There is no such
- update to IPv4 part (sys/netinet) for compatibility, but small
- change is added to its pr_input() prototype. So "struct ipprotosw"
- is also defined. Because of this, if you receive IPsec-over-IPv4
- packet with massive number of IPsec headers, kernel stack may blow
- up. IPsec-over-IPv6 is okay. (Off-course, for those all IPsec
- headers to be processed, each such IPsec header must pass each
- IPsec check. So an anonymous attacker won't be able to do such an
- attack.)
-
-
-
- ICMPv6
-
- After RFC2463 was published, IETF ipngwg has decided to
- disallow ICMPv6 error packet against ICMPv6 redirect, to prevent
- ICMPv6 storm on a network medium. This is already implemented
- into the kernel.
-
-
-
- Applications
-
- For userland programming, we support IPv6 socket API as
- specified in RFC2553, RFC2292 and upcoming internet drafts.
-
- TCP/UDP over IPv6 is available and quite stable. You can
- enjoy &man.telnet.1;, &man.ftp.1;, &man.rlogin.1;, &man.rsh.1;,
- &man.ssh.1, etc. These applications are protocol independent.
- That is, they automatically chooses IPv4 or IPv6 according to DNS.
-
-
-
-
- Kernel Internals
-
- While ip_forward() calls ip_output(), ip6_forward() directly
- calls if_output() since routers must not divide IPv6 packets into
- fragments.
-
- ICMPv6 should contain the original packet as long as possible
- up to 1280. UDP6/IP6 port unreach, for instance, should contain
- all extension headers and the *unchanged* UDP6 and IP6 headers.
- So, all IP6 functions except TCP never convert network byte
- order into host byte order, to save the original packet.
-
- tcp_input(), udp6_input() and icmp6_input() can't assume that
- IP6 header is preceding the transport headers due to extension
- headers. So, in6_cksum() was implemented to handle packets whose IP6
- header and transport header is not continuous. TCP/IP6 nor UDP6/IP6
- header structure don't exist for checksum calculation.
-
- To process IP6 header, extension headers and transport headers
- easily, network drivers are now required to store packets in one
- internal mbuf or one or more external mbufs. A typical old driver
- prepares two internal mbufs for 96 - 204 bytes data, however, now
- such packet data is stored in one external mbuf.
-
- netstat -s -p ip6 tells you whether or not
- your driver conforms such requirement. In the following example,
- "cce0" violates the requirement. (For more information, refer to
- Section 2.)
-
-
- Mbuf statistics:
- 317 one mbuf
- two or more mbuf::
- lo0 = 8
- cce0 = 10
- 3282 one ext mbuf
- 0 two or more ext mbuf
-
-
- Each input function calls IP6_EXTHDR_CHECK in the beginning to
- check if the region between IP6 and its header is continuous.
- IP6_EXTHDR_CHECK calls m_pullup() only if the mbuf has M_LOOP flag,
- that is, the packet comes from the loopback interface. m_pullup()
- is never called for packets coming from physical network interfaces.
-
-
- Both IP and IP6 reassemble functions never call m_pullup().
-
-
-
- IPv4 mapped address and IPv6 wildcard socket
-
- RFC2553 describes IPv4 mapped address (3.7) and special behavior
- of IPv6 wildcard bind socket (3.8). The spec allows you to:
-
-
- Accept IPv4 connections by AF_INET6 wildcard bind
- socket.
-
-
- Transmit IPv4 packet over AF_INET6 socket by using
- special form of the address like ::ffff:10.1.1.1.
-
-
-
- but the spec itself is very complicated and does not specify
- how the socket layer should behave. Here we call the former one
- "listening side" and the latter one "initiating side", for
- reference purposes.
-
- You can perform wildcard bind on both of the address families,
- on the same port.
-
- The following table show the behavior of FreeBSD 4.x.
-
-
- listening side initiating side
- (AF_INET6 wildcard (connection to ::ffff:10.1.1.1)
- socket gets IPv4 conn.)
- --- ---
-FreeBSD 4.x configurable supported
- default: enabled
-
-
- The following sections will give you more details, and how you can
- configure the behavior.
-
- Comments on listening side:
-
- It looks that RFC2553 talks too little on wildcard bind issue,
- especially on the port space issue, failure mode and relationship
- between AF_INET/INET6 wildcard bind. There can be several separate
- interpretation for this RFC which conform to it but behaves differently.
- So, to implement portable application you should assume nothing
- about the behavior in the kernel. Using &man.getaddrinfo.3; is the
- safest way. Port number space and wildcard bind issues were discussed
- in detail on ipv6imp mailing list, in mid March 1999 and it looks
- that there's no concrete consensus (means, up to implementers).
- You may want to check the mailing list archives.
-
- If a server application would like to accept IPv4 and IPv6
- connections, there will be two alternatives.
-
- One is using AF_INET and AF_INET6 socket (you'll need two
- sockets). Use &man.getaddrinfo.3; with AI_PASSIVE into ai_flags,
- and &man.socket.2; and &man.bind.2; to all the addresses returned.
- By opening multiple sockets, you can accept connections onto the
- socket with proper address family. IPv4 connections will be
- accepted by AF_INET socket, and IPv6 connections will be accepted
- by AF_INET6 socket.
-
- Another way is using one AF_INET6 wildcard bind socket. Use
- &man.getaddrinfo.3; with AI_PASSIVE into ai_flags and with
- AF_INET6 into ai_family, and set the 1st argument hostname to
- NULL. And &man.socket.2; and &man.bind.2; to the address returned.
- (should be IPv6 unspecified addr). You can accept either of IPv4
- and IPv6 packet via this one socket.
-
- To support only IPv6 traffic on AF_INET6 wildcard binded socket
- portably, always check the peer address when a connection is made
- toward AF_INET6 listening socket. If the address is IPv4 mapped
- address, you may want to reject the connection. You can check the
- condition by using IN6_IS_ADDR_V4MAPPED() macro.
-
- To resolve this issue more easily, there is system dependent
- &man.setsockopt.2; option, IPV6_BINDV6ONLY, used like below.
-
-
- int on;
-
- setsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY,
- (char *)&on, sizeof (on)) < 0));
-
-
- When this call succeed, then this socket only receive IPv6
- packets.
-
- Comments on initiating side:
-
- Advise to application implementers: to implement a portable
- IPv6 application (which works on multiple IPv6 kernels), we believe
- that the following is the key to the success:
-
-
-
- NEVER hardcode AF_INET nor AF_INET6.
-
-
-
- Use &man.getaddrinfo.3; and &man.getnameinfo.3;
- throughout the system. Never use gethostby*(), getaddrby*(),
- inet_*() or getipnodeby*(). (To update existing applications
- to be IPv6 aware easily, sometime getipnodeby*() will be
- useful. But if possible, try to rewrite the code to use
- &man.getaddrinfo.3; and &man.getnameinfo.3;.)
-
-
-
- If you would like to connect to destination, use
- &man.getaddrinfo.3; and try all the destination returned,
- like &man.telnet.1; does.
-
-
-
- Some of the IPv6 stack is shipped with buggy
- &man.getaddrinfo.3;. Ship a minimal working version with
- your application and use that as last resort.
-
-
-
- If you would like to use AF_INET6 socket for both IPv4 and
- IPv6 outgoing connection, you will need to use &man.getipnodebyname.3;.
- When you would like to update your existing application to be IPv6
- aware with minimal effort, this approach might be chosen. But please
- note that it is a temporal solution, because &man.getipnodebyname.3;
- itself is not recommended as it does not handle scoped IPv6 addresses
- at all. For IPv6 name resolution, &man.getaddrinfo.3; is the
- preferred API. So you should rewrite your application to use
- &man.getaddrinfo.3;, when you get the time to do it.
-
- When writing applications that make outgoing connections,
- story goes much simpler if you treat AF_INET and AF_INET6 as totally
- separate address family. {set,get}sockopt issue goes simpler,
- DNS issue will be made simpler. We do not recommend you to rely
- upon IPv4 mapped address.
-
-
- unified tcp and inpcb code
-
- FreeBSD 4.x uses shared tcp code between IPv4 and IPv6
- (from sys/netinet/tcp*) and separate udp4/6 code. It uses
- unified inpcb structure.
-
- The platform can be configured to support IPv4 mapped address.
- Kernel configuration is summarized as follows:
-
-
-
- By default, AF_INET6 socket will grab IPv4
- connections in certain condition, and can initiate
- connection to IPv4 destination embedded in IPv4 mapped
- IPv6 address.
-
-
-
- You can disable it on entire system with sysctl like
- below.
-
-
- sysctl -w net.inet6.ip6.mapped_addr=0
-
-
-
-
-
-
- listening side
-
- Each socket can be configured to support special AF_INET6
- wildcard bind (enabled by default). You can disable it on
- each socket basis with &man.setsockopt.2; like below.
-
-
- int on;
-
- setsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY,
- (char *)&on, sizeof (on)) < 0));
-
-
- Wildcard AF_INET6 socket grabs IPv4 connection if and only
- if the following conditions are satisfied:
-
-
-
- there's no AF_INET socket that matches the IPv4
- connection
-
-
-
- the AF_INET6 socket is configured to accept IPv4
- traffic, i.e. getsockopt(IPV6_BINDV6ONLY) returns 0.
-
-
-
- There's no problem with open/close ordering.
-
-
-
- initiating side
-
- FreeBSD 4.x supports outgoing connection to IPv4 mapped
- address (::ffff:10.1.1.1), if the node is configured to support
- IPv4 mapped address.
-
-
-
-
-
- sockaddr_storage
-
- When RFC2553 was about to be finalized, there was discussion on
- how struct sockaddr_storage members are named. One proposal is to
- prepend "__" to the members (like "__ss_len") as they should not be
- touched. The other proposal was that don't prepend it (like "ss_len")
- as we need to touch those members directly. There was no clear
- consensus on it.
-
- As a result, RFC2553 defines struct sockaddr_storage as
- follows:
-
-
- struct sockaddr_storage {
- u_char __ss_len; /* address length */
- u_char __ss_family; /* address family */
- /* and bunch of padding */
- };
-
-
- On the contrary, XNET draft defines as follows:
-
-
- struct sockaddr_storage {
- u_char ss_len; /* address length */
- u_char ss_family; /* address family */
- /* and bunch of padding */
- };
-
-
- In December 1999, it was agreed that RFC2553bis should pick
- the latter (XNET) definition.
-
- Current implementation conforms to XNET definition, based on
- RFC2553bis discussion.
-
- If you look at multiple IPv6 implementations, you will be able
- to see both definitions. As an userland programmer, the most
- portable way of dealing with it is to:
-
-
-
- ensure ss_family and/or ss_len are available on the
- platform, by using GNU autoconf,
-
-
-
- have -Dss_family=__ss_family to unify all occurrences
- (including header file) into __ss_family, or
-
-
-
- never touch __ss_family. cast to sockaddr * and use sa_family
- like:
-
-
- struct sockaddr_storage ss;
- family = ((struct sockaddr *)&ss)->sa_family
-
-
-
-
-
-
-
-
- Network Drivers
-
- Now following two items are required to be supported by standard
- drivers:
-
-
-
- mbuf clustering requirement. In this stable release, we
- changed MINCLSIZE into MHLEN+1 for all the operating systems
- in order to make all the drivers behave as we expect.
-
-
-
- multicast. If &man.ifmcstat.8; yields no multicast group for
- a interface, that interface has to be patched.
-
-
-
- If any of the driver don't support the requirements, then
- the driver can't be used for IPv6 and/or IPsec communication. If
- you find any problem with your card using IPv6/IPsec, then, please
- report it to freebsd-bugs@FreeBSD.org.
-
- (NOTE: In the past we required all PCMCIA drivers to have a
- call to in6_ifattach(). We have no such requirement any more)
-
-
-
- Translator
-
- We categorize IPv4/IPv6 translator into 4 types:
-
-
-
- Translator A --- It is used in the early
- stage of transition to make it possible to establish a
- connection from an IPv6 host in an IPv6 island to an IPv4 host
- in the IPv4 ocean.
-
-
-
- Translator B --- It is used in the early
- stage of transition to make it possible to establish a connection
- from an IPv4 host in the IPv4 ocean to an IPv6 host in an
- IPv6 island.
-
-
-
- Translator C --- It is used in the late
- stage of transition to make it possible to establish a
- connection from an IPv4 host in an IPv4 island to an IPv6 host
- in the IPv6 ocean.
-
-
-
- Translator D --- It is used in the late
- stage of transition to make it possible to establish a
- connection from an IPv6 host in the IPv6 ocean to an IPv4 host
- in an IPv4 island.
-
-
-
- TCP relay translator for category A is supported. This is called
- "FAITH". We also provide IP header translator for category A.
- (The latter is not yet put into FreeBSD 4.x yet.)
-
-
- FAITH TCP relay translator
-
- FAITH system uses TCP relay daemon called &man.faithd.8; helped
- by the kernel. FAITH will reserve an IPv6 address prefix, and relay
- TCP connection toward that prefix to IPv4 destination.
-
- For example, if the reserved IPv6 prefix is
- 3ffe:0501:0200:ffff::, and the IPv6 destination for TCP connection
- is 3ffe:0501:0200:ffff::163.221.202.12, the connection will be
- relayed toward IPv4 destination 163.221.202.12.
-
-
- destination IPv4 node (163.221.202.12)
- ^
- | IPv4 tcp toward 163.221.202.12
- FAITH-relay dual stack node
- ^
- | IPv6 TCP toward 3ffe:0501:0200:ffff::163.221.202.12
- source IPv6 node
-
-
- &man.faithd.8; must be invoked on FAITH-relay dual stack
- node.
-
- For more details, consult
- src/usr.sbin/faithd/README
-
-
-
-
- IPsec
-
- IPsec is mainly organized by three components.
-
-
-
- Policy Management
-
-
-
- Key Management
-
-
-
- AH and ESP handling
-
-
-
-
- Policy Management
-
- The kernel implements experimental policy management code.
- There are two way to manage security policy. One is to configure
- per-socket policy using &man.setsockopt.2;. In this cases, policy
- configuration is described in &man.ipsec.set.policy.3;. The other
- is to configure kernel packet filter-based policy using PF_KEY
- interface, via &man.setkey.8;.
-
- The policy entry is not re-ordered with its
- indexes, so the order of entry when you add is very significant.
-
-
-
- Key Management
-
- The key management code implemented in this kit (sys/netkey)
- is a home-brew PFKEY v2 implementation. This conforms to RFC2367.
-
-
- The home-brew IKE daemon, "racoon" is included in the
- kit (kame/kame/racoon). Basically you'll need to run racoon as
- daemon, then setup a policy to require keys (like
- ping -P 'out ipsec esp/transport//use').
- The kernel will contact racoon daemon as necessary to exchange
- keys.
-
-
-
- AH and ESP handling
-
- IPsec module is implemented as "hooks" to the standard IPv4/IPv6
- processing. When sending a packet, ip{,6}_output() checks if ESP/AH
- processing is required by checking if a matching SPD (Security
- Policy Database) is found. If ESP/AH is needed,
- {esp,ah}{4,6}_output() will be called and mbuf will be updated
- accordingly. When a packet is received, {esp,ah}4_input() will be
- called based on protocol number, i.e. (*inetsw[proto])().
- {esp,ah}4_input() will decrypt/check authenticity of the packet,
- and strips off daisy-chained header and padding for ESP/AH. It is
- safe to strip off the ESP/AH header on packet reception, since we
- will never use the received packet in "as is" form.
-
- By using ESP/AH, TCP4/6 effective data segment size will be
- affected by extra daisy-chained headers inserted by ESP/AH. Our
- code takes care of the case.
-
- Basic crypto functions can be found in directory "sys/crypto".
- ESP/AH transform are listed in {esp,ah}_core.c with wrapper functions.
- If you wish to add some algorithm, add wrapper function in
- {esp,ah}_core.c, and add your crypto algorithm code into
- sys/crypto.
-
- Tunnel mode is partially supported in this release, with the
- following restrictions:
-
-
-
- IPsec tunnel is not combined with GIF generic tunneling
- interface. It needs a great care because we may create an
- infinite loop between ip_output() and tunnelifp->if_output().
- Opinion varies if it is better to unify them, or not.
-
-
-
- MTU and Don't Fragment bit (IPv4) considerations need more
- checking, but basically works fine.
-
-
-
- Authentication model for AH tunnel must be revisited.
- We'll need to improve the policy management engine,
- eventually.
-
-
-
-
-
- Conformance to RFCs and IDs
-
- The IPsec code in the kernel conforms (or, tries to conform)
- to the following standards:
-
- "old IPsec" specification documented in
- rfc182[5-9].txt
-
- "new IPsec" specification documented in
- rfc240[1-6].txt,
- rfc241[01].txt, rfc2451.txt
- and draft-mcdonald-simple-ipsec-api-01.txt
- (draft expired, but you can take from
- ftp://ftp.kame.net/pub/internet-drafts/).
- (NOTE: IKE specifications, rfc241[7-9].txt are
- implemented in userland, as "racoon" IKE daemon)
-
- Currently supported algorithms are:
-
-
- old IPsec AH
-
-
- null crypto checksum (no document, just for
- debugging)
-
-
- keyed MD5 with 128bit crypto checksum
- (rfc1828.txt)
-
-
- keyed SHA1 with 128bit crypto checksum
- (no document)
-
-
- HMAC MD5 with 128bit crypto checksum
- (rfc2085.txt)
-
-
- HMAC SHA1 with 128bit crypto checksum
- (no document)
-
-
-
-
-
- old IPsec ESP
-
-
- null encryption (no document, similar to
- rfc2410.txt)
-
-
- DES-CBC mode (rfc1829.txt)
-
-
-
-
-
- new IPsec AH
-
-
- null crypto checksum (no document,
- just for debugging)
-
-
- keyed MD5 with 96bit crypto checksum
- (no document)
-
-
- keyed SHA1 with 96bit crypto checksum
- (no document)
-
-
- HMAC MD5 with 96bit crypto checksum
- (rfc2403.txt)
-
-
- HMAC SHA1 with 96bit crypto checksum
- (rfc2404.txt)
-
-
-
-
-
- new IPsec ESP
-
-
- null encryption
- (rfc2410.txt)
-
-
- DES-CBC with derived IV
- (draft-ietf-ipsec-ciph-des-derived-01.txt,
- draft expired)
-
-
- DES-CBC with explicit IV
- (rfc2405.txt)
-
-
- 3DES-CBC with explicit IV
- (rfc2451.txt)
-
-
- BLOWFISH CBC
- (rfc2451.txt)
-
-
- CAST128 CBC
- (rfc2451.txt)
-
-
- RC5 CBC
- (rfc2451.txt)
-
-
- each of the above can be combined with:
-
-
- ESP authentication with HMAC-MD5(96bit)
-
-
- ESP authentication with HMAC-SHA1(96bit)
-
-
-
-
-
-
-
- The following algorithms are NOT supported:
-
-
-
- old IPsec AH
-
-
-
- HMAC MD5 with 128bit crypto checksum + 64bit
- replay prevention (rfc2085.txt)
-
-
- keyed SHA1 with 160bit crypto checksum + 32bit padding
- (rfc1852.txt)
-
-
-
-
-
-
- IPsec (in kernel) and IKE (in userland as "racoon") has been
- tested at several interoperability test events, and it is known to
- interoperate with many other implementations well. Also, current
- IPsec implementation as quite wide coverage for IPsec crypto
- algorithms documented in RFC (we cover algorithms without intellectual
- property issues only).
-
-
-
- ECN consideration on IPsec tunnels
-
- ECN-friendly IPsec tunnel is supported as described in
- draft-ipsec-ecn-00.txt.
-
- Normal IPsec tunnel is described in RFC2401. On encapsulation,
- IPv4 TOS field (or, IPv6 traffic class field) will be copied from inner
- IP header to outer IP header. On decapsulation outer IP header
- will be simply dropped. The decapsulation rule is not compatible
- with ECN, since ECN bit on the outer IP TOS/traffic class field will be
- lost.
-
- To make IPsec tunnel ECN-friendly, we should modify encapsulation
- and decapsulation procedure. This is described in
- http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt,
- chapter 3.
-
- IPsec tunnel implementation can give you three behaviors, by
- setting net.inet.ipsec.ecn (or net.inet6.ipsec6.ecn) to some
- value:
-
-
-
- RFC2401: no consideration for ECN (sysctl value -1)
-
-
- ECN forbidden (sysctl value 0)
-
-
- ECN allowed (sysctl value 1)
-
-
-
- Note that the behavior is configurable in per-node manner,
- not per-SA manner (draft-ipsec-ecn-00 wants per-SA configuration,
- but it looks too much for me).
-
- The behavior is summarized as follows (see source code for
- more detail):
-
-
-
- encapsulate decapsulate
- --- ---
-RFC2401 copy all TOS bits drop TOS bits on outer
- from inner to outer. (use inner TOS bits as is)
-
-ECN forbidden copy TOS bits except for ECN drop TOS bits on outer
- (masked with 0xfc) from inner (use inner TOS bits as is)
- to outer. set ECN bits to 0.
-
-ECN allowed copy TOS bits except for ECN use inner TOS bits with some
- CE (masked with 0xfe) from change. if outer ECN CE bit
- inner to outer. is 1, enable ECN CE bit on
- set ECN CE bit to 0. the inner.
-
-
-
- General strategy for configuration is as follows:
-
-
- if both IPsec tunnel endpoint are capable of ECN-friendly
- behavior, you'd better configure both end to "ECN allowed"
- (sysctl value 1).
-
-
- if the other end is very strict about TOS bit, use "RFC2401"
- (sysctl value -1).
-
-
- in other cases, use "ECN forbidden" (sysctl value 0).
-
-
-
- The default behavior is "ECN forbidden" (sysctl value 0).
-
- For more information, please refer to:
-
-
- http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt,
- RFC2481 (Explicit Congestion Notification),
- src/sys/netinet6/{ah,esp}_input.c
-
- (Thanks goes to Kenjiro Cho kjc@csl.sony.co.jp
- for detailed analysis)
-
-
-
- Interoperability
-
- Here are (some of) platforms that KAME code have tested
- IPsec/IKE interoperability in the past. Note that both ends may
- have modified their implementation, so use the following list just
- for reference purposes.
-
- Altiga, Ashley-laurent (vpcom.com), Data Fellows (F-Secure),
- Ericsson ACC, FreeS/WAN, HITACHI, IBM AIX, IIJ, Intel,
- Microsoft WinNT, NIST (linux IPsec + plutoplus), Netscreen, OpenBSD,
- RedCreek, Routerware, SSH, Secure Computing, Soliton, Toshiba,
- VPNet, Yamaha RT100i
-
-
-
-
-
-
-
diff --git a/en_US.ISO_8859-1/books/handbook/security/chapter.sgml b/en_US.ISO_8859-1/books/handbook/security/chapter.sgml
index 67fb4a8239..cdbd04568c 100644
--- a/en_US.ISO_8859-1/books/handbook/security/chapter.sgml
+++ b/en_US.ISO_8859-1/books/handbook/security/chapter.sgml
@@ -1,2848 +1,2850 @@
Security
Much of this chapter has been taken from the
&man.security.7; man page, originally written by
&a.dillon;.
Synopsis
The following chapter will provide a basic introduction to
system security concepts, some general good rules of thumb, and some
advanced topics such as S/Key, OpenSSL, Kerberos, and others.
Introduction
Security is a function that begins and ends with the system
administrator. While all BSD UNIX multi-user systems have some
inherent security, the job of building and maintaining additional
security mechanisms to keep those users honest
is
probably one of the single largest undertakings of the sysadmin.
Machines are only as secure as you make them, and security concerns
are ever competing with the human necessity for convenience. UNIX
systems, in general, are capable of running a huge number of
simultaneous processes and many of these processes operate as
servers – meaning that external entities can connect and talk
to them. As yesterday's mini-computers and mainframes become
today's desktops, and as computers become networked and
internetworked, security becomes an ever bigger issue.
Security is best implemented through a layered
onion
approach. In a nutshell, what you want to do is
to create as many layers of security as are convenient and then
carefully monitor the system for intrusions. You do not want to
overbuild your security or you will interfere with the detection
side, and detection is one of the single most important aspects of
any security mechanism. For example, it makes little sense to set
the schg flags (see &man.chflags.1;) on every system binary because
while this may temporarily protect the binaries, it prevents an
attacker who has broken in from making an easily detectable change
that may result in your security mechanisms not detecting the attacker
at all.
System security also pertains to dealing with various forms of
attack, including attacks that attempt to crash or otherwise make a
system unusable but do not attempt to break root. Security concerns
can be split up into several categories:
Denial of service attacks.
User account compromises.
Root compromise through accessible servers.
Root compromise via user accounts.
Backdoor creation.
A denial of service attack is an action that deprives the
machine of needed resources. Typically, D.O.S. attacks are
brute-force mechanisms that attempt to crash or otherwise make a
machine unusable by overwhelming its servers or network stack. Some
D.O.S. attacks try to take advantages of bugs in the networking
stack to crash a machine with a single packet. The latter can only
be fixed by applying a bug fix to the kernel. Attacks on servers
can often be fixed by properly specifying options to limit the load
the servers incur on the system under adverse conditions.
Brute-force network attacks are harder to deal with. A
spoofed-packet attack, for example, is nearly impossible to stop
short of cutting your system off from the internet. It may not be
able to take your machine down, but it can fill up internet
pipe.
A user account compromise is even more common then a D.O.S.
attack. Many sysadmins still run standard telnetd, rlogind, rshd,
and ftpd servers on their machines. These servers, by default, do
not operate over encrypted connections. The result is that if you
have any moderate-sized user base, one or more of your users logging
into your system from a remote location (which is the most common
and convenient way to login to a system) will have his or her
password sniffed. The attentive system admin will analyze his
remote access logs looking for suspicious source addresses even for
successful logins.
One must always assume that once an attacker has access to a
user account, the attacker can break root. However, the reality is
that in a well secured and maintained system, access to a user
account does not necessarily give the attacker access to root. The
distinction is important because without access to root the attacker
cannot generally hide his tracks and may, at best, be able to do
nothing more then mess with the user's files or crash the machine.
User account compromises are very common because users tend not to
take the precautions that sysadmins take.
System administrators must keep in mind that there are
potentially many ways to break root on a machine. The attacker
may know the root password, the attacker may find a bug in a
root-run server and be able to break root over a network
connection to that server, or the attacker may know of a bug in
an suid-root program that allows the attacker to break root once
he has broken into a user's account. If an attacker has found a
a way to break root on a machine, the attacker may not have a need
to install a backdoor. Many of the root holes
found and closed to date involve a considerable amount of work
by the attacker to cleanup after himself, so most attackers install
backdoors. Backdoors provide the attacker with a way to easily
regain root access to the system, but it also gives the smart
system administrator a convenient way to detect the intrusion.
Making it impossible for an attacker to install a backdoor may
actually be detrimental to your security because it will not
close off the hole the attacker found to break in the first
place.
Security remedies should always be implemented with a
multi-layered onion peel
approach and can be
categorized as follows:
Securing root and staff accounts.
Securing root – root-run servers and suid/sgid
binaries.
Securing user accounts.
Securing the password file.
Securing the kernel core, raw devices, and
filesystems.
Quick detection of inappropriate changes made to the
system.
Paranoia.
The next section of this chapter will cover the above bullet
items in greater depth.
Securing FreeBSD
The sections that follow will cover the methods of securing your
FreeBSD system that were mentioned in the last section of this chapter.
Securing the root account and staff accounts
First off, do not bother securing staff accounts if you have
not secured the root account. Most systems have a password
assigned to the root account. The first thing you do is assume
that the password is always compromised.
This does not mean that you should remove the password. The
password is almost always necessary for console access to the
machine. What it does mean is that you should not make it
possible to use the password outside of the console or possibly
even with the &man.su.1; command. For example, make sure that
your pty's are specified as being unsecure in the
/etc/ttys file so that direct root logins
via telnet or rlogin are
disallowed. If using other login services such as
sshd, make sure that direct root logins
are disabled there as well. Consider every access method –
services such as FTP often fall through the cracks. Direct root
logins should only be allowed via the system console.
Of course, as a sysadmin you have to be able to get to root,
so we open up a few holes. But we make sure these holes require
additional password verification to operate. One way to make root
accessible is to add appropriate staff accounts to the
wheel group (in
/etc/group). The staff members placed in the
wheel group are allowed to
su to root. You should never give staff
members native wheel access by putting them in the
wheel group in their password entry. Staff
accounts should be placed in a staff group, and
then added to the wheel group via the
/etc/group file. Only those staff members
who actually need to have root access should be placed in the
wheel group. It is also possible, when using
an authentication method such as kerberos, to use kerberos'
.k5login file in the root account to allow a
&man.ksu.1; to root without having to place anyone at all in the
wheel group. This may be the better solution
since the wheel mechanism still allows an
intruder to break root if the intruder has gotten hold of your
password file and can break into a staff account. While having
the wheel mechanism is better then having
nothing at all, it is not necessarily the safest option.
An indirect way to secure the root account is to secure your
staff accounts by using an alternative login access method and
*'ing out the crypted password for the staff
accounts. This way an intruder may be able to steal the password
file but will not be able to break into any staff accounts (or,
indirectly, root, even if root has a crypted password associated
with it). Staff members get into their staff accounts through a
secure login mechanism such as &man.kerberos.1; or &man.ssh.1;
using a private/public key pair. When you use something like
kerberos, you generally must secure the machines which run the
kerberos servers and your desktop workstation. When you use a
public/private key pair with ssh, you
must generally secure the machine you are logging in
from (typically your workstation), but you
can also add an additional layer of protection to the key pair by
password protecting the keypair when you create it with
&man.ssh-keygen.1;. Being able to * out the
passwords for staff accounts also guarantees that staff members can
only login through secure access methods that you have setup. You
can thus force all staff members to use secure, encrypted
connections for all of their sessions which closes an important
hole used by many intruders: That of sniffing the network from an
unrelated, less secure machine.
The more indirect security mechanisms also assume that you are
logging in from a more restrictive server to a less restrictive
server. For example, if your main box is running all sorts of
servers, your workstation should not be running any. In order for
your workstation to be reasonably secure you should run as few
servers as possible, up to and including no servers at all, and
you should run a password-protected screen blanker. Of course,
given physical access to a workstation an attacker can break any
sort of security you put on it. This is definitely a problem that
you should consider but you should also consider the fact that the
vast majority of break-ins occur remotely, over a network, from
people who do not have physical access to your workstation or
servers.
Using something like kerberos also gives you the ability to
disable or change the password for a staff account in one place
and have it immediately effect all the machine the staff member
may have an account on. If a staff member's account gets
compromised, the ability to instantly change his password on all
machines should not be underrated. With discrete passwords,
changing a password on N machines can be a mess. You can also
impose re-passwording restrictions with kerberos: not only can a
kerberos ticket be made to timeout after a while, but the kerberos
system can require that the user choose a new password after a
certain period of time (say, once a month).
Securing Root-run Servers and SUID/SGID Binaries
The prudent sysadmin only runs the servers he needs to, no
more, no less. Be aware that third party servers are often the
most bug-prone. For example, running an old version of imapd or
popper is like giving a universal root ticket out to the entire
world. Never run a server that you have not checked out
carefully. Many servers do not need to be run as root. For
example, the ntalk,
comsat, and
finger daemons can be run in special
user sandboxes. A sandbox isn't perfect unless
you go to a large amount of trouble, but the onion approach to
security still stands: If someone is able to break in through
a server running in a sandbox, they still have to break out of the
sandbox. The more layers the attacker must break through, the
lower the likelihood of his success. Root holes have historically
been found in virtually every server ever run as root, including
basic system servers. If you are running a machine through which
people only login via sshd and never
login via telnetd or
rshd or
rlogind, then turn off those
services!
FreeBSD now defaults to running
ntalkd,
comsat, and
finger in a sandbox. Another program
which may be a candidate for running in a sandbox is &man.named.8;.
/etc/defaults/rc.conf includes the arguments
necessary to run named in a sandbox in a
commented-out form. Depending on whether you are installing a new
system or upgrading an existing system, the special user accounts
used by these sandboxes may not be installed. The prudent
sysadmin would research and implement sandboxes for servers
whenever possible.
There are a number of other servers that typically do not run
in sandboxes: sendmail,
popper,
imapd, ftpd,
and others. There are alternatives to some of these, but
installing them may require more work then you are willing to
perform (the convenience factor strikes again). You may have to
run these servers as root and rely on other mechanisms to detect
break-ins that might occur through them.
The other big potential root hole in a system are the
suid-root and sgid binaries installed on the system. Most of
these binaries, such as rlogin, reside
in /bin, /sbin,
/usr/bin, or /usr/sbin.
While nothing is 100% safe, the system-default suid and sgid
binaries can be considered reasonably safe. Still, root holes are
occasionally found in these binaries. A root hole was found in
Xlib in 1998 that made
xterm (which is typically suid)
vulnerable. It is better to be safe then sorry and the prudent
sysadmin will restrict suid binaries that only staff should run to
a special group that only staff can access, and get rid of
(chmod 000) any suid binaries that nobody uses.
A server with no display generally does not need an
xterm binary. Sgid binaries can be
almost as dangerous. If an intruder can break an sgid-kmem binary
the intruder might be able to read /dev/kmem
and thus read the crypted password file, potentially compromising
any passworded account. Alternatively an intruder who breaks
group kmem can monitor keystrokes sent through
pty's, including pty's used by users who login through secure
methods. An intruder that breaks the tty group can write to
almost any user's tty. If a user is running a terminal program or
emulator with a keyboard-simulation feature, the intruder can
potentially generate a data stream that causes the user's terminal
to echo a command, which is then run as that user.
Securing User Accounts
User accounts are usually the most difficult to secure. While
you can impose Draconian access restrictions on your staff and
* out their passwords, you may not be able to
do so with any general user accounts you might have. If you do
have sufficient control then you may win out and be able to secure
the user accounts properly. If not, you simply have to be more
vigilant in your monitoring of those accounts. Use of
ssh and kerberos for user accounts is
more problematic due to the extra administration and technical
support required, but still a very good solution compared to a
crypted password file.
Securing the Password File
The only sure fire way is to * out as many
passwords as you can and use ssh or
kerberos for access to those accounts. Even though the crypted
password file (/etc/spwd.db) can only be read
by root, it may be possible for an intruder to obtain read access
to that file even if the attacker cannot obtain root-write
access.
Your security scripts should always check for and report
changes to the password file (see Checking file integrity
below).
Securing the Kernel Core, Raw Devices, and
Filesystems
If an attacker breaks root he can do just about anything, but
there are certain conveniences. For example, most modern kernels
have a packet sniffing device driver built in. Under FreeBSD it
is called the bpf device. An intruder
will commonly attempt to run a packet sniffer on a compromised
machine. You do not need to give the intruder the capability and
most systems should not have the bpf device compiled in.
But even if you turn off the bpf device, you still have
/dev/mem and /dev/kmem
to worry about. For that matter, the intruder can still write to
raw disk devices. Also, there is another kernel feature called
the module loader, &man.kldload.8;. An enterprising intruder can
use a KLD module to install his own bpf device or other sniffing
device on a running kernel. To avoid these problems you have to
run the kernel at a higher secure level, at least securelevel 1.
The securelevel can be set with a sysctl on
the kern.securelevel variable. Once you have
set the securelevel to 1, write access to raw devices will be
denied and special chflags flags, such as schg,
will be enforced. You must also ensure that the
schg flag is set on critical startup binaries,
directories, and script files – everything that gets run up
to the point where the securelevel is set. This might be overdoing
it, and upgrading the system is much more difficult when you
operate at a higher secure level. You may compromise and run the
system at a higher secure level but not set the
schg flag for every system file and directory
under the sun. Another possibility is to simply mount
/ and /usr read-only.
It should be noted that being too draconian in what you attempt to
protect may prevent the all-important detection of an
intrusion.
Checking File Integrity: Binaries, Configuration Files,
Etc.
When it comes right down to it, you can only protect your core
system configuration and control files so much before the
convenience factor rears its ugly head. For example, using
chflags to set the schg bit
on most of the files in / and
/usr is probably counterproductive because
while it may protect the files, it also closes a detection window.
The last layer of your security onion is perhaps the most
important – detection. The rest of your security is pretty
much useless (or, worse, presents you with a false sense of
safety) if you cannot detect potential incursions. Half the job
of the onion is to slow down the attacker rather then stop him in
order to give the detection side of the equation a chance to catch
him in the act.
The best way to detect an incursion is to look for modified,
missing, or unexpected files. The best way to look for modified
files is from another (often centralized) limited-access system.
Writing your security scripts on the extra-secure limited-access
system makes them mostly invisible to potential attackers, and this
is important. In order to take maximum advantage you generally
have to give the limited-access box significant access to the
other machines in the business, usually either by doing a
read-only NFS export of the other machines to the limited-access
box, or by setting up ssh keypairs to
allow the limit-access box to ssh to
the other machines. Except for its network traffic, NFS is the
least visible method – allowing you to monitor the
filesystems on each client box virtually undetected. If your
limited-access server is connected to the client boxes through a
switch, the NFS method is often the better choice. If your
limited-access server is connected to the client boxes through a
hub or through several layers of routing, the NFS method may be
too insecure (network-wise) and using
ssh may be the better choice even with
the audit-trail tracks that ssh
lays.
Once you give a limit-access box at least read access to the
client systems it is supposed to monitor, you must write scripts
to do the actual monitoring. Given an NFS mount, you can write
scripts out of simple system utilities such as &man.find.1; and
&man.md5.1;. It is best to physically md5 the client-box files
boxes at least once a day, and to test control files such as those
found in /etc and
/usr/local/etc even more often. When
mismatches are found relative to the base md5 information the
limited-access machine knows is valid, it should scream at a
sysadmin to go check it out. A good security script will also
check for inappropriate suid binaries and for new or deleted files
on system partitions such as / and
/usr.
When using ssh rather then NFS,
writing the security script is much more difficult. You
essentially have to scp the scripts to the client box in order to
run them, making them visible, and for safety you also need to
scp the binaries (such as find) that those
scripts use. The ssh daemon on the
client box may already be compromised. All in all, using
ssh may be necessary when running over
unsecure links, but it's also a lot harder to deal with.
A good security script will also check for changes to user and
staff members access configuration files:
.rhosts, .shosts,
.ssh/authorized_keys and so forth…
files that might fall outside the purview of the
MD5 check.
If you have a huge amount of user disk space it may take too
long to run through every file on those partitions. In this case,
setting mount flags to disallow suid binaries and devices on those
partitions is a good idea. The nodev and
nosuid options (see &man.mount.8;) are what you
want to look into. You should probably scan them anyway at least
once a week, since the object of this layer is to detect a break-in
whether or not the break-in is effective.
Process accounting (see &man.accton.8;) is a relatively
low-overhead feature of the operating system which might help
as a post-break-in evaluation mechanism. It is especially
useful in tracking down how an intruder has actually broken into
a system, assuming the file is still intact after the break-in
occurs.
Finally, security scripts should process the log files and the
logs themselves should be generated in as secure a manner as
possible – remote syslog can be very useful. An intruder
tries to cover his tracks, and log files are critical to the
sysadmin trying to track down the time and method of the initial
break-in. One way to keep a permanent record of the log files is
to run the system console to a serial port and collect the
information on a continuing basis through a secure machine
monitoring the consoles.
Paranoia
A little paranoia never hurts. As a rule, a sysadmin can add
any number of security features as long as they do not effect
convenience, and can add security features that do effect
convenience with some added thought. Even more importantly, a
security administrator should mix it up a bit – if you use
recommendations such as those given by this document verbatim, you
give away your methodologies to the prospective attacker who also
has access to this document.
Denial of Service Attacks
This section covers Denial of Service attacks. A DOS attack
is typically a packet attack. While there is not much you can do
about modern spoofed packet attacks that saturate your network,
you can generally limit the damage by ensuring that the attacks
cannot take down your servers.
Limiting server forks.
Limiting springboard attacks (ICMP response attacks, ping
broadcast, etc.).
Kernel Route Cache.
A common DOS attack is against a forking server that attempts
to cause the server to eat processes, file descriptors, and memory
until the machine dies. Inetd (see &man.inetd.8;) has several
options to limit this sort of attack. It should be noted that
while it is possible to prevent a machine from going down it is
not generally possible to prevent a service from being disrupted
by the attack. Read the inetd manual page carefully and pay
specific attention to the , ,
and options. Note that spoofed-IP attacks
will circumvent the option to inetd, so
typically a combination of options must be used. Some standalone
servers have self-fork-limitation parameters.
Sendmail has its
option which tends to work
much better than trying to use sendmail's load limiting options
due to the load lag. You should specify a
MaxDaemonChildren parameter when you start
sendmail high enough to handle your
expected load but no so high that the computer cannot handle that
number of sendmails without falling on
its face. It is also prudent to run sendmail in queued mode
() and to run the daemon
(sendmail -bd) separate from the queue-runs
(sendmail -q15m). If you still want real-time
delivery you can run the queue at a much lower interval, such as
, but be sure to specify a reasonable
MaxDaemonChildren option for that sendmail to
prevent cascade failures.
Syslogd can be attacked directly
and it is strongly recommended that you use the
option whenever possible, and the option
otherwise.
You should also be fairly careful with connect-back services
such as tcpwrapper's reverse-identd,
which can be attacked directly. You generally do not want to use
the reverse-ident feature of
tcpwrappers for this reason.
It is a very good idea to protect internal services from
external access by firewalling them off at your border routers.
The idea here is to prevent saturation attacks from outside your
LAN, not so much to protect internal services from network-based
root compromise. Always configure an exclusive firewall, i.e.,
firewall everything except ports A, B,
C, D, and M-Z
. This way you can firewall off all of your
low ports except for certain specific services such as
named (if you are primary for a zone),
ntalkd,
sendmail, and other internet-accessible
services. If you try to configure the firewall the other way
– as an inclusive or permissive firewall, there is a good
chance that you will forget to close
a couple of
services or that you will add a new internal service and forget
to update the firewall. You can still open up the high-numbered
port range on the firewall to allow permissive-like operation
without compromising your low ports. Also take note that FreeBSD
allows you to control the range of port numbers used for dynamic
binding via the various net.inet.ip.portrange
sysctl's (sysctl -a | fgrep
portrange), which can also ease the complexity of your
firewall's configuration. For example, you might use a normal
first/last range of 4000 to 5000, and a hiport range of 49152 to
65535, then block everything under 4000 off in your firewall
(except for certain specific internet-accessible ports, of
course).
Another common DOS attack is called a springboard attack
– to attack a server in a manner that causes the server to
generate responses which then overload the server, the local
network, or some other machine. The most common attack of this
nature is the ICMP ping broadcast attack.
The attacker spoofs ping packets sent to your LAN's broadcast
address with the source IP address set to the actual machine they
wish to attack. If your border routers are not configured to
stomp on ping's to broadcast addresses, your LAN winds up
generating sufficient responses to the spoofed source address to
saturate the victim, especially when the attacker uses the same
trick on several dozen broadcast addresses over several dozen
different networks at once. Broadcast attacks of over a hundred
and twenty megabits have been measured. A second common
springboard attack is against the ICMP error reporting system.
By constructing packets that generate ICMP error responses, an
attacker can saturate a server's incoming network and cause the
server to saturate its outgoing network with ICMP responses. This
type of attack can also crash the server by running it out of
mbuf's, especially if the server cannot drain the ICMP responses
it generates fast enough. The FreeBSD kernel has a new kernel
compile option called ICMP_BANDLIM which limits the effectiveness
of these sorts of attacks. The last major class of springboard
attacks is related to certain internal inetd services such as the
udp echo service. An attacker simply spoofs a UDP packet with the
source address being server A's echo port, and the destination
address being server B's echo port, where server A and B are both
on your LAN. The two servers then bounce this one packet back and
forth between each other. The attacker can overload both servers
and their LANs simply by injecting a few packets in this manner.
Similar problems exist with the internal chargen port. A
competent sysadmin will turn off all of these inetd-internal test
services.
Spoofed packet attacks may also be used to overload the kernel
route cache. Refer to the net.inet.ip.rtexpire,
rtminexpire, and rtmaxcache
sysctl parameters. A spoofed packet attack
that uses a random source IP will cause the kernel to generate a
temporary cached route in the route table, viewable with
netstat -rna | fgrep W3. These routes
typically timeout in 1600 seconds or so. If the kernel detects
that the cached route table has gotten too big it will dynamically
reduce the rtexpire but will never decrease it to less then
rtminexpire. There are two problems:
The kernel does not react quickly enough when a lightly
loaded server is suddenly attacked.
The rtminexpire is not low enough for
the kernel to survive a sustained attack.
If your servers are connected to the internet via a T3 or
better it may be prudent to manually override both
rtexpire and rtminexpire
via &man.sysctl.8;. Never set either parameter to zero (unless
you want to crash the machine :-). Setting both
parameters to 2 seconds should be sufficient to protect the route
table from attack.
Access Issues with Kerberos and SSH
There are a few issues with both kerberos and
ssh that need to be addressed if
you intend to use them. Kerberos V is an excellent
authentication protocol but there are bugs in the kerberized
telnet and
rlogin applications that make them
unsuitable for dealing with binary streams. Also, by default
kerberos does not encrypt a session unless you use the
option. ssh
encrypts everything by default.
ssh works quite well in every
respect except that it forwards encryption keys by default. What
this means is that if you have a secure workstation holding keys
that give you access to the rest of the system, and you
ssh to an unsecure machine, your keys
becomes exposed. The actual keys themselves are not exposed, but
ssh installs a forwarding port for the
duration of your login and if a attacker has broken root on the
unsecure machine he can utilize that port to use your keys to gain
access to any other machine that your keys unlock.
We recommend that you use ssh in
combination with kerberos whenever possible for staff logins.
ssh can be compiled with kerberos
support. This reduces your reliance on potentially exposable
ssh keys while at the same time
protecting passwords via kerberos. ssh
keys should only be used for automated tasks from secure machines
(something that kerberos is unsuited to). We also recommend that
you either turn off key-forwarding in the
ssh configuration, or that you make use
of the from=IP/DOMAIN option that
ssh allows in its
authorized_keys file to make the key only
usable to entities logging in from specific machines.
DES, MD5, and Crypt
Parts rewritten and updated by &a.unfurl;, 21 March
2000.
Every user on a UNIX system has a password associated with
their account. It seems obvious that these passwords need to be
known only to the user and the actual operating system. In
order to keep these passwords secret, they are encrypted with
what is known as a one-way hash
, that is, they can
only be easily encrypted but not decrypted. In other words, what
we told you a moment ago was obvious is not even true: the
operating system itself does not really know
the password. It only knows the encrypted
form of the password. The only way to get the
plain-text
password is by a brute force search of the
space of possible passwords.
Unfortunately the only secure way to encrypt passwords when
UNIX came into being was based on DES, the Data Encryption
Standard. This is not such a problem for users that live in
the US, but since the source code for DES could not be exported
outside the US, FreeBSD had to find a way to both comply with
US law and retain compatibility with all the other UNIX
variants that still use DES.
The solution was to divide up the encryption libraries
so that US users could install the DES libraries and use
DES but international users still had an encryption method
that could be exported abroad. This is how FreeBSD came to
use MD5 as its default encryption method. MD5 is believed to
be more secure than DES, so installing DES is offered primarily
for compatibility reasons.
Recognizing your crypt mechanism
It is pretty easy to identify which encryption method
FreeBSD is set up to use. Examining the encrypted passwords in
the /etc/master.passwd file is one way.
Passwords encrypted with the MD5 hash are longer than those with
encrypted with the DES hash and also begin with the characters
$1$. DES password strings do not
have any particular identifying characteristics, but they are
shorter than MD5 passwords, and are coded in a 64-character
alphabet which does not include the $
character, so a relatively short string which does not begin with
a dollar sign is very likely a DES password.
The libraries can identify the passwords this way as well.
As a result, the DES libraries are able to identify MD5
passwords, and use MD5 to check passwords that were encrypted
that way, and DES for the rest. They are able to do this
because the DES libraries also contain MD5. Unfortunately, the
reverse is not true, so the MD5 libraries cannot authenticate
passwords that were encrypted with DES.
Identifying which library is being used by the programs on
your system is easy as well. Any program that uses crypt is linked
against libcrypt which for each type of library is a symbolic link
to the appropriate implementation. For example, on a system using
the DES versions:
&prompt.user; ls -l /usr/lib/libcrypt*
lrwxr-xr-x 1 root wheel 13 Mar 19 06:56 libcrypt.a -> libdescrypt.a
lrwxr-xr-x 1 root wheel 18 Mar 19 06:56 libcrypt.so.2.0 -> libdescrypt.so.2.0
lrwxr-xr-x 1 root wheel 15 Mar 19 06:56 libcrypt_p.a -> libdescrypt_p.a
On a system using the MD5-based libraries, the same links will
be present, but the target will be libscrypt
rather than libdescrypt.
If you have installed the DES-capable crypt library
libdescrypt (e.g. by installing the
"crypto" distribution), then which password format will be used
for new passwords is controlled by the
passwd_format
login capability in
/etc/login.conf, which takes values of
either des
or md5
. See the
login.conf(5) manpage for more information about login
capabilities.
S/Key
S/Key is a one-time password scheme based on a one-way hash
function. FreeBSD uses the MD4 hash for compatibility but other
systems have used MD5 and DES-MAC. S/Key has been part of the
FreeBSD base system since version 1.1.5 and is also used on a
growing number of other operating systems. S/Key is a registered
trademark of Bell Communications Research, Inc.
There are three different sorts of passwords which we will talk
about in the discussion below. The first is your usual UNIX-style or
Kerberos password; we will call this a UNIX password
.
The second sort is the one-time password which is generated by the
S/Key key program and accepted by the
keyinit program and the login prompt; we will
call this a one-time password
. The final sort of
password is the secret password which you give to the
key program (and sometimes the
keyinit program) which it uses to generate
one-time passwords; we will call it a secret password
or just unqualified password
.
The secret password does not have anything to do with your UNIX
password; they can be the same but this is not recommended. S/Key
secret passwords are not limited to 8 characters like UNIX passwords,
they can be as long as you like. Passwords of six or seven word
long phrases are fairly common. For the most part, the S/Key system
operates completely independently of the UNIX password
system.
Besides the password, there are two other pieces of data that
are important to S/Key. One is what is known as the
seed
or key
and consists of two letters
and five digits. The other is what is called the iteration
count
and is a number between 1 and 100. S/Key creates the
one-time password by concatenating the seed and the secret password,
then applying the MD4 hash as many times as specified by the
iteration count and turning the result into six short English words.
These six English words are your one-time password. The
login and su programs keep
track of the last one-time password used, and the user is
authenticated if the hash of the user-provided password is equal to
the previous password. Because a one-way hash is used it is
impossible to generate future one-time passwords if a successfully
used password is captured; the iteration count is decremented after
each successful login to keep the user and the login program in
sync. When the iteration count gets down to 1 S/Key must be
reinitialized.
There are four programs involved in the S/Key system which we
will discuss below. The key program accepts an
iteration count, a seed, and a secret password, and generates a
one-time password. The keyinit program is used
to initialized S/Key, and to change passwords, iteration counts, or
seeds; it takes either a secret password, or an iteration count,
seed, and one-time password. The keyinfo program
examines the /etc/skeykeys file and prints out
the invoking user's current iteration count and seed. Finally, the
login and su programs contain
the necessary logic to accept S/Key one-time passwords for
authentication. The login program is also
capable of disallowing the use of UNIX passwords on connections
coming from specified addresses.
There are four different sorts of operations we will cover. The
first is using the keyinit program over a secure
connection to set up S/Key for the first time, or to change your
password or seed. The second operation is using the
keyinit program over an insecure connection, in
conjunction with the key program over a secure
connection, to do the same. The third is using the
key program to log in over an insecure
connection. The fourth is using the key program
to generate a number of keys which can be written down or printed
out to carry with you when going to some location without secure
connections to anywhere.
Secure connection initialization
To initialize S/Key for the first time, change your password,
or change your seed while logged in over a secure connection
(e.g., on the console of a machine or via ssh), use the
keyinit command without any parameters while
logged in as yourself:
&prompt.user; keyinit
Adding unfurl:
Reminder - Only use this method if you are directly connected.
If you are using telnet or rlogin exit with no password and use keyinit -s.
Enter secret password:
Again secret password:
ID unfurl s/key is 99 to17757
DEFY CLUB PRO NASH LACE SOFT
At the Enter secret password: prompt you
should enter a password or phrase. Remember, this is not the
password that you will use to login with, this is used to generate
your one-time login keys. The ID
line gives the
parameters of your particular S/Key instance; your login name, the
iteration count, and seed. When logging in with S/Key, the system
will remember these parameters and present them back to you so you
do not have to remember them. The last line gives the particular
one-time password which corresponds to those parameters and your
secret password; if you were to re-login immediately, this
one-time password is the one you would use.
Insecure connection initialization
To initialize S/Key or change your secret password over an
insecure connection, you will need to already have a secure
connection to some place where you can run the
key program; this might be in the form of a
desk accessory on a Macintosh, or a shell prompt on a machine you
trust. You will also need to make up an iteration count (100 is
probably a good value), and you may make up your own seed or use a
randomly-generated one. Over on the insecure connection (to the
machine you are initializing), use the keyinit
-s command:
&prompt.user; keyinit -s
Updating unfurl:
Old key: to17758
Reminder you need the 6 English words from the key command.
Enter sequence count from 1 to 9999: 100
Enter new key [default to17759]:
s/key 100 to 17759
s/key access password:
To accept the default seed (which the
keyinit program confusingly calls a
key), press return. Then before entering an
access password, move over to your secure connection or S/Key desk
accessory, and give it the same parameters:
&prompt.user; key 100 to17759
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: <secret password>
CURE MIKE BANE HIM RACY GORE
Now switch back over to the insecure connection, and copy the
one-time password generated by key over to the
keyinit program:
s/key access password:CURE MIKE BANE HIM RACY GORE
ID unfurl s/key is 100 to17759
CURE MIKE BANE HIM RACY GORE
The rest of the description from the previous section applies
here as well.
Generating a single one-time password
Once you've initialized S/Key, when you login you will be
presented with a prompt like this:
&prompt.user; telnet example.com
Trying 10.0.0.1...
Connected to example.com
Escape character is '^]'.
FreeBSD/i386 (example.com) (ttypa)
login: <username>
s/key 97 fw13894
Password:
As a side note, the S/Key prompt has a useful feature
(not shown here): if you press return at the password prompt, the
login program will turn echo on, so you can see what you are
typing. This can be extremely useful if you are attempting to
type in an S/Key by hand, such as from a printout. Also, if this
machine were configured to disallow UNIX passwords over a
connection from the source machine, the prompt would have also included
the annotation (s/key required), indicating
that only S/Key one-time passwords will be accepted.
At this point you need to generate your one-time password to
answer this login prompt. This must be done on a trusted system
that you can run the key command on. (There
are versions of the key program from DOS,
Windows and MacOS as well.) The key program
needs both the iteration count and the seed as command line
options. You can cut-and-paste these right from the login prompt
on the machine that you are logging in to.
On the trusted system:
&prompt.user; key 97 fw13894
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password:
WELD LIP ACTS ENDS ME HAAG
Now that you have your one-time password you can continue
logging in:
login: <username>
s/key 97 fw13894
Password: <return to enable echo>
s/key 97 fw13894
Password [echo on]: WELD LIP ACTS ENDS ME HAAG
Last login: Tue Mar 21 11:56:41 from 10.0.0.2 ...
This is the easiest mechanism if you have
a trusted machine. There is a Java S/Key key
applet, The Java OTP
Calculator, that you can download and run locally on any
Java supporting browser.
Generating multiple one-time passwords
Sometimes you have have to go places where you do not have
access to a trusted machine or secure connection. In this case,
it is possible to use the key command to
generate a number of one-time passwords before hand to be printed
out and taken with you. For example:
&prompt.user; key -n 5 30 zz99999
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: <secret password>
26: SODA RUDE LEA LIND BUDD SILT
27: JILT SPY DUTY GLOW COWL ROT
28: THEM OW COLA RUNT BONG SCOT
29: COT MASH BARR BRIM NAN FLAG
30: CAN KNEE CAST NAME FOLK BILK
The requests five keys in sequence, the
specifies what the last iteration number
should be. Note that these are printed out in
reverse order of eventual use. If you are
really paranoid, you might want to write the results down by hand;
otherwise you can cut-and-paste into lpr. Note
that each line shows both the iteration count and the one-time
password; you may still find it handy to scratch off passwords as
you use them.
Restricting use of UNIX passwords
Restrictions can be placed on the use of UNIX passwords based
on the host name, user name, terminal port, or IP address of a
login session. These restrictions can be found in the
configuration file /etc/skey.access. The
&man.skey.access.5; manual page has more info on the complete
format of the file and also details some security cautions to be
aware of before depending on this file for security.
If there is no /etc/skey.access file
(this is the FreeBSD default), then all users will be allowed to
use UNIX passwords. If the file exists, however, then all users
will be required to use S/Key unless explicitly permitted to do
otherwise by configuration statements in the
skey.access file. In all cases, UNIX
passwords are permitted on the console.
Here is a sample configuration file which illustrates the
three most common sorts of configuration statements:
permit internet 192.168.0.0 255.255.0.0
permit user fnord
permit port ttyd0
The first line (permit internet) allows
users whose IP source address (which is vulnerable to spoofing)
matches the specified value and mask, to use UNIX passwords. This
should not be considered a security mechanism, but rather, a means
to remind authorized users that they are using an insecure network
and need to use S/Key for authentication.
The second line (permit user) allows the
specified username, in this case fnord, to use
UNIX passwords at any time. Generally speaking, this should only
be used for people who are either unable to use the
key program, like those with dumb terminals, or
those who are uneducable.
The third line (permit port) allows all
users logging in on the specified terminal line to use UNIX
passwords; this would be used for dial-ups.
Kerberos
Contributed by &a.markm; (based on contribution by
&a.md;).
Kerberos is a network add-on system/protocol that allows users to
authenticate themselves through the services of a secure server.
Services such as remote login, remote copy, secure inter-system file
copying and other high-risk tasks are made considerably safer and more
controllable.
The following instructions can be used as a guide on how to set up
Kerberos as distributed for FreeBSD. However, you should refer to the
relevant manual pages for a complete description.
In FreeBSD, the Kerberos is not that from the original 4.4BSD-Lite,
distribution, but eBones, which had been previously ported to FreeBSD
1.1.5.1, and was sourced from outside the USA/Canada, and was thus
available to system owners outside those countries during the era
of restrictive export controls on cryptographic code from the USA.
Creating the initial database
This is done on the Kerberos server only. First make sure that
you do not have any old Kerberos databases around. You should change
to the directory /etc/kerberosIV and check that
only the following files are present:
&prompt.root; cd /etc/kerberosIV
&prompt.root; ls
README krb.conf krb.realms
If any additional files (such as principal.*
or master_key) exist, then use the
kdb_destroy command to destroy the old Kerberos
database, of if Kerberos is not running, simply delete the extra
files.
You should now edit the krb.conf and
krb.realms files to define your Kerberos realm.
In this case the realm will be GRONDAR.ZA and the
server is grunt.grondar.za. We edit or create
the krb.conf file:
&prompt.root; cat krb.conf
GRONDAR.ZA
GRONDAR.ZA grunt.grondar.za admin server
CS.BERKELEY.EDU okeeffe.berkeley.edu
ATHENA.MIT.EDU kerberos.mit.edu
ATHENA.MIT.EDU kerberos-1.mit.edu
ATHENA.MIT.EDU kerberos-2.mit.edu
ATHENA.MIT.EDU kerberos-3.mit.edu
LCS.MIT.EDU kerberos.lcs.mit.edu
TELECOM.MIT.EDU bitsy.mit.edu
ARC.NASA.GOV trident.arc.nasa.gov
In this case, the other realms do not need to be there. They are
here as an example of how a machine may be made aware of multiple
realms. You may wish to not include them for simplicity.
The first line names the realm in which this system works. The
other lines contain realm/host entries. The first item on a line is a
realm, and the second is a host in that realm that is acting as a
key distribution center
. The words admin
server following a hosts name means that host also
provides an administrative database server. For further explanation
of these terms, please consult the Kerberos man pages.
Now we have to add grunt.grondar.za
to the GRONDAR.ZA realm and also add an entry to
put all hosts in the .grondar.za
domain in the GRONDAR.ZA realm. The
krb.realms file would be updated as
follows:
&prompt.root; cat krb.realms
grunt.grondar.za GRONDAR.ZA
.grondar.za GRONDAR.ZA
.berkeley.edu CS.BERKELEY.EDU
.MIT.EDU ATHENA.MIT.EDU
.mit.edu ATHENA.MIT.EDU
Again, the other realms do not need to be there. They are here as
an example of how a machine may be made aware of multiple realms. You
may wish to remove them to simplify things.
The first line puts the specific system into
the named realm. The rest of the lines show how to default systems of
a particular subdomain to a named realm.
Now we are ready to create the database. This only needs to run
on the Kerberos server (or Key Distribution Center). Issue the
kdb_init command to do this:
&prompt.root; kdb_init
Realm name [default ATHENA.MIT.EDU ]: GRONDAR.ZA
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter Kerberos master key:
Now we have to save the key so that servers on the local machine
can pick it up. Use the kstash command to do
this.
&prompt.root; kstash
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
This saves the encrypted master password in
/etc/kerberosIV/master_key.
Making it all run
Two principals need to be added to the database for
each system that will be secured with Kerberos.
Their names are kpasswd and rcmd
These two principals are made for each system, with the instance being
the name of the individual system.
These daemons, kpasswd and
rcmd allow other systems to change Kerberos
passwords and run commands like rcp,
rlogin and rsh.
Now let's add these entries:
&prompt.root; kdb_edit
Opening database...
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Previous or default values are in [brackets] ,
enter return to leave the same, or new value.
Principal name: passwd
Instance: grunt
<Not found>, Create [y] ? y
Principal: passwd, Instance: grunt, kdc_key_ver: 1
New Password: <---- enter RANDOM here
Verifying password
New Password: <---- enter RANDOM here
Random password [y] ? y
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ?
Attributes [ 0 ] ?
Edit O.K.
Principal name: rcmd
Instance: grunt
<Not found>, Create [y] ?
Principal: rcmd, Instance: grunt, kdc_key_ver: 1
New Password: <---- enter RANDOM here
Verifying password
New Password: <---- enter RANDOM here
Random password [y] ?
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ?
Attributes [ 0 ] ?
Edit O.K.
Principal name: <---- null entry here will cause an exit
Creating the server file
We now have to extract all the instances which define the services
on each machine. For this we use the ext_srvtab
command. This will create a file which must be copied or moved
by secure means to each Kerberos client's
/etc/kerberosIV directory. This file must be present on each server
and client, and is crucial to the operation of Kerberos.
&prompt.root; ext_srvtab grunt
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Generating 'grunt-new-srvtab'....
Now, this command only generates a temporary file which must be
renamed to srvtab so that all the server can pick
it up. Use the mv command to move it into place on
the original system:
&prompt.root; mv grunt-new-srvtab srvtab
If the file is for a client system, and the network is not deemed
safe, then copy the
client-new-srvtab to
removable media and transport it by secure physical means. Be sure to
rename it to srvtab in the client's
/etc/kerberosIV directory, and make sure it is
mode 600:
&prompt.root; mv grumble-new-srvtab srvtab
&prompt.root; chmod 600 srvtab
Populating the database
We now have to add some user entries into the database. First
let's create an entry for the user jane. Use the
kdb_edit command to do this:
&prompt.root; kdb_edit
Opening database...
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Previous or default values are in [brackets] ,
enter return to leave the same, or new value.
Principal name: jane
Instance:
<Not found>, Create [y] ? y
Principal: jane, Instance: , kdc_key_ver: 1
New Password: <---- enter a secure password here
Verifying password
New Password: <---- re-enter the password here
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ?
Attributes [ 0 ] ?
Edit O.K.
Principal name: <---- null entry here will cause an exit
Testing it all out
First we have to start the Kerberos daemons. NOTE that if you
have correctly edited your /etc/rc.conf then this
will happen automatically when you reboot. This is only necessary on
the Kerberos server. Kerberos clients will automagically get what
they need from the /etc/kerberosIV
directory.
&prompt.root; kerberos &
Kerberos server starting
Sleep forever on error
Log file is /var/log/kerberos.log
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Current Kerberos master key version is 1
Local realm: GRONDAR.ZA
&prompt.root; kadmind -n &
KADM Server KADM0.0A initializing
Please do not use 'kill -9' to kill this job, use a
regular kill instead
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Now we can try using the kinit command to get a
ticket for the id jane that we created
above:
&prompt.user; kinit jane
MIT Project Athena (grunt.grondar.za)
Kerberos Initialization for "jane"
Password:
Try listing the tokens using klist to see if we
really have them:
&prompt.user; klist
Ticket file: /tmp/tkt245
Principal: jane@GRONDAR.ZA
Issued Expires Principal
Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.GRONDAR.ZA@GRONDAR.ZA
Now try changing the password using passwd to
check if the kpasswd daemon can get authorization to the Kerberos
database:
&prompt.user; passwd
realm GRONDAR.ZA
Old password for jane:
New Password for jane:
Verifying password
New Password for jane:
Password changed.
Adding su privileges
Kerberos allows us to give each user who
needs root privileges their own separate
supassword. We could now add an id which is
authorized to su to root.
This is controlled by having an instance of root
associated with a principal. Using kdb_edit we can
create the entry jane.root in the Kerberos
database:
&prompt.root; kdb_edit
Opening database...
Enter Kerberos master key:
Current Kerberos master key version is 1.
Master key entered. BEWARE!
Previous or default values are in [brackets] ,
enter return to leave the same, or new value.
Principal name: jane
Instance: root
<Not found>, Create [y] ? y
Principal: jane, Instance: root, kdc_key_ver: 1
New Password: <---- enter a SECURE password here
Verifying password
New Password: <---- re-enter the password here
Principal's new key version = 1
Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?
Max ticket lifetime (*5 minutes) [ 255 ] ? 12 <--- Keep this short!
Attributes [ 0 ] ?
Edit O.K.
Principal name: <---- null entry here will cause an exit
Now try getting tokens for it to make sure it works:
&prompt.root; kinit jane.root
MIT Project Athena (grunt.grondar.za)
Kerberos Initialization for "jane.root"
Password:
Now we need to add the user to root's .klogin
file:
&prompt.root; cat /root/.klogin
jane.root@GRONDAR.ZA
Now try doing the su:
&prompt.user; su
Password:
and take a look at what tokens we have:
&prompt.root; klist
Ticket file: /tmp/tkt_root_245
Principal: jane.root@GRONDAR.ZA
Issued Expires Principal
May 2 20:43:12 May 3 04:43:12 krbtgt.GRONDAR.ZA@GRONDAR.ZA
Using other commands
In an earlier example, we created a principal called
jane with an instance root.
This was based on a user with the same name as the principal, and this
is a Kerberos default; that a
<principal>.<instance> of the form
<username>.root will allow
that <username> to su to
root if the necessary entries are in the .klogin
file in root's home directory:
&prompt.root; cat /root/.klogin
jane.root@GRONDAR.ZA
Likewise, if a user has in their own home directory lines of the
form:
&prompt.user; cat ~/.klogin
jane@GRONDAR.ZA
jack@GRONDAR.ZA
This allows anyone in the GRONDAR.ZA realm
who has authenticated themselves to jane or
jack (via kinit, see above)
access to rlogin to jane's
account or files on this system (grunt) via
rlogin, rsh or
rcp.
For example, Jane now logs into another system, using
Kerberos:
&prompt.user; kinit
MIT Project Athena (grunt.grondar.za)
Password:
%prompt.user; rlogin grunt
Last login: Mon May 1 21:14:47 from grumble
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995
Or Jack logs into Jane's account on the same machine (Jane having
set up the .klogin file as above, and the person
in charge of Kerberos having set up principal
jack with a null instance:
&prompt.user; kinit
&prompt.user; rlogin grunt -l jane
MIT Project Athena (grunt.grondar.za)
Password:
Last login: Mon May 1 21:16:55 from grumble
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995
Firewalls
Contributed by &a.gpalmer; and Alex Nash.
Firewalls are an area of increasing interest for people who are
connected to the Internet, and are even finding applications on private
networks to provide enhanced security. This section will hopefully
explain what firewalls are, how to use them, and how to use the
facilities provided in the FreeBSD kernel to implement them.
People often think that having a firewall between your
internal network and the Big Bad Internet
will solve all
your security problems. It may help, but a poorly setup firewall
system is more of a security risk than not having one at all. A
firewall can add another layer of security to your systems, but it
cannot stop a really determined cracker from penetrating your internal
network. If you let internal security lapse because you believe your
firewall to be impenetrable, you have just made the crackers job that
much easier.
What is a firewall?
There are currently two distinct types of firewalls in common use
on the Internet today. The first type is more properly called a
packet filtering router, where the kernel on a
multi-homed machine chooses whether to forward or block packets based
on a set of rules. The second type, known as a proxy
server, relies on daemons to provide authentication and to
forward packets, possibly on a multi-homed machine which has kernel
packet forwarding disabled.
Sometimes sites combine the two types of firewalls, so that only a
certain machine (known as a bastion host) is
allowed to send packets through a packet filtering router onto an
internal network. Proxy services are run on the bastion host, which
are generally more secure than normal authentication
mechanisms.
FreeBSD comes with a kernel packet filter (known as
IPFW), which is what the rest of this
section will concentrate on. Proxy servers can be built on FreeBSD
from third party software, but there is such a variety of proxy
servers available that it would be impossible to cover them in this
document.
Packet filtering routers
A router is a machine which forwards packets between two or more
networks. A packet filtering router has an extra piece of code in
its kernel which compares each packet to a list of rules before
deciding if it should be forwarded or not. Most modern IP routing
software has packet filtering code within it that defaults to
forwarding all packets. To enable the filters, you need to define a
set of rules for the filtering code so it can decide if the
packet should be allowed to pass or not.
To decide whether a packet should be passed on, the code looks
through its set of rules for a rule which matches the contents of
this packets headers. Once a match is found, the rule action is
obeyed. The rule action could be to drop the packet, to forward the
packet, or even to send an ICMP message back to the originator.
Only the first match counts, as the rules are searched in order.
Hence, the list of rules can be referred to as a rule
chain
.
The packet matching criteria varies depending on the software
used, but typically you can specify rules which depend on the source
IP address of the packet, the destination IP address, the source
port number, the destination port number (for protocols which
support ports), or even the packet type (UDP, TCP, ICMP,
etc).
Proxy servers
Proxy servers are machines which have had the normal system
daemons (telnetd, ftpd, etc) replaced with special servers. These
servers are called proxy servers as they
normally only allow onward connections to be made. This enables you
to run (for example) a proxy telnet server on your firewall host,
and people can telnet in to your firewall from the outside, go
through some authentication mechanism, and then gain access to the
internal network (alternatively, proxy servers can be used for
signals coming from the internal network and heading out).
Proxy servers are normally more secure than normal servers, and
often have a wider variety of authentication mechanisms available,
including one-shot
password systems so that even if
someone manages to discover what password you used, they will not be
able to use it to gain access to your systems as the password
instantly expires. As they do not actually give users access to the
host machine, it becomes a lot more difficult for someone to install
backdoors around your security system.
Proxy servers often have ways of restricting access further, so
that only certain hosts can gain access to the servers, and often
they can be set up so that you can limit which users can talk to
which destination machine. Again, what facilities are available
depends largely on what proxy software you choose.
What does IPFW allow me to do?
IPFW, the software supplied with
FreeBSD, is a packet filtering and accounting system which resides in
the kernel, and has a user-land control utility,
&man.ipfw.8;. Together, they allow you to define and query the
rules currently used by the kernel in its routing decisions.
There are two related parts to IPFW.
The firewall section allows you to perform packet filtering. There is
also an IP accounting section which allows you to track usage of your
router, based on similar rules to the firewall section. This allows
you to see (for example) how much traffic your router is getting from
a certain machine, or how much WWW (World Wide Web) traffic it is
forwarding.
As a result of the way that IPFW is
designed, you can use IPFW on non-router
machines to perform packet filtering on incoming and outgoing
connections. This is a special case of the more general use of
IPFW, and the same commands and techniques
should be used in this situation.
Enabling IPFW on FreeBSD
As the main part of the IPFW system
lives in the kernel, you will need to add one or more options to your
kernel configuration file, depending on what facilities you want, and
recompile your kernel. See reconfiguring
the kernel for more details on how to recompile your
kernel.
There are currently three kernel configuration options relevant to
IPFW:
options IPFIREWALL
Compiles into the kernel the code for packet
filtering.
options IPFIREWALL_VERBOSE
Enables code to allow logging of packets through
&man.syslogd.8;. Without this option, even if you specify
that packets should be logged in the filter rules, nothing will
happen.
options IPFIREWALL_VERBOSE_LIMIT=10
Limits the number of packets logged through
&man.syslogd.8; on a per entry basis. You may wish to use
this option in hostile environments in which you want to log
firewall activity, but do not want to be open to a denial of
service attack via syslog flooding.
When a chain entry reaches the packet limit specified,
logging is turned off for that particular entry. To resume
logging, you will need to reset the associated counter using the
&man.ipfw.8; utility:
&prompt.root; ipfw zero 4500
Where 4500 is the chain entry you wish to continue
logging.
Previous versions of FreeBSD contained an
IPFIREWALL_ACCT option. This is now obsolete as
the firewall code automatically includes accounting
facilities.
Configuring IPFW
The configuration of the IPFW software
is done through the &man.ipfw.8; utility. The syntax for this
command looks quite complicated, but it is relatively simple once you
understand its structure.
There are currently four different command categories used by the
utility: addition/deletion, listing, flushing, and clearing.
Addition/deletion is used to build the rules that control how packets
are accepted, rejected, and logged. Listing is used to examine the
contents of your rule set (otherwise known as the chain) and packet
counters (accounting). Flushing is used to remove all entries from
the chain. Clearing is used to zero out one or more accounting
entries.
Altering the IPFW rules
The syntax for this form of the command is:
ipfw
-N
command
index
action
log
protocol
addresses
options
There is one valid flag when using this form of the
command:
-N
Resolve addresses and service names in output.
The command given can be shortened to the
shortest unique form. The valid commands
are:
add
Add an entry to the firewall/accounting rule list
delete
Delete an entry from the firewall/accounting rule
list
Previous versions of IPFW used
separate firewall and accounting entries. The present version
provides packet accounting with each firewall entry.
If an index value is supplied, it used to
place the entry at a specific point in the chain. Otherwise, the
entry is placed at the end of the chain at an index 100 greater than
the last chain entry (this does not include the default policy, rule
65535, deny).
The log option causes matching rules to be
output to the system console if the kernel was compiled with
IPFIREWALL_VERBOSE.
Valid actions are:
reject
Drop the packet, and send an ICMP host or port unreachable
(as appropriate) packet to the source.
allow
Pass the packet on as normal. (aliases:
pass and
accept)
deny
Drop the packet. The source is not notified via an
ICMP message (thus it appears that the packet never
arrived at the destination).
count
Update packet counters but do not allow/deny the packet
based on this rule. The search continues with the next chain
entry.
Each action will be recognized by the
shortest unambiguous prefix.
The protocols which can be specified
are:
all
Matches any IP packet
icmp
Matches ICMP packets
tcp
Matches TCP packets
udp
Matches UDP packets
The address specification is:
from
address/maskport
to
address/maskport
via interface
You can only specify port in
conjunction with protocols which support ports
(UDP and TCP).
The is optional and may specify the IP
address or domain name of a local IP interface, or an interface name
(e.g. ed0) to match only packets coming
through this interface. Interface unit numbers can be specified
with an optional wildcard. For example, ppp*
would match all kernel PPP interfaces.
The syntax used to specify an
address/mask is:
address
or
address/mask-bits
or
address:mask-pattern
A valid hostname may be specified in place of the IP address.
is a decimal
number representing how many bits in the address mask should be set.
e.g. specifying 192.216.222.1/24 will create a
mask which will allow any address in a class C subnet (in this case,
192.216.222) to be matched.
is an IP
address which will be logically AND'ed with the address given. The
keyword any may be used to specify any IP
address
.
The port numbers to be blocked are specified as:
port,port,port…
to specify either a single port or a list of ports, or
port-port
to specify a range of ports. You may also combine a single range
with a list, but the range must always be specified first.
The options available are:
frag
Matches if the packet is not the first fragment of the
datagram.
in
Matches if the packet is on the way in.
out
Matches if the packet is on the way out.
ipoptions spec
Matches if the IP header contains the comma separated list
of options specified in spec. The
supported list of IP options are: ssrr
(strict source route), lsrr (loose source
route), rr (record packet route), and
ts (time stamp). The absence of a
particular option may be denoted with a leading
!.
established
Matches if the packet is part of an already established
TCP connection (i.e. it has the RST or ACK bits set). You can
optimize the performance of the firewall by placing
established rules early in the
chain.
setup
Matches if the packet is an attempt to establish a TCP
connection (the SYN bit set is set but the ACK bit is
not).
tcpflags flags
Matches if the TCP header contains the comma separated
list of flags. The supported flags
are fin, syn,
rst, psh,
ack, and urg. The
absence of a particular flag may be indicated by a leading
!.
icmptypes types
Matches if the ICMP type is present in the list
types. The list may be specified
as any combination of ranges and/or individual types separated
by commas. Commonly used ICMP types are: 0
echo reply (ping reply), 3 destination
unreachable, 5 redirect,
8 echo request (ping request), and
11 time exceeded (used to indicate TTL
expiration as with &man.traceroute.8;).
Listing the IPFW rules
The syntax for this form of the command is:
ipfw
-a
-t
-N
l
There are three valid flags when using this form of the
command:
-a
While listing, show counter values. This option is the
only way to see accounting counters.
-t
Display the last match times for each chain entry. The
time listing is incompatible with the input syntax used by the
&man.ipfw.8; utility.
-N
Attempt to resolve given addresses and service
names.
Flushing the IPFW rules
The syntax for flushing the chain is:
ipfw
flush
This causes all entries in the firewall chain to be removed
except the fixed default policy enforced by the kernel (index
65535). Use caution when flushing rules, the default deny policy
will leave your system cut off from the network until allow entries
are added to the chain.
Clearing the IPFW packet counters
The syntax for clearing one or more packet counters is:
ipfw
zero
index
When used without an index argument,
all packet counters are cleared. If an
index is supplied, the clearing operation
only affects a specific chain entry.
Example commands for ipfw
This command will deny all packets from the host evil.crackers.org to the telnet port of the
host nice.people.org:
&prompt.root ipfw add deny tcp from evil.crackers.org to nice.people.org 23
The next example denies and logs any TCP traffic from the entire
crackers.org network (a class C) to
the nice.people.org machine (any
port).
&prompt.root; ipfw add deny log tcp from evil.crackers.org/24 to nice.people.org
If you do not want people sending X sessions to your internal
network (a subnet of a class C), the following command will do the
necessary filtering:
&prompt.root; ipfw add deny tcp from any to my.org/28 6000 setup
To see the accounting records:
&prompt.root; ipfw -a list
or in the short form
&prompt.root; ipfw -a l
You can also see the last time a chain entry was matched
with:
&prompt.root; ipfw -at l
Building a packet filtering firewall
The following suggestions are just that: suggestions. The
requirements of each firewall are different and we cannot tell you
how to build a firewall to meet your particular requirements.
When initially setting up your firewall, unless you have a test
bench setup where you can configure your firewall host in a controlled
environment, it is strongly recommend you use the logging version of the
commands and enable logging in the kernel. This will allow you to
quickly identify problem areas and cure them without too much
disruption. Even after the initial setup phase is complete, I
recommend using the logging for `deny' as it allows tracing of
possible attacks and also modification of the firewall rules if your
requirements alter.
If you use the logging versions of the accept
command, it can generate large amounts of log
data as one log line will be generated for every packet that passes
through the firewall, so large ftp/http transfers, etc, will really
slow the system down. It also increases the latencies on those
packets as it requires more work to be done by the kernel before the
packet can be passed on. syslogd with also start using up a lot
more processor time as it logs all the extra data to disk, and it
could quite easily fill the partition /var/log
is located on.
You should enable your firewall from
/etc/rc.conf.local or
/etc/rc.conf. The associated man page explains
which knobs to fiddle and lists some preset firewall configurations.
If you do not use a preset configuration, ipfw list
will output the current ruleset into a file that you can
pass to rc.conf. If you do not use
/etc/rc.conf.local or
/etc/rc.conf to enable your firewall,
it is important to make sure your firewall is enabled before
any IP interfaces are configured.
The next problem is what your firewall should actually
do! This is largely dependent on what access to
your network you want to allow from the outside, and how much access
to the outside world you want to allow from the inside. Some general
rules are:
Block all incoming access to ports below 1024 for TCP. This is
where most of the security sensitive services are, like finger,
SMTP (mail) and telnet.
Block all incoming UDP traffic. There
are very few useful services that travel over UDP, and what useful
traffic there is is normally a security threat (e.g. Suns RPC and
NFS protocols). This has its disadvantages also, since UDP is a
connectionless protocol, denying incoming UDP traffic also blocks
the replies to outgoing UDP traffic. This can cause a problem for
people (on the inside) using external archie (prospero) servers.
If you want to allow access to archie, you'll have to allow
packets coming from ports 191 and 1525 to any internal UDP port
through the firewall. ntp is another service you may consider
allowing through, which comes from port 123.
Block traffic to port 6000 from the outside. Port 6000 is the
port used for access to X11 servers, and can be a security threat
(especially if people are in the habit of doing xhost
+ on their workstations). X11 can actually use a
range of ports starting at 6000, the upper limit being how many X
displays you can run on the machine. The upper limit as defined
by RFC 1700 (Assigned Numbers) is 6063.
Check what ports any internal servers use (e.g. SQL servers,
etc). It is probably a good idea to block those as well, as they
normally fall outside the 1-1024 range specified above.
Another checklist for firewall configuration is available from
CERT at http://www.cert.org/tech_tips/packet_filtering.html
As stated above, these are only guidelines.
You will have to decide what filter rules you want to use on your
firewall yourself. We cannot accept ANY responsibility if someone
breaks into your network, even if you follow the advice given
above.
OpenSSL
As of FreeBSD 4.0, the OpenSSL toolkit is a part of the base
system. OpenSSL
provides a general-purpose cryptography library, as well as the
Secure Sockets Layer v2/v3 (SSLv2/SSLv3) and Transport Layer
Security v1 (TLSv1) network security protocols.
However, one of the algorithms (specifically IDEA)
included in OpenSSL is protected by patents in the USA and
elsewhere, and is not available for unrestricted use.
IDEA is included in the OpenSSL sources in FreeBSD, but it is not
built by default. If you wish to use it, and you comply with the
license terms, enable the MAKE_IDEA switch in /etc/make.conf and
rebuild your sources using 'make world'.
Today, the RSA algorithm is free for use in USA and other
countries. In the past it was protected by a patent.
Source Code Installations
OpenSSL is part of the src-crypto and
src-secure cvsup collections. See the Obtaining FreeBSD section for more
information about obtaining and updating FreeBSD source
code.
IPsec
Contributed by &a.shin;, 5 March
2000.
- IPsec mechanism provides secure communication either for IP
+ The IPsec mechanism provides secure communication either for IP
layer and socket layer communication. This section should
- explain how to use them. About IPsec implementation, please
- refer section 23.5.4.
+ explain how to use them. For implementation details, please
+ refer to The
+ Developers' Handbook.
The current IPsec implementation supports both transport mode
and tunnel mode. However, tunnel mode comes with some restrictions.
http://www.kame.net/newsletter/
has more comprehensive examples.
Please be aware that in order to use this functionality, you
must have the following options compiled into your kernel:
options IPSEC #IP security
options IPSEC_ESP #IP security (crypto; define w/IPSEC)
Transport mode example with IPv4
Let's setup security association to deploy a secure channel
between HOST A (10.2.3.4) and HOST B (10.6.7.8). Here we show a little
complicated example. From HOST A to HOST B, only old AH is used.
From HOST B to HOST A, new AH and new ESP are combined.
Now we should choose algorithm to be used corresponding to
"AH"/"new AH"/"ESP"/"new ESP". Please refer to the &man.setkey.8; man
page to know algorithm names. Our choice is MD5 for AH, new-HMAC-SHA1
for new AH, and new-DES-expIV with 8 byte IV for new ESP.
Key length highly depends on each algorithm. For example, key
length must be equal to 16 bytes for MD5, 20 for new-HMAC-SHA1,
and 8 for new-DES-expIV. Now we choose "MYSECRETMYSECRET",
"KAMEKAMEKAMEKAMEKAME", "PASSWORD", respectively.
OK, let's assign SPI (Security Parameter Index) for each protocol.
Please note that we need 3 SPIs for this secure channel since three
security headers are produced (one for from HOST A to HOST B, two for
from HOST B to HOST A). Please also note that SPI MUST be greater
than or equal to 256. We choose, 1000, 2000, and 3000, respectively.
(1)
HOST A ------> HOST B
(1)PROTO=AH
ALG=MD5(RFC1826)
KEY=MYSECRETMYSECRET
SPI=1000
(2.1)
HOST A <------ HOST B
<------
(2.2)
(2.1)
PROTO=AH
ALG=new-HMAC-SHA1(new AH)
KEY=KAMEKAMEKAMEKAMEKAME
SPI=2000
(2.2)
PROTO=ESP
ALG=new-DES-expIV(new ESP)
IV length = 8
KEY=PASSWORD
SPI=3000
Now, let's setup security association. Execute &man.setkey.8;
on both HOST A and B:
&prompt.root; setkey -c
add 10.2.3.4 10.6.7.8 ah-old 1000 -m transport -A keyed-md5 "MYSECRETMYSECRET" ;
add 10.6.7.8 10.2.3.4 ah 2000 -m transport -A hmac-sha1 "KAMEKAMEKAMEKAMEKAME" ;
add 10.6.7.8 10.2.3.4 esp 3000 -m transport -E des-cbc "PASSWORD" ;
^D
Actually, IPsec communication doesn't process until security policy
entries will be defined. In this case, you must setup each host.
At A:
&prompt.root; setkey -c
spdadd 10.2.3.4 10.6.7.8 any -P out ipsec
ah/transport/10.2.3.4-10.6.7.8/require ;
^D
At B:
&prompt.root; setkey -c
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
esp/transport/10.6.7.8-10.2.3.4/require ;
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
ah/transport/10.6.7.8-10.2.3.4/require ;
^D
HOST A --------------------------------------> HOST E
10.2.3.4 10.6.7.8
| |
========== old AH keyed-md5 ==========>
<========= new AH hmac-sha1 ===========
<========= new ESP des-cbc ============
Transport mode example with IPv6
Another example using IPv6.
ESP transport mode is recommended for TCP port number 110 between
Host-A and Host-B.
============ ESP ============
| |
Host-A Host-B
fec0::10 -------------------- fec0::11
Encryption algorithm is blowfish-cbc whose key is "kamekame", and
authentication algorithm is hmac-sha1 whose key is "this is the test
key". Configuration at Host-A:
&prompt.root; setkey -c <<EOF
spdadd fec0::10[any] fec0::11[110] tcp -P out ipsec
esp/transport/fec0::10-fec0::11/use ;
spdadd fec0::11[110] fec0::10[any] tcp -P in ipsec
esp/transport/fec0::11-fec0::10/use ;
add fec0::10 fec0::11 esp 0x10001
-m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
add fec0::11 fec0::10 esp 0x10002
-m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
EOF
and at Host-B:
&prompt.root; setkey -c <<EOF
spdadd fec0::11[110] fec0::10[any] tcp -P out ipsec
esp/transport/fec0::11-fec0::10/use ;
spdadd fec0::10[any] fec0::11[110] tcp -P in ipsec
esp/transport/fec0::10-fec0::11/use ;
add fec0::10 fec0::11 esp 0x10001 -m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
add fec0::11 fec0::10 esp 0x10002 -m transport
-E blowfish-cbc "kamekame"
-A hmac-sha1 "this is the test key" ;
EOF
Note the direction of SP.
Tunnel mode example with IPv4
Tunnel mode between two security gateways
Security protocol is old AH tunnel mode, i.e. specified by
RFC1826, with keyed-md5 whose key is "this is the test" as
authentication algorithm.
======= AH =======
| |
Network-A Gateway-A Gateway-B Network-B
10.0.1.0/24 ---- 172.16.0.1 ----- 172.16.0.2 ---- 10.0.2.0/24
Configuration at Gateway-A:
&prompt.root; setkey -c <<EOF
spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec
ah/tunnel/172.16.0.1-172.16.0.2/require ;
spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec
ah/tunnel/172.16.0.2-172.16.0.1/require ;
add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any
-A keyed-md5 "this is the test" ;
add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any
-A keyed-md5 "this is the test" ;
EOF
If port number field is omitted such above then "[any]" is
employed. `-m' specifies the mode of SA to be used. "-m any" means
wild-card of mode of security protocol. You can use this SA for both
tunnel and transport mode.
and at Gateway-B:
&prompt.root; setkey -c <<EOF
spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec
ah/tunnel/172.16.0.2-172.16.0.1/require ;
spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec
ah/tunnel/172.16.0.1-172.16.0.2/require ;
add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any
-A keyed-md5 "this is the test" ;
add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any
-A keyed-md5 "this is the test" ;
EOF
Making SA bundle between two security gateways
AH transport mode and ESP tunnel mode is required between
Gateway-A and Gateway-B. In this case, ESP tunnel mode is applied first,
and AH transport mode is next.
========== AH =========
| ======= ESP ===== |
| | | |
Network-A Gateway-A Gateway-B Network-B
fec0:0:0:1::/64 --- fec0:0:0:1::1 ---- fec0:0:0:2::1 --- fec0:0:0:2::/64
Tunnel mode example with IPv6
Encryption algorithm is 3des-cbc, and authentication algorithm
for ESP is hmac-sha1. Authentication algorithm for AH is hmac-md5.
Configuration at Gateway-A:
&prompt.root; setkey -c <<EOF
spdadd fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out ipsec
esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require
ah/transport/fec0:0:0:1::1-fec0:0:0:2::1/require ;
spdadd fec0:0:0:2::/64 fec0:0:0:1::/64 any -P in ipsec
esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require
ah/transport/fec0:0:0:2::1-fec0:0:0:1::1/require ;
add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10001 -m tunnel
-E 3des-cbc "kamekame12341234kame1234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:1::1 fec0:0:0:2::1 ah 0x10001 -m transport
-A hmac-md5 "this is the test" ;
add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10001 -m tunnel
-E 3des-cbc "kamekame12341234kame1234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:2::1 fec0:0:0:1::1 ah 0x10001 -m transport
-A hmac-md5 "this is the test" ;
EOF
Making SAs with the different end
ESP tunnel mode is required between Host-A and Gateway-A. Encryption
algorithm is cast128-cbc, and authentication algorithm for ESP is
hmac-sha1. ESP transport mode is recommended between Host-A and Host-B.
Encryption algorithm is rc5-cbc, and authentication algorithm for ESP is
hmac-md5.
================== ESP =================
| ======= ESP ======= |
| | | |
Host-A Gateway-A Host-B
fec0:0:0:1::1 ---- fec0:0:0:2::1 ---- fec0:0:0:2::2
Configuration at Host-A:
&prompt.root; setkey -c <<EOF
spdadd fec0:0:0:1::1[any] fec0:0:0:2::2[80] tcp -P out ipsec
esp/transport/fec0:0:0:1::1-fec0:0:0:2::2/use
esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ;
spdadd fec0:0:0:2::1[80] fec0:0:0:1::1[any] tcp -P in ipsec
esp/transport/fec0:0:0:2::2-fec0:0:0:l::1/use
esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ;
add fec0:0:0:1::1 fec0:0:0:2::2 esp 0x10001
-m transport
-E cast128-cbc "12341234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10002
-E rc5-cbc "kamekame"
-A hmac-md5 "this is the test" ;
add fec0:0:0:2::2 fec0:0:0:1::1 esp 0x10003
-m transport
-E cast128-cbc "12341234"
-A hmac-sha1 "this is the test key" ;
add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004
-E rc5-cbc "kamekame"
-A hmac-md5 "this is the test" ;
EOF
OpenSSH
Contributed by &a.chern;, April 21,
2001.
Secure shell is a secure set of programs used to access a remote
machine. It can be used as a secure medium in place of rlogin, rsh,
rcp, etc. X11 connections, as well as other TCP/IP connections can
be tunnelled/forwarded securely through OpenSSH. Utilizing, RSA
public key cryptography, OpenSSH is a powerful secure alternative
over traditional utilities.
The package provides secure alternatives to many r*
*nix commands. Namely, rlogin, rcp, and
rsh.
OpenSSH is maintained by the OpenBSD project, and is based upon
SSH v1.2.12 with all the recent bug fixes and updates.
The OpenSSH client is compatible with both SSH protocols 1 and
2.
Advantages of using OpenSSH
Normally, when using telnet or
rlogin, data is sent over the network in an clear,
un-encrypted form. Network sniffers on either side, the server
or the client, or any route in between, can steal your
user/password information, and data transferred in your session.
Attackers can even hijack an existing TCP/IP connection and gain
control of your login session.
With the SSH protocol, all this data is sent encrypted,
making the above impossible.
Enabling sshd
Be sure to make the following additions to your
rc.conf file:
sshd_enable="YES"
This will load the ssh daemon the next time your system inits.
SSH client
The ssh utility works similarly to
rlogin.
&prompt.root ssh user@foobardomain.com
Host key not found from the list of known hosts.
Are you sure you want to continue connecting (yes/no)? yes
Host 'foobardomain.com' added to the list of known hosts.
user@foobardomain.com's password: *******
The login will continue just as it would have if a session was
created using rlogin or telnet. SSH utilizes a key fingerprint
system for verifying the authenticity of the server when the
client connects. The user is prompted to enter 'yes' only during
the first time connecting. Future attempts to login are all
verified against the saved fingerprint key. The SSH client
will alert you if the saved fingerprint differs from the
received fingerprint on future login attempts. The fingerprints
are saved in ~/.ssh/known_hosts
Secure copy
The scp command works similarly to rcp; it copies a
file off a remote machine, except in a secure fashion.
&prompt.root scp user@foobardomain.com:/COPYRIGHT COPYRIGHT
user@foobardomain.com's password:
COPYRIGHT 100% |*****************************| 4735
00:00
&prompt.root
Since the fingerprint was already saved for this host in the
previous example, it is verified when using scp
here.
Configuration
The system-wide configuration files for both the OpenSSH
daemon and client reside within the /etc/ssh
directory.
ssh_config configures the client
settings, while sshd_config configures the
daemon.
ssh-keygen
Instead of using passwords, ssh-keygen can
be used to generate RSA keys to authenticate a user.
&prompt.user ssh-keygen
Initializing random number generator...
Generating p: .++ (distance 66)
Generating q: ..............................++ (distance 498)
Computing the keys...
Key generation complete.
Enter file in which to save the key (/home/user/.ssh/identity):
Enter passphrase:
Enter the same passphrase again:
Your identification has been saved in /home/user/.ssh/identity.
...
ssh-keygen will create a public and private
key pair for use in authentication. The private key is stored in
~/.ssh/identity, whereas the public key is
stored in ~/.ssh/identity.pub. The public
key must be placed in ~/.ssh/authorized_keys
of the remote machine in order for the setup to work.
This will allow connection to the remote machine based upon
RSA authentication, not password.
If a passphrase is used in ssh-keygen, the user
will be prompted for a password each time in order to use the private
key.
ssh-agent and ssh-add are
utilities used in managing multiple passworded private keys.
Further Reading
OpenSSH
&man.ssh.1 &man.scp.1 &man.ssh-keygen.1
&man.ssh-agent.1 &man.ssh-add.1
&man.sshd.8 &man.sftp-server.8