doc/en_US.ISO8859-1/books/handbook/security/chapter.xml
Bjoern Heidotting 7080ac9337 - Turn programlistings into screens
- Add root prompts to screens
- Separate corp-net an priv-net screens

Reviewed by:	bcr
Differential Revision:	https://reviews.freebsd.org/D26575
2020-09-29 17:31:03 +00:00

4157 lines
168 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!--
The FreeBSD Documentation Project
$FreeBSD$
-->
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="security">
<info>
<title>Security</title>
<authorgroup>
<author>
<personname>
<firstname>Tom</firstname>
<surname>Rhodes</surname>
</personname>
<contrib>Rewritten by </contrib>
</author>
</authorgroup>
</info>
<indexterm><primary>security</primary></indexterm>
<sect1 xml:id="security-synopsis">
<title>Synopsis</title>
<para>Security, whether physical or virtual, is a topic so broad
that an entire industry has evolved around it. Hundreds of
standard practices have been authored about how to secure
systems and networks, and as a user of &os;, understanding how
to protect against attacks and intruders is a must.</para>
<para>In this chapter, several fundamentals and techniques will be
discussed. The &os; system comes with multiple layers of
security, and many more third party utilities may be added to
enhance security.</para>
<para>After reading this chapter, you will know:</para>
<itemizedlist>
<listitem>
<para>Basic &os; system security concepts.</para>
</listitem>
<listitem>
<para>The various crypt mechanisms available in &os;.</para>
</listitem>
<listitem>
<para>How to set up one-time password authentication.</para>
</listitem>
<listitem>
<para>How to configure <application>TCP Wrapper</application>
for use with &man.inetd.8;.</para>
</listitem>
<listitem>
<para>How to set up <application>Kerberos</application> on
&os;.</para>
</listitem>
<listitem>
<para>How to configure <acronym>IPsec</acronym> and create a
<acronym>VPN</acronym>.</para>
</listitem>
<listitem>
<para>How to configure and use
<application>OpenSSH</application> on &os;.</para>
</listitem>
<listitem>
<para>How to use file system <acronym>ACL</acronym>s.</para>
</listitem>
<listitem>
<para>How to use <application>pkg</application> to audit
third party software packages installed from the Ports
Collection.</para>
</listitem>
<listitem>
<para>How to utilize &os; security advisories.</para>
</listitem>
<listitem>
<para>What Process Accounting is and how to enable it on
&os;.</para>
</listitem>
<listitem>
<para>How to control user resources using login classes or the
resource limits database.</para>
</listitem>
</itemizedlist>
<para>Before reading this chapter, you should:</para>
<itemizedlist>
<listitem>
<para>Understand basic &os; and Internet concepts.</para>
</listitem>
</itemizedlist>
<para>Additional security topics are covered elsewhere in this
Handbook. For example, Mandatory Access Control is discussed in
<xref linkend="mac"/> and Internet firewalls are discussed in
<xref linkend="firewalls"/>.</para>
</sect1>
<sect1 xml:id="security-intro">
<title>Introduction</title>
<para>Security is everyone's responsibility. A weak entry point
in any system could allow intruders to gain access to critical
information and cause havoc on an entire network. One of the
core principles of information security is the
<acronym>CIA</acronym> triad, which stands for the
Confidentiality, Integrity, and Availability of information
systems.</para>
<para>The <acronym>CIA</acronym> triad is a bedrock concept of
computer security as customers and users expect their data to be
protected. For example, a customer expects that their credit
card information is securely stored (confidentiality), that
their orders are not changed behind the scenes (integrity), and
that they have access to their order information at all times
(availablility).</para>
<para>To provide <acronym>CIA</acronym>, security professionals
apply a defense in depth strategy. The idea of defense in depth
is to add several layers of security to prevent one single layer
failing and the entire security system collapsing. For example,
a system administrator cannot simply turn on a firewall and
consider the network or system secure. One must also audit
accounts, check the integrity of binaries, and ensure malicious
tools are not installed. To implement an effective security
strategy, one must understand threats and how to defend against
them.</para>
<para>What is a threat as it pertains to computer security?
Threats are not limited to remote attackers who attempt to
access a system without permission from a remote location.
Threats also include employees, malicious software, unauthorized
network devices, natural disasters, security vulnerabilities,
and even competing corporations.</para>
<para>Systems and networks can be accessed without permission,
sometimes by accident, or by remote attackers, and in some
cases, via corporate espionage or former employees. As a user,
it is important to prepare for and admit when a mistake has led
to a security breach and report possible issues to the security
team. As an administrator, it is important to know of the
threats and be prepared to mitigate them.</para>
<para>When applying security to systems, it is recommended to
start by securing the basic accounts and system configuration,
and then to secure the network layer so that it adheres to the
system policy and the organization's security procedures. Many
organizations already have a security policy that covers the
configuration of technology devices. The policy should include
the security configuration of workstations, desktops, mobile
devices, phones, production servers, and development servers.
In many cases, standard operating procedures
(<acronym>SOP</acronym>s) already exist. When in doubt, ask the
security team.</para>
<para>The rest of this introduction describes how some of these
basic security configurations are performed on a &os; system.
The rest of this chapter describes some specific tools which can
be used when implementing a security policy on a &os;
system.</para>
<sect2 xml:id="security-accounts">
<title>Preventing Logins</title>
<para>In securing a system, a good starting point is an audit of
accounts. Ensure that <systemitem
class="username">root</systemitem> has a strong password and
that this password is not shared. Disable any accounts that
do not need login access.</para>
<para>To deny login access to accounts, two methods exist. The
first is to lock the account. This example locks the
<systemitem class="username">toor</systemitem> account:</para>
<screen>&prompt.root; <userinput>pw lock <replaceable>toor</replaceable></userinput></screen>
<para>The second method is to prevent login access by changing
the shell to <filename>/usr/sbin/nologin</filename>. Only the
superuser can change the shell for other users:</para>
<screen>&prompt.root; <userinput>chsh -s /usr/sbin/nologin <replaceable>toor</replaceable></userinput></screen>
<para>The <filename>/usr/sbin/nologin</filename> shell prevents
the system from assigning a shell to the user when they
attempt to login.</para>
</sect2>
<sect2 xml:id="security-accountmgmt">
<title>Permitted Account Escalation</title>
<para>In some cases, system administration needs to be shared
with other users. &os; has two methods to handle this. The
first one, which is not recommended, is a shared root password
used by members of the <systemitem
class="groupname">wheel</systemitem> group. With this
method, a user types <command>su</command> and enters the
password for <systemitem class="groupname">wheel</systemitem>
whenever superuser access is needed. The user should then
type <command>exit</command> to leave privileged access after
finishing the commands that required administrative access.
To add a user to this group, edit
<filename>/etc/group</filename> and add the user to the end of
the <literal>wheel</literal> entry. The user must be
separated by a comma character with no space.</para>
<para>The second, and recommended, method to permit privilege
escalation is to install the <package>security/sudo</package>
package or port. This software provides additional auditing,
more fine-grained user control, and can be configured to lock
users into running only the specified privileged
commands.</para>
<para>After installation, use <command>visudo</command> to edit
<filename>/usr/local/etc/sudoers</filename>. This example
creates a new <systemitem
class="groupname">webadmin</systemitem> group, adds the
<systemitem class="username">trhodes</systemitem> account to
that group, and configures that group access to restart
<package>apache24</package>:</para>
<screen>&prompt.root; <userinput>pw groupadd webadmin -M trhodes -g 6000</userinput>
&prompt.root; <userinput>visudo</userinput>
%webadmin ALL=(ALL) /usr/sbin/service apache24 *</screen>
</sect2>
<sect2 xml:id="security-passwords">
<title>Password Hashes</title>
<para>Passwords are a necessary evil of technology. When they
must be used, they should be complex and a powerful hash
mechanism should be used to encrypt the version that is stored
in the password database. &os; supports the
<acronym>DES</acronym>, <acronym>MD5</acronym>,
<acronym>SHA256</acronym>, <acronym>SHA512</acronym>, and
Blowfish hash algorithms in its <function>crypt()</function>
library. The default of <acronym>SHA512</acronym> should not
be changed to a less secure hashing algorithm, but can be
changed to the more secure Blowfish algorithm.</para>
<note>
<para>Blowfish is not part of <acronym>AES</acronym> and is
not considered compliant with any Federal Information
Processing Standards (<acronym>FIPS</acronym>). Its use may
not be permitted in some environments.</para>
</note>
<para>To determine which hash algorithm is used to encrypt a
user's password, the superuser can view the hash for the user
in the &os; password database. Each hash starts with a symbol
which indicates the type of hash mechanism used to encrypt the
password. If <acronym>DES</acronym> is used, there is no
beginning symbol. For <acronym>MD5</acronym>, the symbol is
<literal>$</literal>. For <acronym>SHA256</acronym> and
<acronym>SHA512</acronym>, the symbol is
<literal>$6$</literal>. For Blowfish, the symbol is
<literal>$2a$</literal>. In this example, the password for
<systemitem class="username">dru</systemitem> is hashed using
the default <acronym>SHA512</acronym> algorithm as the hash
starts with <literal>$6$</literal>. Note that the encrypted
hash, not the password itself, is stored in the password
database:</para>
<screen>&prompt.root; <userinput>grep dru /etc/master.passwd</userinput>
dru:$6$pzIjSvCAn.PBYQBA$PXpSeWPx3g5kscj3IMiM7tUEUSPmGexxta.8Lt9TGSi2lNQqYGKszsBPuGME0:1001:1001::0:0:dru:/usr/home/dru:/bin/csh</screen>
<para>The hash mechanism is set in the user's login class. For
this example, the user is in the <literal>default</literal>
login class and the hash algorithm is set with this line in
<filename>/etc/login.conf</filename>:</para>
<programlisting> :passwd_format=sha512:\</programlisting>
<para>To change the algorithm to Blowfish, modify that line to
look like this:</para>
<programlisting> :passwd_format=blf:\</programlisting>
<para>Then run <command>cap_mkdb /etc/login.conf</command> as
described in <xref linkend="users-limiting"/>. Note that this
change will not affect any existing password hashes. This
means that all passwords should be re-hashed by asking users
to run <command>passwd</command> in order to change their
password.</para>
<para>For remote logins, two-factor authentication should be
used. An example of two-factor authentication is
<quote>something you have</quote>, such as a key, and
<quote>something you know</quote>, such as the passphrase for
that key. Since <application>OpenSSH</application> is part of
the &os; base system, all network logins should be over an
encrypted connection and use key-based authentication instead
of passwords. For more information, refer to <xref
linkend="openssh"/>. Kerberos users may need to make
additional changes to implement
<application>OpenSSH</application> in their network. These
changes are described in <xref linkend="kerberos5"/>.</para>
</sect2>
<sect2 xml:id="security-pwpolicy">
<title>Password Policy Enforcement</title>
<para>Enforcing a strong password policy for local accounts is a
fundamental aspect of system security. In &os;, password
length, password strength, and password complexity can be
implemented using built-in Pluggable Authentication Modules
(<acronym>PAM</acronym>).</para>
<para>This section demonstrates how to configure the minimum and
maximum password length and the enforcement of mixed
characters using the <filename>pam_passwdqc.so</filename>
module. This module is enforced when a user changes their
password.</para>
<para>To configure this module, become the superuser and
uncomment the line containing
<literal>pam_passwdqc.so</literal> in
<filename>/etc/pam.d/passwd</filename>. Then, edit that line
to match the password policy:</para>
<programlisting>password requisite pam_passwdqc.so <replaceable>min=disabled,disabled,disabled,12,10 similar=deny retry=3</replaceable> enforce=users</programlisting>
<para>This example sets several requirements for new passwords.
The <literal>min</literal> setting controls the minimum
password length. It has five values because this module
defines five different types of passwords based on their
complexity. Complexity is defined by the type of characters
that must exist in a password, such as letters, numbers,
symbols, and case. The types of passwords are described in
&man.pam.passwdqc.8;. In this example, the first three types
of passwords are disabled, meaning that passwords that meet
those complexity requirements will not be accepted, regardless
of their length. The <literal>12</literal> sets a minimum
password policy of at least twelve characters, if the password
also contains characters with three types of complexity. The
<literal>10</literal> sets the password policy to also allow
passwords of at least ten characters, if the password contains
characters with four types of complexity.</para>
<para>The <literal>similar</literal> setting denies passwords
that are similar to the user's previous password. The
<literal>retry</literal> setting provides a user with three
opportunities to enter a new password.</para>
<para>Once this file is saved, a user changing their password
will see a message similar to the following:</para>
<screen>&prompt.user; <userinput>passwd</userinput>
Changing local password for trhodes
Old Password:
You can now choose the new password.
A valid password should be a mix of upper and lower case letters,
digits and other characters. You can use a 12 character long
password with characters from at least 3 of these 4 classes, or
a 10 character long password containing characters from all the
classes. Characters that form a common pattern are discarded by
the check.
Alternatively, if no one else can see your terminal now, you can
pick this as your password: "trait-useful&amp;knob".
Enter new password:</screen>
<para>If a password that does not match the policy is entered,
it will be rejected with a warning and the user will have an
opportunity to try again, up to the configured number of
retries.</para>
<para>Most password policies require passwords to expire after
so many days. To set a password age time in &os;, set
<option>passwordtime</option> for the user's login class in
<filename>/etc/login.conf</filename>. The
<literal>default</literal> login class contains an
example:</para>
<programlisting># :passwordtime=90d:\</programlisting>
<para>So, to set an expiry of 90 days for this login class,
remove the comment symbol (<literal>#</literal>), save the
edit, and run <command>cap_mkdb
/etc/login.conf</command>.</para>
<para>To set the expiration on individual users, pass an
expiration date or the number of days to expiry and a username
to <command>pw</command>:</para>
<screen>&prompt.root; <userinput>pw usermod -p <replaceable>30-apr-2015</replaceable> -n <replaceable>trhodes</replaceable></userinput></screen>
<para>As seen here, an expiration date is set in the form of
day, month, and year. For more information, see
&man.pw.8;.</para>
</sect2>
<sect2 xml:id="security-rkhunter">
<title>Detecting Rootkits</title>
<para>A <firstterm>rootkit</firstterm> is any unauthorized
software that attempts to gain <systemitem
class="username">root</systemitem> access to a system. Once
installed, this malicious software will normally open up
another avenue of entry for an attacker. Realistically, once
a system has been compromised by a rootkit and an
investigation has been performed, the system should be
reinstalled from scratch. There is tremendous risk that even
the most prudent security or systems engineer will miss
something an attacker left behind.</para>
<para>A rootkit does do one thing useful for administrators:
once detected, it is a sign that a compromise happened at some
point. But, these types of applications tend to be very well
hidden. This section demonstrates a tool that can be used to
detect rootkits, <package>security/rkhunter</package>.</para>
<para>After installation of this package or port, the system may
be checked using the following command. It will produce a lot
of information and will require some manual pressing of
<keycap>ENTER</keycap>:</para>
<screen>&prompt.root; <userinput>rkhunter -c</userinput></screen>
<para>After the process completes, a status message will be
printed to the screen. This message will include the amount
of files checked, suspect files, possible rootkits, and more.
During the check, some generic security warnings may
be produced about hidden files, the
<application>OpenSSH</application> protocol selection, and
known vulnerable versions of installed software. These can be
handled now or after a more detailed analysis has been
performed.</para>
<para>Every administrator should know what is running on the
systems they are responsible for. Third-party tools like
<application>rkhunter</application> and
<package>sysutils/lsof</package>, and native commands such
as <command>netstat</command> and <command>ps</command>, can
show a great deal of information on the system. Take notes on
what is normal, ask questions when something seems out of
place, and be paranoid. While preventing a compromise is
ideal, detecting a compromise is a must.</para>
</sect2>
<sect2 xml:id="security-ids">
<title>Binary Verification</title>
<para>Verification of system files and binaries is important
because it provides the system administration and security
teams information about system changes. A software
application that monitors the system for changes is called an
Intrusion Detection System (<acronym>IDS</acronym>).</para>
<para>&os; provides native support for a basic
<acronym>IDS</acronym> system. While the nightly security
emails will notify an administrator of changes, the
information is stored locally and there is a chance that a
malicious user could modify this information in order to hide
their changes to the system. As such, it is recommended to
create a separate set of binary signatures and store them on a
read-only, root-owned directory or, preferably, on a removable
<acronym>USB</acronym> disk or remote
<application>rsync</application> server.</para>
<para>The built-in <command>mtree</command> utility can be used
to generate a specification of the contents of a directory. A
seed, or a numeric constant, is used to generate the
specification and is required to check that the specification
has not changed. This makes it possible to determine if a
file or binary has been modified. Since the seed value is
unknown by an attacker, faking or checking the checksum values
of files will be difficult to impossible. The following
example generates a set of <acronym>SHA256</acronym> hashes,
one for each system binary in <filename>/bin</filename>, and
saves those values to a hidden file in <systemitem
class="username">root</systemitem>'s home directory,
<filename>/root/.bin_chksum_mtree</filename>:</para>
<screen>&prompt.root; <userinput>mtree -s <replaceable>3483151339707503</replaceable> -c -K cksum,sha256digest -p <replaceable>/bin</replaceable> &gt; <replaceable>/root/.bin_chksum_mtree</replaceable></userinput>
&prompt.root; mtree: /bin checksum: 3427012225</screen>
<para>The <replaceable>3483151339707503</replaceable> represents
the seed. This value should be remembered, but not
shared.</para>
<para>Viewing <filename>/root/.bin_cksum_mtree</filename> should
yield output similar to the following:</para>
<programlisting># user: root
# machine: dreadnaught
# tree: /bin
# date: Mon Feb 3 10:19:53 2014
# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=none
. type=dir mode=0755 nlink=2 size=1024 \
time=1380277977.000000000
\133 nlink=2 size=11704 time=1380277977.000000000 \
cksum=484492447 \
sha256digest=6207490fbdb5ed1904441fbfa941279055c3e24d3a4049aeb45094596400662a
cat size=12096 time=1380277975.000000000 cksum=3909216944 \
sha256digest=65ea347b9418760b247ab10244f47a7ca2a569c9836d77f074e7a306900c1e69
chflags size=8168 time=1380277975.000000000 cksum=3949425175 \
sha256digest=c99eb6fc1c92cac335c08be004a0a5b4c24a0c0ef3712017b12c89a978b2dac3
chio size=18520 time=1380277975.000000000 cksum=2208263309 \
sha256digest=ddf7c8cb92a58750a675328345560d8cc7fe14fb3ccd3690c34954cbe69fc964
chmod size=8640 time=1380277975.000000000 cksum=2214429708 \
sha256digest=a435972263bf814ad8df082c0752aa2a7bdd8b74ff01431ccbd52ed1e490bbe7</programlisting>
<para>The machine's hostname, the date and time the
specification was created, and the name of the user who
created the specification are included in this report. There
is a checksum, size, time, and <acronym>SHA</acronym>256
digest for each binary in the directory.</para>
<para>To verify that the binary signatures have not changed,
compare the current contents of the directory to the
previously generated specification, and save the results to a
file. This command requires the seed that was used to
generate the original specification:</para>
<screen>&prompt.root; <userinput>mtree -s <replaceable>3483151339707503</replaceable> -p <replaceable>/bin</replaceable> &lt; <replaceable>/root/.bin_chksum_mtree</replaceable> &gt;&gt; <replaceable>/root/.bin_chksum_output</replaceable></userinput>
&prompt.root; mtree: /bin checksum: 3427012225</screen>
<para>This should produce the same checksum for
<filename>/bin</filename> that was produced when the
specification was created. If no changes have occurred to the
binaries in this directory, the
<filename>/root/.bin_chksum_output</filename> output file will
be empty. To simulate a change, change the date on
<filename>/bin/cat</filename> using <command>touch</command>
and run the verification command again:</para>
<screen>&prompt.root; <userinput>touch /bin/cat</userinput>
&prompt.root; <userinput>mtree -s <replaceable>3483151339707503</replaceable> -p <replaceable>/bin</replaceable> &lt; <replaceable>/root/.bin_chksum_mtree</replaceable> &gt;&gt; <replaceable>/root/.bin_chksum_output</replaceable></userinput>
&prompt.root; <userinput>more /root/.bin_chksum_output</userinput>
cat changed
modification time expected Fri Sep 27 06:32:55 2013 found Mon Feb 3 10:28:43 2014</screen>
<para>It is recommended to create specifications for the
directories which contain binaries and configuration files, as
well as any directories containing sensitive data. Typically,
specifications are created for <filename>/bin</filename>,
<filename>/sbin</filename>, <filename>/usr/bin</filename>,
<filename>/usr/sbin</filename>,
<filename>/usr/local/bin</filename>,
<filename>/etc</filename>, and
<filename>/usr/local/etc</filename>.</para>
<para>More advanced <acronym>IDS</acronym> systems exist, such
as <package>security/aide</package>. In most cases,
<command>mtree</command> provides the functionality
administrators need. It is important to keep the seed value
and the checksum output hidden from malicious users. More
information about <command>mtree</command> can be found in
&man.mtree.8;.</para>
</sect2>
<sect2 xml:id="security-tuning">
<title>System Tuning for Security</title>
<para>In &os;, many system features can be tuned using
<command>sysctl</command>. A few of the security features
which can be tuned to prevent Denial of Service
(<acronym>DoS</acronym>) attacks will be covered in this
section. More information about using
<command>sysctl</command>, including how to temporarily change
values and how to make the changes permanent after testing,
can be found in <xref
linkend="configtuning-sysctl"/>.</para>
<note>
<para>Any time a setting is changed with
<command>sysctl</command>, the chance to cause undesired
harm is increased, affecting the availability of the system.
All changes should be monitored and, if possible, tried on a
testing system before being used on a production
system.</para>
</note>
<para>By default, the &os; kernel boots with a security level of
<literal>-1</literal>. This is called <quote>insecure
mode</quote> because immutable file flags may be turned off
and all devices may be read from or written to. The security
level will remain at <literal>-1</literal> unless it is
altered through <command>sysctl</command> or by a setting in
the startup scripts. The security level may be increased
during system startup by setting
<varname>kern_securelevel_enable</varname> to
<literal>YES</literal> in <filename>/etc/rc.conf</filename>,
and the value of <varname>kern_securelevel</varname> to the
desired security level. See &man.security.7; and &man.init.8;
for more information on these settings and the available
security levels.</para>
<warning>
<para>Increasing the <varname>securelevel</varname> can break
<application>Xorg</application> and cause other issues. Be
prepared to do some debugging.</para>
</warning>
<para>The <varname>net.inet.tcp.blackhole</varname> and
<varname>net.inet.udp.blackhole</varname> settings can be used
to drop incoming <acronym>SYN</acronym> packets on closed
ports without sending a return <acronym>RST</acronym>
response. The default behavior is to return an
<acronym>RST</acronym> to show a port is closed. Changing the
default provides some level of protection against ports scans,
which are used to determine which applications are running on
a system. Set <varname>net.inet.tcp.blackhole</varname> to
<literal>2</literal> and
<varname>net.inet.udp.blackhole</varname> to
<literal>1</literal>. Refer to &man.blackhole.4; for more
information about these settings.</para>
<para>The <varname>net.inet.icmp.drop_redirect</varname> and
<varname>net.inet.ip.redirect</varname> settings help prevent
against <firstterm>redirect attacks</firstterm>. A redirect
attack is a type of <acronym>DoS</acronym> which sends mass
numbers of <acronym>ICMP</acronym> type 5 packets. Since
these packets are not required, set
<varname>net.inet.icmp.drop_redirect</varname> to
<literal>1</literal> and set
<varname>net.inet.ip.redirect</varname> to
<literal>0</literal>.</para>
<para>Source routing is a method for detecting and accessing
non-routable addresses on the internal network. This should
be disabled as non-routable addresses are normally not
routable on purpose. To disable this feature, set
<varname>net.inet.ip.sourceroute</varname> and
<varname>net.inet.ip.accept_sourceroute</varname> to
<literal>0</literal>.</para>
<para>When a machine on the network needs to send messages to
all hosts on a subnet, an <acronym>ICMP</acronym> echo request
message is sent to the broadcast address. However, there is
no reason for an external host to perform such an action. To
reject all external broadcast requests, set
<varname>net.inet.icmp.bmcastecho</varname> to
<literal>0</literal>.</para>
<para>Some additional settings are documented in
&man.security.7;.</para>
</sect2>
</sect1>
<sect1 xml:id="one-time-passwords">
<title>One-time Passwords</title>
<indexterm><primary>one-time passwords</primary></indexterm>
<indexterm>
<primary>security</primary>
<secondary>one-time passwords</secondary>
</indexterm>
<para>By default, &os; includes support for One-time Passwords In
Everything (<acronym>OPIE</acronym>). <acronym>OPIE</acronym>
is designed to prevent replay attacks, in which an attacker
discovers a user's password and uses it to access a system.
Since a password is only used once in <acronym>OPIE</acronym>, a
discovered password is of little use to an attacker.
<acronym>OPIE</acronym> uses a secure hash and a
challenge/response system to manage passwords. The &os;
implementation uses the <acronym>MD5</acronym> hash by
default.</para>
<para><acronym>OPIE</acronym> uses three different types of
passwords. The first is the usual &unix; or Kerberos password.
The second is the one-time password which is generated by
<command>opiekey</command>. The third type of password is the
<quote>secret password</quote> which is used to generate
one-time passwords. The secret password has nothing to do with,
and should be different from, the &unix; password.</para>
<para>There are two other pieces of data that are important to
<acronym>OPIE</acronym>. One is the <quote>seed</quote> or
<quote>key</quote>, consisting of two letters and five digits.
The other is the <quote>iteration count</quote>, a number
between 1 and 100. <acronym>OPIE</acronym> creates the one-time
password by concatenating the seed and the secret password,
applying the <acronym>MD5</acronym> hash as many times as
specified by the iteration count, and turning the result into
six short English words which represent the one-time password.
The authentication system keeps 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 <literal>1</literal>,
<acronym>OPIE</acronym> must be reinitialized.</para>
<para>There are a few programs involved in this process. A
one-time password, or a consecutive list of one-time passwords,
is generated by passing an iteration count, a seed, and a secret
password to &man.opiekey.1;. In addition to initializing
<acronym>OPIE</acronym>, &man.opiepasswd.1; is used to change
passwords, iteration counts, or seeds. The relevant credential
files in <filename>/etc/opiekeys</filename> are examined by
&man.opieinfo.1; which prints out the invoking user's current
iteration count and seed.</para>
<para>This section describes four different sorts of operations.
The first is how to set up one-time-passwords for the first time
over a secure connection. The second is how to use
<command>opiepasswd</command> over an insecure connection. The
third is how to log in over an insecure connection. The fourth
is how to generate a number of keys which can be written down or
printed out to use at insecure locations.</para>
<sect2>
<title>Initializing <acronym>OPIE</acronym></title>
<para>To initialize <acronym>OPIE</acronym> for the first time,
run this command from a secure location:</para>
<screen>&prompt.user; <userinput>opiepasswd -c</userinput>
Adding unfurl:
Only use this method from the console; NEVER from remote. If you are using
telnet, xterm, or a dial-in, type ^C now or exit with no password.
Then run opiepasswd without the -c parameter.
Using MD5 to compute responses.
Enter new secret pass phrase:
Again new secret pass phrase:
ID unfurl OTP key is 499 to4268
MOS MALL GOAT ARM AVID COED</screen>
<para>The <option>-c</option> sets console mode which assumes
that the command is being run from a secure location, such as
a computer under the user's control or a
<acronym>SSH</acronym> session to a computer under the user's
control.</para>
<para>When prompted, enter the secret password which will be
used to generate the one-time login keys. This password
should be difficult to guess and should be different than the
password which is associated with the user's login account.
It must be between 10 and 127 characters long. Remember this
password.</para>
<para>The <literal>ID</literal> line lists the login name
(<literal>unfurl</literal>), default iteration count
(<literal>499</literal>), and default seed
(<literal>to4268</literal>). When logging in, the system will
remember these parameters and display them, meaning that they
do not have to be memorized. The last line lists the
generated one-time password which corresponds to those
parameters and the secret password. At the next login, use
this one-time password.</para>
</sect2>
<sect2>
<title>Insecure Connection Initialization</title>
<para>To initialize or change the secret password on an
insecure system, a secure connection is needed to some place
where <command>opiekey</command> can be run. This might be a
shell prompt on a trusted machine. An iteration count is
needed, where 100 is probably a good value, and the seed can
either be specified or the randomly-generated one used. On
the insecure connection, the machine being initialized, use
&man.opiepasswd.1;:</para>
<screen>&prompt.user; <userinput>opiepasswd</userinput>
Updating unfurl:
You need the response from an OTP generator.
Old secret pass phrase:
otp-md5 498 to4268 ext
Response: GAME GAG WELT OUT DOWN CHAT
New secret pass phrase:
otp-md5 499 to4269
Response: LINE PAP MILK NELL BUOY TROY
ID mark OTP key is 499 gr4269
LINE PAP MILK NELL BUOY TROY</screen>
<para>To accept the default seed, press <keycap>Return</keycap>.
Before entering an access password, move over to the secure
connection and give it the same parameters:</para>
<screen>&prompt.user; <userinput>opiekey 498 to4268</userinput>
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase:
GAME GAG WELT OUT DOWN CHAT</screen>
<para>Switch back over to the insecure connection, and copy the
generated one-time password over to the relevant
program.</para>
</sect2>
<sect2>
<title>Generating a Single One-time Password</title>
<para>After initializing <acronym>OPIE</acronym> and logging in,
a prompt like this will be displayed:</para>
<screen>&prompt.user; <userinput>telnet example.com</userinput>
Trying 10.0.0.1...
Connected to example.com
Escape character is '^]'.
FreeBSD/i386 (example.com) (ttypa)
login: <userinput>&lt;username&gt;</userinput>
otp-md5 498 gr4269 ext
Password: </screen>
<para>The <acronym>OPIE</acronym> prompts provides a useful
feature. If <keycap>Return</keycap> is pressed at the
password prompt, the prompt will turn echo on and display
what is typed. This can be useful when attempting to type in
a password by hand from a printout.</para>
<indexterm><primary>MS-DOS</primary></indexterm>
<indexterm><primary>Windows</primary></indexterm>
<indexterm><primary>MacOS</primary></indexterm>
<para>At this point, generate the one-time password to answer
this login prompt. This must be done on a trusted system
where it is safe to run &man.opiekey.1;. There are versions
of this command for &windows;, &macos; and &os;. This command
needs the iteration count and the seed as command line
options. Use cut-and-paste from the login prompt on the
machine being logged in to.</para>
<para>On the trusted system:</para>
<screen>&prompt.user; <userinput>opiekey 498 to4268</userinput>
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase:
GAME GAG WELT OUT DOWN CHAT</screen>
<para>Once the one-time password is generated, continue to log
in.</para>
</sect2>
<sect2>
<title>Generating Multiple One-time Passwords</title>
<para>Sometimes there is no access to a trusted machine or
secure connection. In this case, it is possible to use
&man.opiekey.1; to generate a number of one-time passwords
beforehand. For example:</para>
<screen>&prompt.user; <userinput>opiekey -n 5 30 zz99999</userinput>
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase: <userinput>&lt;secret password&gt;</userinput>
26: JOAN BORE FOSS DES NAY QUIT
27: LATE BIAS SLAY FOLK MUCH TRIG
28: SALT TIN ANTI LOON NEAL USE
29: RIO ODIN GO BYE FURY TIC
30: GREW JIVE SAN GIRD BOIL PHI</screen>
<para>The <option>-n 5</option> requests five keys in sequence,
and <option>30</option> specifies what the last iteration
number should be. Note that these are printed out in
<emphasis>reverse</emphasis> order of use. The really
paranoid might want to write the results down by hand;
otherwise, print the list. Each line shows both the iteration
count and the one-time password. Scratch off the passwords as
they are used.</para>
</sect2>
<sect2>
<title>Restricting Use of &unix; Passwords</title>
<para><acronym>OPIE</acronym> can restrict the use of &unix;
passwords based on the IP address of a login session. The
relevant file is <filename>/etc/opieaccess</filename>, which
is present by default. Refer to &man.opieaccess.5; for more
information on this file and which security considerations to
be aware of when using it.</para>
<para>Here is a sample <filename>opieaccess</filename>:</para>
<programlisting>permit 192.168.0.0 255.255.0.0</programlisting>
<para>This line allows users whose IP source address (which is
vulnerable to spoofing) matches the specified value and mask,
to use &unix; passwords at any time.</para>
<para>If no rules in <filename>opieaccess</filename> are
matched, the default is to deny non-<acronym>OPIE</acronym>
logins.</para>
</sect2>
</sect1>
<sect1 xml:id="tcpwrappers">
<info>
<title>TCP Wrapper</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written
by </contrib></author>
</authorgroup>
</info>
<indexterm><primary>TCP Wrapper</primary></indexterm>
<para><application>TCP Wrapper</application> is a host-based
access control system which extends the abilities of <xref
linkend="network-inetd"/>. It can be configured to provide
logging support, return messages, and connection restrictions
for the server daemons under the control of
<application>inetd</application>. Refer to &man.tcpd.8; for
more information about
<application>TCP Wrapper</application> and its features.</para>
<para><application>TCP Wrapper</application> should not be
considered a replacement for a properly configured firewall.
Instead, <application>TCP Wrapper</application> should be used
in conjunction with a firewall and other security enhancements
in order to provide another layer of protection in the
implementation of a security policy.</para>
<sect2>
<title>Initial Configuration</title>
<para>To enable <application>TCP Wrapper</application> in &os;,
add the following lines to
<filename>/etc/rc.conf</filename>:</para>
<programlisting>inetd_enable="YES"
inetd_flags="-Ww"</programlisting>
<para>Then, properly configure
<filename>/etc/hosts.allow</filename>.</para>
<note>
<para>Unlike other implementations of
<application>TCP Wrapper</application>, the use of
<filename>hosts.deny</filename> is deprecated in &os;. All
configuration options should be placed in
<filename>/etc/hosts.allow</filename>.</para>
</note>
<para>In the simplest configuration, daemon connection policies
are set to either permit or block, depending on the options in
<filename>/etc/hosts.allow</filename>. The default
configuration in &os; is to allow all connections to the
daemons started with <application>inetd</application>.</para>
<para>Basic configuration usually takes the form of
<literal>daemon : address : action</literal>, where
<literal>daemon</literal> is the daemon which
<application>inetd</application> started,
<literal>address</literal> is a valid hostname,
<acronym>IP</acronym> address, or an IPv6 address enclosed in
brackets ([&nbsp;]), and <literal>action</literal> is either
<literal>allow</literal> or <literal>deny</literal>.
<application>TCP Wrapper</application> uses a first rule match
semantic, meaning that the configuration file is scanned from
the beginning for a matching rule. When a match is found, the
rule is applied and the search process stops.</para>
<para>For example, to allow <acronym>POP</acronym>3 connections
via the <package>mail/qpopper</package> daemon, the following
lines should be appended to
<filename>hosts.allow</filename>:</para>
<programlisting># This line is required for POP3 connections:
qpopper : ALL : allow</programlisting>
<para>Whenever this file is edited, restart
<application>inetd</application>:</para>
<screen>&prompt.root; <userinput>service inetd restart</userinput></screen>
</sect2>
<sect2>
<title>Advanced Configuration</title>
<para><application>TCP Wrapper</application> provides advanced
options to allow more control over the way connections are
handled. In some cases, it may be appropriate to return a
comment to certain hosts or daemon connections. In other
cases, a log entry should be recorded or an email sent to the
administrator. Other situations may require the use of a
service for local connections only. This is all possible
through the use of configuration options known as wildcards,
expansion characters, and external command execution.</para>
<para>Suppose that a situation occurs where a connection should
be denied yet a reason should be sent to the host who
attempted to establish that connection. That action is
possible with <option>twist</option>. When a connection
attempt is made, <option>twist</option> executes a shell
command or script. An example exists in
<filename>hosts.allow</filename>:</para>
<programlisting># The rest of the daemons are protected.
ALL : ALL \
: severity auth.info \
: twist /bin/echo "You are not welcome to use %d from %h."</programlisting>
<para>In this example, the message <quote>You are not allowed to
use <replaceable>daemon name</replaceable> from
<replaceable>hostname</replaceable>.</quote> will be
returned for any daemon not configured in
<filename>hosts.allow</filename>. This is useful for sending
a reply back to the connection initiator right after the
established connection is dropped. Any message returned
<emphasis>must</emphasis> be wrapped in quote
(<literal>"</literal>) characters.</para>
<warning>
<para>It may be possible to launch a denial of service attack
on the server if an attacker floods these daemons with
connection requests.</para>
</warning>
<para>Another possibility is to use <option>spawn</option>.
Like <option>twist</option>, <option>spawn</option> implicitly
denies the connection and may be used to run external shell
commands or scripts. Unlike <option>twist</option>,
<option>spawn</option> will not send a reply back to the host
who established the connection. For example, consider the
following configuration:</para>
<programlisting># We do not allow connections from example.com:
ALL : .example.com \
: spawn (/bin/echo %a from %h attempted to access %d &gt;&gt; \
/var/log/connections.log) \
: deny</programlisting>
<para>This will deny all connection attempts from <systemitem
class="fqdomainname">*.example.com</systemitem> and log the
hostname, <acronym>IP</acronym> address, and the daemon to
which access was attempted to
<filename>/var/log/connections.log</filename>. This example
uses the substitution characters <literal>%a</literal> and
<literal>%h</literal>. Refer to &man.hosts.access.5; for the
complete list.</para>
<para>To match every instance of a daemon, domain, or
<acronym>IP</acronym> address, use <literal>ALL</literal>.
Another wildcard is <literal>PARANOID</literal> which may be
used to match any host which provides an <acronym>IP</acronym>
address that may be forged because the <acronym>IP</acronym>
address differs from its resolved hostname. In this example,
all connection requests to <application>Sendmail</application>
which have an <acronym>IP</acronym> address that varies from
its hostname will be denied:</para>
<programlisting># Block possibly spoofed requests to sendmail:
sendmail : PARANOID : deny</programlisting>
<caution>
<para>Using the <literal>PARANOID</literal> wildcard will
result in denied connections if the client or server has a
broken <acronym>DNS</acronym> setup.</para>
</caution>
<para>To learn more about wildcards and their associated
functionality, refer to &man.hosts.access.5;.</para>
<note>
<para>When adding new configuration lines, make sure that any
unneeded entries for that daemon are commented out in
<filename>hosts.allow</filename>.</para>
</note>
</sect2>
</sect1>
<sect1 xml:id="kerberos5">
<info>
<title><application>Kerberos</application></title>
<authorgroup>
<author>
<personname>
<firstname>Tillman</firstname>
<surname>Hodgson</surname>
</personname>
<contrib>Contributed by </contrib>
</author>
</authorgroup>
<authorgroup>
<author>
<personname>
<firstname>Mark</firstname>
<surname>Murray</surname>
</personname>
<contrib>Based on a contribution by </contrib>
</author>
</authorgroup>
</info>
<para><application>Kerberos</application> is a network
authentication protocol which was originally created by the
Massachusetts Institute of Technology (<acronym>MIT</acronym>)
as a way to securely provide authentication across a potentially
hostile network. The <application>Kerberos</application>
protocol uses strong cryptography so that both a client and
server can prove their identity without sending any unencrypted
secrets over the network. <application>Kerberos</application>
can be described as an identity-verifying proxy system and as a
trusted third-party authentication system. After a user
authenticates with <application>Kerberos</application>, their
communications can be encrypted to assure privacy and data
integrity.</para>
<para>The only function of <application>Kerberos</application> is
to provide the secure authentication of users and servers on the
network. It does not provide authorization or auditing
functions. It is recommended that
<application>Kerberos</application> be used with other security
methods which provide authorization and audit services.</para>
<para>The current version of the protocol is version 5, described
in <acronym>RFC</acronym>&nbsp;4120. Several free
implementations of this protocol are available, covering a wide
range of operating systems. <acronym>MIT</acronym> continues to
develop their <application>Kerberos</application> package. It
is commonly used in the <acronym>US</acronym> as a cryptography
product, and has historically been subject to
<acronym>US</acronym> export regulations. In &os;,
<acronym>MIT</acronym> <application>Kerberos</application> is
available as the <package>security/krb5</package> package or
port. The Heimdal <application>Kerberos</application>
implementation was explicitly developed outside of the
<acronym>US</acronym> to avoid export regulations. The Heimdal
<application>Kerberos</application> distribution is included in
the base &os; installation, and another distribution with more
configurable options is available as
<package>security/heimdal</package> in the Ports
Collection.</para>
<para>In <application>Kerberos</application> users and services
are identified as <quote>principals</quote> which are contained
within an administrative grouping, called a
<quote>realm</quote>. A typical user principal would be of the
form
<literal><replaceable>user</replaceable>@<replaceable>REALM</replaceable></literal>
(realms are traditionally uppercase).</para>
<para>This section provides a guide on how to set up
<application>Kerberos</application> using the Heimdal
distribution included in &os;.</para>
<para>For purposes of demonstrating a
<application>Kerberos</application> installation, the name
spaces will be as follows:</para>
<itemizedlist>
<listitem>
<para>The <acronym>DNS</acronym> domain (zone) will be
<systemitem
class="fqdomainname">example.org</systemitem>.</para>
</listitem>
<listitem>
<para>The <application>Kerberos</application> realm will be
<literal>EXAMPLE.ORG</literal>.</para>
</listitem>
</itemizedlist>
<note>
<para>Use real domain names when setting up
<application>Kerberos</application>, even if it will run
internally. This avoids <acronym>DNS</acronym> problems and
assures inter-operation with other
<application>Kerberos</application> realms.</para>
</note>
<sect2>
<title>Setting up a Heimdal <acronym>KDC</acronym></title>
<indexterm>
<primary>Kerberos5</primary>
<secondary>Key Distribution Center</secondary>
</indexterm>
<para>The Key Distribution Center (<acronym>KDC</acronym>) is
the centralized authentication service that
<application>Kerberos</application> provides, the
<quote>trusted third party</quote> of the system. It is the
computer that issues <application>Kerberos</application>
tickets, which are used for clients to authenticate to
servers. Because the <acronym>KDC</acronym> is considered
trusted by all other computers in the
<application>Kerberos</application> realm, it has heightened
security concerns. Direct access to the KDC should be
limited.</para>
<para>While running a <acronym>KDC</acronym> requires few
computing resources, a dedicated machine acting only as a
<acronym>KDC</acronym> is recommended for security
reasons.</para>
<para>To begin, install the <package>security/heimdal</package>
package as follows:</para>
<screen>&prompt.root; <userinput>pkg install heimdal</userinput></screen>
<para>Next, update <filename>/etc/rc.conf</filename> using
<command>sysrc</command> as follows:</para>
<screen>&prompt.root; <userinput>sysrc kdc_enable=yes</userinput>
&prompt.root; <userinput>sysrc kadmind_enable=yes</userinput></screen>
<para>Next, edit <filename>/etc/krb5.conf</filename> as
follows:</para>
<programlisting>[libdefaults]
default_realm = <replaceable>EXAMPLE.ORG</replaceable>
[realms]
<replaceable>EXAMPLE.ORG</replaceable> = {
kdc = <replaceable>kerberos.example.org</replaceable>
admin_server = <replaceable>kerberos.example.org</replaceable>
}
[domain_realm]
<replaceable>.example.org</replaceable> = <replaceable>EXAMPLE.ORG</replaceable></programlisting>
<para>In this example, the <acronym>KDC</acronym> will use the
fully-qualified hostname <systemitem
class="fqdomainname">kerberos.example.org</systemitem>. The
hostname of the KDC must be resolvable in the
<acronym>DNS</acronym>.</para>
<para><application>Kerberos</application> can also use the
<acronym>DNS</acronym> to locate KDCs, instead of a
<literal>[realms]</literal> section in
<filename>/etc/krb5.conf</filename>. For large organizations
that have their own <acronym>DNS</acronym> servers, the above
example could be trimmed to:</para>
<programlisting>[libdefaults]
default_realm = <replaceable>EXAMPLE.ORG</replaceable>
[domain_realm]
<replaceable>.example.org</replaceable> = <replaceable>EXAMPLE.ORG</replaceable></programlisting>
<para>With the following lines being included in the
<systemitem class="fqdomainname">example.org</systemitem> zone
file:</para>
<programlisting>_kerberos._udp IN SRV 01 00 88 <replaceable>kerberos.example.org</replaceable>.
_kerberos._tcp IN SRV 01 00 88 <replaceable>kerberos.example.org</replaceable>.
_kpasswd._udp IN SRV 01 00 464 <replaceable>kerberos.example.org</replaceable>.
_kerberos-adm._tcp IN SRV 01 00 749 <replaceable>kerberos.example.org</replaceable>.
_kerberos IN TXT <replaceable>EXAMPLE.ORG</replaceable></programlisting>
<note>
<para>In order for clients to be able to find the
<application>Kerberos</application> services, they
<emphasis>must</emphasis> have either
a fully configured <filename>/etc/krb5.conf</filename> or a
minimally configured <filename>/etc/krb5.conf</filename>
<emphasis>and</emphasis> a properly configured
<acronym>DNS</acronym> server.</para>
</note>
<para>Next, create the <application>Kerberos</application>
database which contains the keys of all principals (users and
hosts) encrypted with a master password. It is not required
to remember this password as it will be stored in
<filename>/var/heimdal/m-key</filename>; it would be
reasonable to use a 45-character random password for this
purpose. To create the master key, run
<command>kstash</command> and enter a password:</para>
<screen>&prompt.root; <userinput>kstash</userinput>
Master key: <userinput><replaceable>xxxxxxxxxxxxxxxxxxxxxxx</replaceable></userinput>
Verifying password - Master key: <userinput><replaceable>xxxxxxxxxxxxxxxxxxxxxxx</replaceable></userinput></screen>
<para>Once the master key has been created, the database should
be initialized. The <application>Kerberos</application>
administrative tool &man.kadmin.8; can be used on the KDC in a
mode that operates directly on the database, without using the
&man.kadmind.8; network service, as
<command>kadmin -l</command>. This resolves the
chicken-and-egg problem of trying to connect to the database
before it is created. At the <command>kadmin</command>
prompt, use <command>init</command> to create the realm's
initial database:</para>
<screen>&prompt.root; <userinput>kadmin -l</userinput>
kadmin&gt; <userinput>init <replaceable>EXAMPLE.ORG</replaceable></userinput>
Realm max ticket life [unlimited]:</screen>
<para>Lastly, while still in <command>kadmin</command>, create
the first principal using <command>add</command>. Stick to
the default options for the principal for now, as these can be
changed later with <command>modify</command>.
Type <literal>?</literal> at the prompt to see the available
options.</para>
<screen>kadmin&gt; <userinput>add tillman</userinput>
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Password: <userinput><replaceable>xxxxxxxx</replaceable></userinput>
Verifying password - Password: <userinput><replaceable>xxxxxxxx</replaceable></userinput></screen>
<para>Next, start the <acronym>KDC</acronym> services by
running:</para>
<screen>&prompt.root; <userinput>service kdc start</userinput>
&prompt.root; <userinput>service kadmind start</userinput></screen>
<para>While there will not be any kerberized daemons running at
this point, it is possible to confirm that the
<acronym>KDC</acronym> is functioning by obtaining a ticket
for the principal that was just created:</para>
<screen>&prompt.user; <userinput>kinit <replaceable>tillman</replaceable></userinput>
tillman@EXAMPLE.ORG's Password:</screen>
<para>Confirm that a ticket was successfully obtained using
<command>klist</command>:</para>
<screen>&prompt.user; <userinput>klist</userinput>
Credentials cache: FILE:/tmp/krb5cc_1001
Principal: tillman@EXAMPLE.ORG
Issued Expires Principal
Aug 27 15:37:58 2013 Aug 28 01:37:58 2013 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG</screen>
<para>The temporary ticket can be destroyed when the test is
finished:</para>
<screen>&prompt.user; <userinput>kdestroy</userinput></screen>
</sect2>
<sect2>
<title>Configuring a Server to Use
<application>Kerberos</application></title>
<indexterm>
<primary>Kerberos5</primary>
<secondary>enabling services</secondary>
</indexterm>
<para>The first step in configuring a server to use
<application>Kerberos</application> authentication is to
ensure that it has the correct configuration in
<filename>/etc/krb5.conf</filename>. The version from the
<acronym>KDC</acronym> can be used as-is, or it can be
regenerated on the new system.</para>
<para>Next, create <filename>/etc/krb5.keytab</filename> on the
server. This is the main part of <quote>Kerberizing</quote> a
service &mdash; it corresponds to generating a secret shared
between the service and the <acronym>KDC</acronym>. The
secret is a cryptographic key, stored in a
<quote>keytab</quote>. The keytab contains the server's host
key, which allows it and the <acronym>KDC</acronym> to verify
each others' identity. It must be transmitted to the server
in a secure fashion, as the security of the server can be
broken if the key is made public. Typically, the
<filename>keytab</filename> is generated on an administrator's
trusted machine using <command>kadmin</command>, then securely
transferred to the server, e.g., with &man.scp.1;; it can also
be created directly on the server if that is consistent with
the desired security policy. It is very important that the
keytab is transmitted to the server in a secure fashion: if
the key is known by some other party, that party can
impersonate any user to the server! Using
<command>kadmin</command> on the server directly is
convenient, because the entry for the host principal in the
<acronym>KDC</acronym> database is also created using
<command>kadmin</command>.</para>
<para>Of course, <command>kadmin</command> is a kerberized
service; a <application>Kerberos</application> ticket is
needed to authenticate to the network service, but to ensure
that the user running <command>kadmin</command> is actually
present (and their session has not been hijacked),
<command>kadmin</command> will prompt for the password to get
a fresh ticket. The principal authenticating to the kadmin
service must be permitted to use the <command>kadmin</command>
interface, as specified in
<filename>/var/heimdal/kadmind.acl</filename>. See the
section titled <quote>Remote administration</quote> in
<command>info heimdal</command> for details on designing
access control lists. Instead of enabling remote
<command>kadmin</command> access, the administrator could
securely connect to the <acronym>KDC</acronym> via the local
console or &man.ssh.1;, and perform administration locally
using <command>kadmin -l</command>.</para>
<para>After installing <filename>/etc/krb5.conf</filename>,
use <command>add --random-key</command> in
<command>kadmin</command>. This adds the server's host
principal to the database, but does not extract a copy of the
host principal key to a keytab. To generate the keytab, use
<command>ext</command> to extract the server's host principal
key to its own keytab:</para>
<screen>&prompt.root; <userinput>kadmin</userinput>
kadmin&gt;<userinput> add --random-key host/myserver.example.org</userinput>
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin&gt;<userinput> ext_keytab <replaceable>host/myserver.example.org</replaceable></userinput>
kadmin&gt;<userinput> exit</userinput></screen>
<para>Note that <command>ext_keytab</command> stores the
extracted key in <filename>/etc/krb5.keytab</filename> by
default. This is good when being run on the server being
kerberized, but the <command>--keytab
<replaceable>path/to/file</replaceable></command> argument
should be used when the keytab is being extracted
elsewhere:</para>
<screen>&prompt.root; <userinput>kadmin</userinput>
kadmin&gt;<userinput> ext_keytab --keytab=/tmp/example.keytab <replaceable>host/myserver.example.org</replaceable></userinput>
kadmin&gt;<userinput> exit</userinput></screen>
<para>The keytab can then be securely copied to the server
using &man.scp.1; or a removable media. Be sure to specify a
non-default keytab name to avoid inserting unneeded keys into
the system's keytab.</para>
<para>At this point, the server can read encrypted messages from
the <acronym>KDC</acronym> using its shared key, stored in
<filename>krb5.keytab</filename>. It is now ready for the
<application>Kerberos</application>-using services to be
enabled. One of the most common such services is
&man.sshd.8;, which supports
<application>Kerberos</application> via the
<acronym>GSS-API</acronym>. In
<filename>/etc/ssh/sshd_config</filename>, add the
line:</para>
<programlisting>GSSAPIAuthentication yes</programlisting>
<para>After making this change, &man.sshd.8; must be restarted
for the new configuration to take effect:
<command>service sshd restart</command>.</para>
</sect2>
<sect2>
<title>Configuring a Client to Use
<application>Kerberos</application></title>
<indexterm>
<primary>Kerberos5</primary>
<secondary>configure clients</secondary>
</indexterm>
<para>As it was for the server, the client requires
configuration in <filename>/etc/krb5.conf</filename>. Copy
the file in place (securely) or re-enter it as needed.</para>
<para>Test the client by using <command>kinit</command>,
<command>klist</command>, and <command>kdestroy</command> from
the client to obtain, show, and then delete a ticket for an
existing principal. <application>Kerberos</application>
applications should also be able to connect to
<application>Kerberos</application> enabled servers. If that
does not work but obtaining a ticket does, the problem is
likely with the server and not with the client or the
<acronym>KDC</acronym>. In the case of kerberized
&man.ssh.1;, <acronym>GSS-API</acronym> is disabled by
default, so test using <command>ssh -o
GSSAPIAuthentication=yes
<replaceable>hostname</replaceable></command>.</para>
<para>When testing a Kerberized application, try using a packet
sniffer such as <command>tcpdump</command> to confirm that no
sensitive information is sent in the clear.</para>
<para>Various <application>Kerberos</application> client
applications are available. With the advent of a bridge so
that applications using <acronym>SASL</acronym> for
authentication can use <acronym>GSS-API</acronym> mechanisms
as well, large classes of client applications can use
<application>Kerberos</application> for authentication, from
Jabber clients to <acronym>IMAP</acronym> clients.</para>
<indexterm>
<primary><filename>.k5login</filename></primary>
</indexterm>
<indexterm>
<primary><filename>.k5users</filename></primary>
</indexterm>
<para>Users within a realm typically have their
<application>Kerberos</application> principal mapped to a
local user account. Occasionally, one needs to grant access
to a local user account to someone who does not have a
matching <application>Kerberos</application> principal. For
example, <systemitem
class="username">tillman@EXAMPLE.ORG</systemitem> may need
access to the local user account <systemitem
class="username">webdevelopers</systemitem>. Other
principals may also need access to that local account.</para>
<para>The <filename>.k5login</filename> and
<filename>.k5users</filename> files, placed in a user's home
directory, can be used to solve this problem. For example, if
the following <filename>.k5login</filename> is placed in the
home directory of <systemitem
class="username">webdevelopers</systemitem>, both principals
listed will have access to that account without requiring a
shared password:</para>
<programlisting>tillman@example.org
jdoe@example.org</programlisting>
<para>Refer to &man.ksu.1; for more information about
<filename>.k5users</filename>.</para>
</sect2>
<sect2>
<title><acronym>MIT</acronym> Differences</title>
<para>The major difference between the <acronym>MIT</acronym>
and Heimdal implementations is that <command>kadmin</command>
has a different, but equivalent, set of commands and uses a
different protocol. If the <acronym>KDC</acronym> is
<acronym>MIT</acronym>, the Heimdal version of
<command>kadmin</command> cannot be used to administer the
<acronym>KDC</acronym> remotely, and vice versa.</para>
<para>Client applications may also use slightly different
command line options to accomplish the same tasks. Following
the instructions at <link
xlink:href="http://web.mit.edu/Kerberos/www/">http://web.mit.edu/Kerberos/www/</link>
is recommended. Be careful of path issues: the
<acronym>MIT</acronym> port installs into
<filename>/usr/local/</filename> by default, and the &os;
system applications run instead of the
<acronym>MIT</acronym> versions if <envar>PATH</envar> lists
the system directories first.</para>
<para>When using MIT Kerberos as a <acronym>KDC</acronym> on
&os;, the following edits should also be made to
<filename>rc.conf</filename>:</para>
<programlisting>kdc_program="/usr/local/sbin/kdc"
kadmind_program="/usr/local/sbin/kadmind"
kdc_flags=""
kdc_enable="YES"
kadmind_enable="YES"</programlisting>
</sect2>
<sect2>
<title><application>Kerberos</application> Tips, Tricks, and
Troubleshooting</title>
<para>When configuring and troubleshooting
<application>Kerberos</application>, keep the following points
in mind:</para>
<itemizedlist>
<listitem>
<para>When using either Heimdal or <acronym>MIT</acronym>
<application>Kerberos</application> from ports, ensure
that the <envar>PATH</envar> lists the port's versions of
the client applications before the system versions.</para>
</listitem>
<listitem>
<para>If all the computers in the realm do not have
synchronized time settings, authentication may fail.
<xref linkend="network-ntp"/> describes how to synchronize
clocks using <acronym>NTP</acronym>.</para>
</listitem>
<listitem>
<para>If the hostname is changed, the <systemitem
class="username">host/</systemitem> principal must be
changed and the keytab updated. This also applies to
special keytab entries like the <systemitem
class="username">HTTP/</systemitem> principal used for
Apache's <package>www/mod_auth_kerb</package>.</para>
</listitem>
<listitem>
<para>All hosts in the realm must be both forward and
reverse resolvable in <acronym>DNS</acronym> or, at a
minimum, exist in <filename>/etc/hosts</filename>. CNAMEs
will work, but the A and PTR records must be correct and
in place. The error message for unresolvable hosts is not
intuitive: <errorname>Kerberos5 refuses authentication
because Read req failed: Key table entry not
found</errorname>.</para>
</listitem>
<listitem>
<para>Some operating systems that act as clients to the
<acronym>KDC</acronym> do not set the permissions for
<command>ksu</command> to be setuid <systemitem
class="username">root</systemitem>. This means that
<command>ksu</command> does not work. This is a
permissions problem, not a <acronym>KDC</acronym>
error.</para>
</listitem>
<listitem>
<para>With <acronym>MIT</acronym>
<application>Kerberos</application>, to allow a principal
to have a ticket life longer than the default lifetime of
ten hours, use <command>modify_principal</command> at the
&man.kadmin.8; prompt to change the
<literal>maxlife</literal> of both the principal in
question and the
<systemitem class="username">krbtgt</systemitem>
principal. The principal can then use
<command>kinit -l</command> to request a ticket with a
longer lifetime.</para>
</listitem>
<listitem>
<para>When running a packet sniffer on the
<acronym>KDC</acronym> to aid in troubleshooting while
running <command>kinit</command> from a workstation, the
Ticket Granting Ticket (<acronym>TGT</acronym>) is sent
immediately, even before the password is typed. This is
because the <application>Kerberos</application> server
freely transmits a <acronym>TGT</acronym> to any
unauthorized request. However, every
<acronym>TGT</acronym> is encrypted in a key derived from
the user's password. When a user types their password, it
is not sent to the <acronym>KDC</acronym>, it is instead
used to decrypt the <acronym>TGT</acronym> that
<command>kinit</command> already obtained. If the
decryption process results in a valid ticket with a valid
time stamp, the user has valid
<application>Kerberos</application> credentials. These
credentials include a session key for establishing secure
communications with the
<application>Kerberos</application> server in the future,
as well as the actual <acronym>TGT</acronym>, which is
encrypted with the <application>Kerberos</application>
server's own key. This second layer of encryption allows
the <application>Kerberos</application> server to verify
the authenticity of each <acronym>TGT</acronym>.</para>
</listitem>
<listitem>
<para>Host principals can have a longer ticket lifetime. If
the user principal has a lifetime of a week but the host
being connected to has a lifetime of nine hours, the user
cache will have an expired host principal and the ticket
cache will not work as expected.</para>
</listitem>
<listitem>
<para>When setting up <filename>krb5.dict</filename> to
prevent specific bad passwords from being used as
described in &man.kadmind.8;, remember that it only
applies to principals that have a password policy assigned
to them. The format used in
<filename>krb5.dict</filename> is one string per line.
Creating a symbolic link to
<filename>/usr/share/dict/words</filename> might be
useful.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Mitigating <application>Kerberos</application>
Limitations</title>
<indexterm>
<primary>Kerberos5</primary>
<secondary>limitations and shortcomings</secondary>
</indexterm>
<para>Since <application>Kerberos</application> is an all or
nothing approach, every service enabled on the network must
either be modified to work with
<application>Kerberos</application> or be otherwise secured
against network attacks. This is to prevent user credentials
from being stolen and re-used. An example is when
<application>Kerberos</application> is enabled on all remote
shells but the non-Kerberized <acronym>POP3</acronym> mail
server sends passwords in plain text.</para>
<para>The <acronym>KDC</acronym> is a single point of failure.
By design, the <acronym>KDC</acronym> must be as secure as its
master password database. The <acronym>KDC</acronym> should
have absolutely no other services running on it and should be
physically secure. The danger is high because
<application>Kerberos</application> stores all passwords
encrypted with the same master key which is stored as a file
on the <acronym>KDC</acronym>.</para>
<para>A compromised master key is not quite as bad as one might
fear. The master key is only used to encrypt the
<application>Kerberos</application> database and as a seed for
the random number generator. As long as access to the
<acronym>KDC</acronym> is secure, an attacker cannot do much
with the master key.</para>
<para>If the <acronym>KDC</acronym> is unavailable, network
services are unusable as authentication cannot be performed.
This can be alleviated with a single master
<acronym>KDC</acronym> and one or more slaves, and with
careful implementation of secondary or fall-back
authentication using <acronym>PAM</acronym>.</para>
<para><application>Kerberos</application> allows users, hosts
and services to authenticate between themselves. It does not
have a mechanism to authenticate the
<acronym>KDC</acronym> to the users, hosts, or services. This
means that a trojanned <command>kinit</command> could record
all user names and passwords. File system integrity checking
tools like <package>security/tripwire</package> can
alleviate this.</para>
</sect2>
<sect2>
<title>Resources and Further Information</title>
<indexterm>
<primary>Kerberos5</primary>
<secondary>external resources</secondary>
</indexterm>
<itemizedlist>
<listitem>
<para><link
xlink:href="http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html">
The <application>Kerberos</application>
FAQ</link></para>
</listitem>
<listitem>
<para><link
xlink:href="http://web.mit.edu/Kerberos/www/dialogue.html">Designing
an Authentication System: a Dialog in Four
Scenes</link></para>
</listitem>
<listitem>
<para><link
xlink:href="https://www.ietf.org/rfc/rfc4120.txt">RFC
4120, The <application>Kerberos</application> Network
Authentication Service (V5)</link></para>
</listitem>
<listitem>
<para><link
xlink:href="http://web.mit.edu/Kerberos/www/"><acronym>MIT</acronym>
<application>Kerberos</application> home
page</link></para>
</listitem>
<listitem>
<para><link
xlink:href="https://github.com/heimdal/heimdal/wiki">Heimdal
<application>Kerberos</application> project wiki
page</link></para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 xml:id="openssl">
<info>
<title>OpenSSL</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>security</primary>
<secondary>OpenSSL</secondary>
</indexterm>
<para><application>OpenSSL</application> is an open source
implementation of the <acronym>SSL</acronym> and
<acronym>TLS</acronym> protocols. It provides an encryption
transport layer on top of the normal communications layer,
allowing it to be intertwined with many network applications and
services.</para>
<para>The version of <application>OpenSSL</application> included
in &os; supports the Secure Sockets Layer 3.0 (SSLv3)
and Transport Layer Security 1.0/1.1/1.2 (TLSv1/TLSv1.1/TLSv1.2)
network security
protocols and can be used as a general cryptographic
library. In &os; 12.0-RELEASE and above, OpenSSL also supports
Transport Layer Security 1.3 (TLSv1.3).</para>
<para><application>OpenSSL</application> is often used to encrypt
authentication of mail clients and to secure web based
transactions such as credit card payments. Some ports, such as
<package>www/apache24</package> and
<package>databases/postgresql11-server</package>, include a
compile option for building with
<application>OpenSSL</application>. If selected, the port will
add support using <application>OpenSSL</application> from the
base system. To instead have the port compile against
<application>OpenSSL</application> from the
<package>security/openssl</package> port, add the following to
<filename>/etc/make.conf</filename>:</para>
<programlisting>DEFAULT_VERSIONS+= ssl=openssl</programlisting>
<para>Another common use of <application>OpenSSL</application> is
to provide certificates for use with software applications.
Certificates can be used to verify the credentials of a company
or individual. If a certificate has not been signed by an
external <firstterm>Certificate Authority</firstterm>
(<acronym>CA</acronym>), such as <link
xlink:href="http://www.verisign.com">http://www.verisign.com</link>,
the application that uses the certificate will produce a
warning. There is a cost associated with obtaining a signed
certificate and using a signed certificate is not mandatory as
certificates can be self-signed. However, using an external
authority will prevent warnings and can put users at
ease.</para>
<para>This section demonstrates how to create and use certificates
on a &os; system. Refer to <xref linkend="ldap-config"/> for an
example of how to create a <acronym>CA</acronym> for signing
one's own certificates.</para>
<para>For more information about <acronym>SSL</acronym>, read the
free <link
xlink:href="https://www.feistyduck.com/books/openssl-cookbook/">OpenSSL
Cookbook</link>.</para>
<sect2>
<title>Generating Certificates</title>
<indexterm>
<primary>OpenSSL</primary>
<secondary>certificate generation</secondary>
</indexterm>
<para>To generate a certificate that will be signed by an
external <acronym>CA</acronym>, issue the following command
and input the information requested at the prompts. This
input information will be written to the certificate. At the
<literal>Common Name</literal> prompt, input the fully
qualified name for the system that will use the certificate.
If this name does not match the server, the application
verifying the certificate will issue a warning to the user,
rendering the verification provided by the certificate as
useless.</para>
<screen>&prompt.root; <userinput>openssl req -new -nodes -out req.pem -keyout cert.key -sha256 -newkey rsa:2048</userinput>
Generating a 2048 bit RSA private key
..................+++
.............................................................+++
writing new private key to 'cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:<userinput><replaceable>US</replaceable></userinput>
State or Province Name (full name) [Some-State]:<userinput><replaceable>PA</replaceable></userinput>
Locality Name (eg, city) []:<userinput><replaceable>Pittsburgh</replaceable></userinput>
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<userinput><replaceable>My Company</replaceable></userinput>
Organizational Unit Name (eg, section) []:<userinput><replaceable>Systems Administrator</replaceable></userinput>
Common Name (eg, YOUR name) []:<userinput><replaceable>localhost.example.org</replaceable></userinput>
Email Address []:<userinput><replaceable>trhodes@FreeBSD.org</replaceable></userinput>
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:<userinput><replaceable>Another Name</replaceable></userinput></screen>
<para>Other options, such as the expire time and alternate
encryption algorithms, are available when creating a
certificate. A complete list of options is described in
&man.openssl.1;.</para>
<para>This command will create two files in the current
directory. The certificate request,
<filename>req.pem</filename>, can be sent to a
<acronym>CA</acronym> who will validate the entered
credentials, sign the request, and return the signed
certificate. The second file,
<filename>cert.key</filename>, is the private key for the
certificate and should be stored in a secure location. If
this falls in the hands of others, it can be used to
impersonate the user or the server.</para>
<para>Alternately, if a signature from a <acronym>CA</acronym>
is not required, a self-signed certificate can be created.
First, generate the <acronym>RSA</acronym> key:</para>
<screen>&prompt.root; <userinput>openssl genrsa -rand -genkey -out cert.key 2048</userinput>
0 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
.............................................+++
.................................................................................................................+++
e is 65537 (0x10001)</screen>
<para>Use this key to create a self-signed certificate.
Follow the usual prompts for creating a certificate:</para>
<screen>&prompt.root; <userinput>openssl req -new -x509 -days 365 -key cert.key -out cert.crt -sha256</userinput>
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:<userinput><replaceable>US</replaceable></userinput>
State or Province Name (full name) [Some-State]:<userinput><replaceable>PA</replaceable></userinput>
Locality Name (eg, city) []:<userinput><replaceable>Pittsburgh</replaceable></userinput>
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<userinput><replaceable>My Company</replaceable></userinput>
Organizational Unit Name (eg, section) []:<userinput><replaceable>Systems Administrator</replaceable></userinput>
Common Name (e.g. server FQDN or YOUR name) []:<userinput><replaceable>localhost.example.org</replaceable></userinput>
Email Address []:<userinput><replaceable>trhodes@FreeBSD.org</replaceable></userinput></screen>
<para>This will create two new files in the current directory: a
private key file
<filename>cert.key</filename>, and the certificate itself,
<filename>cert.crt</filename>. These should be placed in a
directory, preferably under <filename>/etc/ssl/</filename>,
which is readable only by <systemitem
class="username">root</systemitem>. Permissions of
<literal>0700</literal> are appropriate for these files and
can be set using <command>chmod</command>.</para>
</sect2>
<sect2>
<title>Using Certificates</title>
<para>One use for a certificate is to encrypt connections to the
<application>Sendmail</application> mail server in order to
prevent the use of clear text authentication.</para>
<note>
<para>Some mail clients will display an error if the user has
not installed a local copy of the certificate. Refer to the
documentation included with the software for more
information on certificate installation.</para>
</note>
<para>In &os; 10.0-RELEASE and above, it is possible to create a
self-signed certificate for
<application>Sendmail</application> automatically. To enable
this, add the following lines to
<filename>/etc/rc.conf</filename>:</para>
<programlisting>sendmail_enable="YES"
sendmail_cert_create="YES"
sendmail_cert_cn="<replaceable>localhost.example.org</replaceable>"</programlisting>
<para>This will automatically create a self-signed certificate,
<filename>/etc/mail/certs/host.cert</filename>, a signing key,
<filename>/etc/mail/certs/host.key</filename>, and a
<acronym>CA</acronym> certificate,
<filename>/etc/mail/certs/cacert.pem</filename>. The
certificate will use the <literal>Common Name</literal>
specified in <option>sendmail_cert_cn</option>. After saving
the edits, restart <application>Sendmail</application>:</para>
<screen>&prompt.root; <userinput>service sendmail restart</userinput></screen>
<para>If all went well, there will be no error messages in
<filename>/var/log/maillog</filename>. For a simple test,
connect to the mail server's listening port using
<command>telnet</command>:</para>
<screen>&prompt.root; <userinput>telnet <replaceable>example.com</replaceable> 25</userinput>
Trying 192.0.34.166...
Connected to example.com.
Escape character is '^]'.
220 example.com ESMTP Sendmail 8.14.7/8.14.7; Fri, 18 Apr 2014 11:50:32 -0400 (EDT)
<userinput>ehlo <replaceable>example.com</replaceable></userinput>
250-example.com Hello example.com [192.0.34.166], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
<userinput>quit</userinput>
221 2.0.0 example.com closing connection
Connection closed by foreign host.</screen>
<para>If the <literal>STARTTLS</literal> line appears in the
output, everything is working correctly.</para>
</sect2>
</sect1>
<sect1 xml:id="ipsec">
<info>
<title><acronym>VPN</acronym> over
<acronym>IPsec</acronym></title>
<authorgroup>
<author>
<personname>
<firstname>Nik</firstname>
<surname>Clayton</surname>
</personname>
<affiliation>
<address>
<email>nik@FreeBSD.org</email>
</address>
</affiliation>
<contrib>Written by </contrib>
</author>
</authorgroup>
<authorgroup>
<author>
<personname>
<firstname>Hiten M.</firstname>
<surname>Pandya</surname>
</personname>
<affiliation>
<address>
<email>hmp@FreeBSD.org</email>
</address>
</affiliation>
<contrib>Written by </contrib>
</author>
</authorgroup>
</info>
<indexterm>
<primary><acronym>IPsec</acronym></primary>
</indexterm>
<para>Internet Protocol Security (<acronym>IPsec</acronym>) is a
set of protocols which sit on top of the Internet Protocol
(<acronym>IP</acronym>) layer. It allows two or more hosts to
communicate in a secure manner by authenticating and encrypting
each <acronym>IP</acronym> packet of a communication session.
The &os; <acronym>IPsec</acronym> network stack is based on the
<link
xlink:href="http://www.kame.net/">http://www.kame.net/</link>
implementation and supports both <acronym>IPv4</acronym> and
<acronym>IPv6</acronym> sessions.</para>
<indexterm>
<primary><acronym>IPsec</acronym></primary>
<secondary>ESP</secondary>
</indexterm>
<indexterm>
<primary><acronym>IPsec</acronym></primary>
<secondary>AH</secondary>
</indexterm>
<para><acronym>IPsec</acronym> is comprised of the following
sub-protocols:</para>
<itemizedlist>
<listitem>
<para><emphasis>Encapsulated Security Payload
(<acronym>ESP</acronym>)</emphasis>: this protocol
protects the <acronym>IP</acronym> packet data from third
party interference by encrypting the contents using
symmetric cryptography algorithms such as Blowfish and
<acronym>3DES</acronym>.</para>
</listitem>
<listitem>
<para><emphasis>Authentication Header
(<acronym>AH</acronym>)</emphasis>: this protocol
protects the <acronym>IP</acronym> packet header from third
party interference and spoofing by computing a cryptographic
checksum and hashing the <acronym>IP </acronym> packet
header fields with a secure hashing function. This is then
followed by an additional header that contains the hash, to
allow the information in the packet to be
authenticated.</para>
</listitem>
<listitem>
<para><emphasis>IP Payload Compression Protocol
(<acronym>IPComp</acronym></emphasis>): this protocol
tries to increase communication performance by compressing
the <acronym>IP </acronym> payload in order to reduce the
amount of data sent.</para>
</listitem>
</itemizedlist>
<para>These protocols can either be used together or separately,
depending on the environment.</para>
<indexterm>
<primary><acronym>VPN</acronym></primary>
</indexterm>
<indexterm>
<primary>virtual private network</primary>
<see>VPN</see>
</indexterm>
<para><acronym>IPsec</acronym> supports two modes of operation.
The first mode, <firstterm>Transport Mode</firstterm>, protects
communications between two hosts. The second mode,
<firstterm>Tunnel Mode</firstterm>, is used to build virtual
tunnels, commonly known as Virtual Private Networks
(<acronym>VPN</acronym>s). Consult &man.ipsec.4; for detailed
information on the <acronym>IPsec</acronym> subsystem in
&os;.</para>
<para><acronym>IPsec</acronym> support is enabled by default on
&os;&nbsp;11 and later. For previous versions of &os;, add
these options to a custom kernel configuration file and rebuild
the kernel using the instructions in <xref
linkend="kernelconfig"/>:</para>
<indexterm>
<primary>kernel options</primary>
<secondary>IPSEC</secondary>
</indexterm>
<screen>options IPSEC #IP security
device crypto</screen>
<indexterm>
<primary>kernel options</primary>
<secondary>IPSEC_DEBUG</secondary>
</indexterm>
<para>If <acronym>IPsec</acronym> debugging support is desired,
the following kernel option should also be added:</para>
<screen>options IPSEC_DEBUG #debug for IP security</screen>
<para>This rest of this chapter demonstrates the process of
setting up an <acronym>IPsec</acronym> <acronym>VPN</acronym>
between a home network and a corporate network. In the example
scenario:</para>
<itemizedlist>
<listitem>
<para>Both sites are connected to the Internet through a
gateway that is running &os;.</para>
</listitem>
<listitem>
<para>The gateway on each network has at least one external
<acronym>IP</acronym> address. In this example, the
corporate <acronym>LAN</acronym>'s external
<acronym>IP</acronym> address is <systemitem
class="ipaddress">172.16.5.4</systemitem> and the home
<acronym>LAN</acronym>'s external <acronym>IP</acronym>
address is <systemitem
class="ipaddress">192.168.1.12</systemitem>.</para>
</listitem>
<listitem>
<para>The internal addresses of the two networks can be either
public or private <acronym>IP</acronym> addresses. However,
the address space must not collide. For example, both
networks cannot use <systemitem
class="ipaddress">192.168.1.x</systemitem>. In this
example, the corporate <acronym>LAN</acronym>'s internal
<acronym>IP</acronym> address is <systemitem
class="ipaddress">10.246.38.1</systemitem> and the home
<acronym>LAN</acronym>'s internal <acronym>IP</acronym>
address is <systemitem
class="ipaddress">10.0.0.5</systemitem>.</para>
</listitem>
</itemizedlist>
<sect2>
<info>
<title>Configuring a <acronym>VPN</acronym> on &os;</title>
<authorgroup>
<author>
<personname>
<firstname>Tom</firstname>
<surname>Rhodes</surname>
</personname>
<affiliation>
<address>
<email>trhodes@FreeBSD.org</email>
</address>
</affiliation>
<contrib>Written by </contrib>
</author>
</authorgroup>
</info>
<para>To begin, <package>security/ipsec-tools</package> must be
installed from the Ports Collection. This software provides a
number of applications which support the configuration.</para>
<para>The next requirement is to create two &man.gif.4;
pseudo-devices which will be used to tunnel packets and allow
both networks to communicate properly. As <systemitem
class="username">root</systemitem>, run the following
commands, replacing <replaceable>internal</replaceable> and
<replaceable>external</replaceable> with the real IP
addresses of the internal and external interfaces of the two
gateways:</para>
<screen>&prompt.root; <userinput>ifconfig gif0 create</userinput>
&prompt.root; <userinput>ifconfig gif0 <replaceable>internal1 internal2</replaceable></userinput>
&prompt.root; <userinput>ifconfig gif0 tunnel <replaceable>external1 external2</replaceable></userinput></screen>
<para>Verify the setup on each gateway, using
<command>ifconfig</command>. Here is the output from Gateway
1:</para>
<programlisting>gif0: flags=8051 mtu 1280
tunnel inet 172.16.5.4 --&gt; 192.168.1.12
inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6
inet 10.246.38.1 --&gt; 10.0.0.5 netmask 0xffffff00</programlisting>
<para>Here is the output from Gateway 2:</para>
<programlisting>gif0: flags=8051 mtu 1280
tunnel inet 192.168.1.12 --&gt; 172.16.5.4
inet 10.0.0.5 --&gt; 10.246.38.1 netmask 0xffffff00
inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4</programlisting>
<para>Once complete, both internal <acronym>IP</acronym>
addresses should be reachable using &man.ping.8;:</para>
<screen>priv-net&prompt.root; <userinput>ping 10.0.0.5</userinput>
PING 10.0.0.5 (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms
--- 10.0.0.5 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms</screen>
<screen>corp-net&prompt.root; <userinput>ping 10.246.38.1</userinput>
PING 10.246.38.1 (10.246.38.1): 56 data bytes
64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms
64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms
64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms
64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms
64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms
--- 10.246.38.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms</screen>
<para>As expected, both sides have the ability to send and
receive <acronym>ICMP</acronym> packets from the privately
configured addresses. Next, both gateways must be told how to
route packets in order to correctly send traffic from either
network. The following commands will achieve this
goal:</para>
<screen>corp-net&prompt.root; <userinput>route add <replaceable>10.0.0.0 10.0.0.5 255.255.255.0</replaceable></userinput>
corp-net&prompt.root; <userinput>route add net <replaceable>10.0.0.0: gateway 10.0.0.5</replaceable></userinput></screen>
<screen>priv-net&prompt.root; <userinput>route add <replaceable>10.246.38.0 10.246.38.1 255.255.255.0</replaceable></userinput>
priv-net&prompt.root; <userinput>route add host <replaceable>10.246.38.0: gateway 10.246.38.1</replaceable></userinput></screen>
<para>At this point, internal machines should be reachable from
each gateway as well as from machines behind the gateways.
Again, use &man.ping.8; to confirm:</para>
<screen>corp-net&prompt.root; <userinput>ping 10.0.0.8</userinput>
PING 10.0.0.8 (10.0.0.8): 56 data bytes
64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms
64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms
64 bytes from 10.0.0.8: icmp_seq=3 ttl=63 time=22.241 ms
64 bytes from 10.0.0.8: icmp_seq=4 ttl=63 time=174.705 ms
--- 10.0.0.8 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms</screen>
<screen>priv-net&prompt.root; <userinput>ping 10.246.38.107</userinput>
PING 10.246.38.1 (10.246.38.107): 56 data bytes
64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms
64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms
64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms
64 bytes from 10.246.38.107: icmp_seq=3 ttl=64 time=21.145 ms
64 bytes from 10.246.38.107: icmp_seq=4 ttl=64 time=36.708 ms
--- 10.246.38.107 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms</screen>
<para>Setting up the tunnels is the easy part. Configuring a
secure link is a more in depth process. The following
configuration uses pre-shared (<acronym>PSK</acronym>)
<acronym>RSA</acronym> keys. Other than the
<acronym>IP</acronym> addresses, the
<filename>/usr/local/etc/racoon/racoon.conf</filename> on both
gateways will be identical and look similar to:</para>
<programlisting>path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
log debug; #log verbosity setting: set to 'notify' when testing and debugging is complete
padding # options are not to be changed
{
maximum_length 20;
randomize off;
strict_check off;
exclusive_tail off;
}
timer # timing options. change as needed
{
counter 5;
interval 20 sec;
persend 1;
# natt_keepalive 15 sec;
phase1 30 sec;
phase2 15 sec;
}
listen # address [port] that racoon will listen on
{
isakmp 172.16.5.4 [500];
isakmp_natt 172.16.5.4 [4500];
}
remote 192.168.1.12 [500]
{
exchange_mode main,aggressive;
doi ipsec_doi;
situation identity_only;
my_identifier address 172.16.5.4;
peers_identifier address 192.168.1.12;
lifetime time 8 hour;
passive off;
proposal_check obey;
# nat_traversal off;
generate_policy off;
proposal {
encryption_algorithm blowfish;
hash_algorithm md5;
authentication_method pre_shared_key;
lifetime time 30 sec;
dh_group 1;
}
}
sainfo (address 10.246.38.0/24 any address 10.0.0.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
{ # $network must be the two internal networks you are joining.
pfs_group 1;
lifetime time 36000 sec;
encryption_algorithm blowfish,3des;
authentication_algorithm hmac_md5,hmac_sha1;
compression_algorithm deflate;
}</programlisting>
<para>For descriptions of each available option, refer to the
manual page for <filename>racoon.conf</filename>.</para>
<para>The Security Policy Database (<acronym>SPD</acronym>)
needs to be configured so that &os; and
<application>racoon</application> are able to encrypt and
decrypt network traffic between the hosts.</para>
<para>This can be achieved with a shell script, similar to the
following, on the corporate gateway. This file will be used
during system initialization and should be saved as
<filename>/usr/local/etc/racoon/setkey.conf</filename>.</para>
<programlisting>flush;
spdflush;
# To the home network
spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use;
spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use;</programlisting>
<para>Once in place, <application>racoon</application> may be
started on both gateways using the following command:</para>
<screen>&prompt.root; <userinput>/usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log</userinput></screen>
<para>The output should be similar to the following:</para>
<screen>corp-net&prompt.root; <userinput>/usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf</userinput>
Foreground mode.
2006-01-30 01:35:47: INFO: begin Identity Protection mode.
2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a
2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]-&gt;172.16.5.4[0] spi=28496098(0x1b2d0e2)
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]-&gt;192.168.1.12[0] spi=47784998(0x2d92426)
2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]-&gt;172.16.5.4[0] spi=124397467(0x76a279b)
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]-&gt;192.168.1.12[0] spi=175852902(0xa7b4d66)</screen>
<para>To ensure the tunnel is working properly, switch to
another console and use &man.tcpdump.1; to view network
traffic using the following command. Replace
<literal>em0</literal> with the network interface card as
required:</para>
<screen>&prompt.root; <userinput>tcpdump -i em0 host <replaceable>172.16.5.4 and dst 192.168.1.12</replaceable></userinput></screen>
<para>Data similar to the following should appear on the
console. If not, there is an issue and debugging the
returned data will be required.</para>
<programlisting>01:47:32.021683 IP corporatenetwork.com &gt; 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa)
01:47:33.022442 IP corporatenetwork.com &gt; 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb)
01:47:34.024218 IP corporatenetwork.com &gt; 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc)</programlisting>
<para>At this point, both networks should be available and seem
to be part of the same network. Most likely both networks are
protected by a firewall. To allow traffic to flow between
them, rules need to be added to pass packets. For the
&man.ipfw.8; firewall, add the following lines to the firewall
configuration file:</para>
<programlisting>ipfw add 00201 allow log esp from any to any
ipfw add 00202 allow log ah from any to any
ipfw add 00203 allow log ipencap from any to any
ipfw add 00204 allow log udp from any 500 to any</programlisting>
<note>
<para>The rule numbers may need to be altered depending on the
current host configuration.</para>
</note>
<para>For users of &man.pf.4; or &man.ipf.8;, the following
rules should do the trick:</para>
<programlisting>pass in quick proto esp from any to any
pass in quick proto ah from any to any
pass in quick proto ipencap from any to any
pass in quick proto udp from any port = 500 to any port = 500
pass in quick on gif0 from any to any
pass out quick proto esp from any to any
pass out quick proto ah from any to any
pass out quick proto ipencap from any to any
pass out quick proto udp from any port = 500 to any port = 500
pass out quick on gif0 from any to any</programlisting>
<para>Finally, to allow the machine to start support for the
<acronym>VPN</acronym> during system initialization, add the
following lines to <filename>/etc/rc.conf</filename>:</para>
<programlisting>ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot
racoon_enable="yes"</programlisting>
</sect2>
</sect1>
<sect1 xml:id="openssh">
<info>
<title>OpenSSH</title>
<authorgroup>
<author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed
by </contrib></author>
<!-- 21 April 2001 -->
</authorgroup>
</info>
<indexterm><primary>OpenSSH</primary></indexterm>
<indexterm>
<primary>security</primary>
<secondary>OpenSSH</secondary>
</indexterm>
<para><application>OpenSSH</application> is a set of network
connectivity tools used to provide secure access to remote
machines. Additionally, <acronym>TCP/IP</acronym> connections
can be tunneled or forwarded securely through
<acronym>SSH</acronym> connections.
<application>OpenSSH</application> encrypts all traffic to
effectively eliminate eavesdropping, connection hijacking, and
other network-level attacks.</para>
<para><application>OpenSSH</application> is maintained by the
OpenBSD project and is installed by default in &os;. It is
compatible with both <acronym>SSH</acronym> version 1 and 2
protocols.</para>
<para>When data is sent over the network in an unencrypted form,
network sniffers anywhere in between the client and server can
steal user/password information or data transferred during the
session. <application>OpenSSH</application> offers a variety of
authentication and encryption methods to prevent this from
happening. More information about
<application>OpenSSH</application> is available from <link
xlink:href="http://www.openssh.com/">http://www.openssh.com/</link>.</para>
<para>This section provides an overview of the built-in client
utilities to securely access other systems and securely transfer
files from a &os; system. It then describes how to configure a
<acronym>SSH</acronym> server on a &os; system. More
information is available in the man pages mentioned in this
chapter.</para>
<sect2>
<title>Using the SSH Client Utilities</title>
<indexterm>
<primary>OpenSSH</primary>
<secondary>client</secondary>
</indexterm>
<para>To log into a <acronym>SSH</acronym> server, use
<command>ssh</command> and specify a username that exists on
that server and the <acronym>IP</acronym> address or hostname
of the server. If this is the first time a connection has
been made to the specified server, the user will be prompted
to first verify the server's fingerprint:</para>
<screen>&prompt.root; <userinput>ssh <replaceable>user@example.com</replaceable></userinput>
The authenticity of host 'example.com (10.0.0.1)' can't be established.
ECDSA key fingerprint is 25:cc:73:b5:b3:96:75:3d:56:19:49:d2:5c:1f:91:3b.
Are you sure you want to continue connecting (yes/no)? <userinput>yes</userinput>
Permanently added 'example.com' (ECDSA) to the list of known hosts.
Password for user@example.com: <userinput><replaceable>user_password</replaceable></userinput></screen>
<para><acronym>SSH</acronym> utilizes a key fingerprint system
to verify the authenticity of the server when the client
connects. When the user accepts the key's fingerprint by
typing <literal>yes</literal> when connecting for the first
time, a copy of the key is saved to
<filename>.ssh/known_hosts</filename> in the user's home
directory. Future attempts to login are verified against the
saved key and <command>ssh</command> will display an alert if
the server's key does not match the saved key. If this
occurs, the user should first verify why the key has changed
before continuing with the connection.</para>
<para>By default, recent versions of
<application>OpenSSH</application> only accept
<acronym>SSH</acronym>v2 connections. By default, the client
will use version 2 if possible and will fall back to version 1
if the server does not support version 2. To force
<command>ssh</command> to only use the specified protocol,
include <option>-1</option> or <option>-2</option>.
Additional options are described in &man.ssh.1;.</para>
<indexterm>
<primary>OpenSSH</primary>
<secondary>secure copy</secondary>
</indexterm>
<indexterm>
<primary>&man.scp.1;</primary>
</indexterm>
<para>Use &man.scp.1; to securely copy a file to or from a
remote machine. This example copies
<filename>COPYRIGHT</filename> on the remote system to a file
of the same name in the current directory of the local
system:</para>
<screen>&prompt.root; <userinput>scp <replaceable>user@example.com:/COPYRIGHT COPYRIGHT</replaceable></userinput>
Password for user@example.com: <userinput><replaceable>*******</replaceable></userinput>
COPYRIGHT 100% |*****************************| 4735
00:00
&prompt.root;</screen>
<para>Since the fingerprint was already verified for this host,
the server's key is automatically checked before prompting for
the user's password.</para>
<para>The arguments passed to <command>scp</command> are similar
to <command>cp</command>. The file or files to copy is the
first argument and the destination to copy to is the second.
Since the file is fetched over the network, one or more of the
file arguments takes the form
<option>user@host:&lt;path_to_remote_file&gt;</option>. Be
aware when copying directories recursively that
<command>scp</command> uses <option>-r</option>, whereas
<command>cp</command> uses <option>-R</option>.</para>
<para>To open an interactive session for copying files, use
<command>sftp</command>. Refer to &man.sftp.1; for a list of
available commands while in an <command>sftp</command>
session.</para>
<sect3 xml:id="security-ssh-keygen">
<title>Key-based Authentication</title>
<para>Instead of using passwords, a client can be configured
to connect to the remote machine using keys. To generate
<acronym>RSA</acronym>
authentication keys, use <command>ssh-keygen</command>. To
generate a public and private key pair, specify the type of
key and follow the prompts. It is recommended to protect
the keys with a memorable, but hard to guess
passphrase.</para>
<screen>&prompt.user; <userinput>ssh-keygen -t rsa</userinput>
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): <co xml:id="co-ssh-keygen-passphrase1"/>
Enter same passphrase again: <co xml:id="co-ssh-keygen-passphrase2"/>
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:54Xm9Uvtv6H4NOo6yjP/YCfODryvUU7yWHzMqeXwhq8 user@host.example.com
The key's randomart image is:
+---[RSA 2048]----+
| |
| |
| |
| . o.. |
| .S*+*o |
| . O=Oo . . |
| = Oo= oo..|
| .oB.* +.oo.|
| =OE**.o..=|
+----[SHA256]-----+</screen>
<calloutlist>
<callout arearefs="co-ssh-keygen-passphrase1">
<para>Type a passphrase here. It can contain spaces and
symbols.</para>
</callout>
<callout arearefs="co-ssh-keygen-passphrase2">
<para>Retype the passphrase to verify it.</para>
</callout>
</calloutlist>
<para>The private key
is stored in <filename>~/.ssh/id_rsa</filename>
and the public key
is stored in <filename>~/.ssh/id_rsa.pub</filename>.
The
<emphasis>public</emphasis> key must be copied to
<filename>~/.ssh/authorized_keys</filename> on the remote
machine for key-based authentication to
work.</para>
<warning>
<para>Many users believe that keys are secure by design and
will use a key without a passphrase. This is
<emphasis>dangerous</emphasis> behavior. An
administrator can verify that a key pair is protected by a
passphrase by viewing the private key manually. If the
private key file contains the word
<literal>ENCRYPTED</literal>, the key owner is using a
passphrase. In addition, to better secure end users,
<literal>from</literal> may be placed in the public key
file. For example, adding
<literal>from="192.168.10.5"</literal> in front of the
<literal>ssh-rsa</literal>
prefix will only allow that specific user to log in from
that <acronym>IP</acronym> address.</para>
</warning>
<para>The options and files vary with different versions of
<application>OpenSSH</application>.
To avoid problems, consult &man.ssh-keygen.1;.</para>
<para>If a passphrase is used, the user is prompted for
the passphrase each time a connection is made to the server.
To load <acronym>SSH</acronym> keys into memory and remove
the need to type the passphrase each time, use
&man.ssh-agent.1; and &man.ssh-add.1;.</para>
<para>Authentication is handled by
<command>ssh-agent</command>, using the private keys that
are loaded into it. <command>ssh-agent</command>
can be used to launch another application like a
shell or a window manager.</para>
<para>To use <command>ssh-agent</command> in a shell, start it
with a shell as an argument. Add the identity by
running <command>ssh-add</command> and entering the
passphrase for the private key.
The user will then be able to <command>ssh</command>
to any host that has the corresponding public key installed.
For example:</para>
<screen>&prompt.user; <userinput>ssh-agent <replaceable>csh</replaceable></userinput>
&prompt.user; <userinput>ssh-add</userinput>
Enter passphrase for key '/usr/home/user/.ssh/id_rsa': <co xml:id="co-ssh-agent-passphrase"/>
Identity added: /usr/home/user/.ssh/id_rsa (/usr/home/user/.ssh/id_rsa)
&prompt.user;</screen>
<calloutlist>
<callout arearefs="co-ssh-agent-passphrase">
<para>Enter the passphrase for the key.</para>
</callout>
</calloutlist>
<para>To use <command>ssh-agent</command> in
<application>&xorg;</application>, add an entry for it in
<filename>~/.xinitrc</filename>. This provides the
<command>ssh-agent</command> services to all programs
launched in <application>&xorg;</application>. An example
<filename>~/.xinitrc</filename> might look like this:</para>
<programlisting>exec ssh-agent <replaceable>startxfce4</replaceable></programlisting>
<para>This launches <command>ssh-agent</command>, which in
turn launches <application>XFCE</application>, every time
<application>&xorg;</application> starts. Once
<application>&xorg;</application> has been restarted so that
the changes can take effect, run <command>ssh-add</command>
to load all of the <acronym>SSH</acronym> keys.</para>
</sect3>
<sect3 xml:id="security-ssh-tunneling">
<title><acronym>SSH</acronym> Tunneling</title>
<indexterm>
<primary>OpenSSH</primary>
<secondary>tunneling</secondary>
</indexterm>
<para><application>OpenSSH</application> has the ability to
create a tunnel to encapsulate another protocol in an
encrypted session.</para>
<para>The following command tells <command>ssh</command> to
create a tunnel for
<application>telnet</application>:</para>
<screen>&prompt.user; <userinput>ssh -2 -N -f -L <replaceable>5023:localhost:23 user@foo.example.com</replaceable></userinput>
&prompt.user;</screen>
<para>This example uses the following options:</para>
<variablelist>
<varlistentry>
<term><option>-2</option></term>
<listitem>
<para>Forces <command>ssh</command> to use version 2 to
connect to the server.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-N</option></term>
<listitem>
<para>Indicates no command, or tunnel only. If omitted,
<command>ssh</command> initiates a normal
session.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option></term>
<listitem>
<para>Forces <command>ssh</command> to run in the
background.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-L</option></term>
<listitem>
<para>Indicates a local tunnel in
<replaceable>localport:remotehost:remoteport</replaceable>
format.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>user@foo.example.com</option></term>
<listitem>
<para>The login name to use on the specified remote
<acronym>SSH</acronym> server.</para>
</listitem>
</varlistentry>
</variablelist>
<para>An <acronym>SSH</acronym> tunnel works by creating a
listen socket on <systemitem>localhost</systemitem> on the
specified <literal>localport</literal>. It then forwards
any connections received on <literal>localport</literal> via
the <acronym>SSH</acronym> connection to the specified
<literal>remotehost:remoteport</literal>. In the example,
port <literal>5023</literal> on the client is forwarded to
port <literal>23</literal> on the remote machine. Since
port 23 is used by <application>telnet</application>, this
creates an encrypted <application>telnet</application>
session through an <acronym>SSH</acronym> tunnel.</para>
<para>This method can be used to wrap any number of insecure
<acronym>TCP</acronym> protocols such as
<acronym>SMTP</acronym>, <acronym>POP3</acronym>, and
<acronym>FTP</acronym>, as seen in the following
examples.</para>
<example>
<title>Create a Secure Tunnel for
<acronym>SMTP</acronym></title>
<screen>&prompt.user; <userinput>ssh -2 -N -f -L <replaceable>5025:localhost:25 user@mailserver.example.com</replaceable></userinput>
user@mailserver.example.com's password: <userinput>*****</userinput>
&prompt.user; <userinput>telnet localhost 5025</userinput>
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mailserver.example.com ESMTP</screen>
<para>This can be used in conjunction with
<command>ssh-keygen</command> and additional user accounts
to create a more seamless <acronym>SSH</acronym> tunneling
environment. Keys can be used in place of typing a
password, and the tunnels can be run as a separate
user.</para>
</example>
<example>
<title>Secure Access of a <acronym>POP3</acronym>
Server</title>
<para>In this example, there is an <acronym>SSH</acronym>
server that accepts connections from the outside. On the
same network resides a mail server running a
<acronym>POP3</acronym> server. To check email in a
secure manner, create an <acronym>SSH</acronym> connection
to the <acronym>SSH</acronym> server and tunnel through to
the mail server:</para>
<screen>&prompt.user; <userinput>ssh -2 -N -f -L <replaceable>2110:mail.example.com:110 user@ssh-server.example.com</replaceable></userinput>
user@ssh-server.example.com's password: <userinput>******</userinput></screen>
<para>Once the tunnel is up and running, point the email
client to send <acronym>POP3</acronym> requests to
<systemitem>localhost</systemitem> on port 2110. This
connection will be forwarded securely across the tunnel to
<systemitem>mail.example.com</systemitem>.</para>
</example>
<example>
<title>Bypassing a Firewall</title>
<para>Some firewalls
filter both incoming and outgoing connections. For
example, a firewall might limit access from remote
machines to ports 22 and 80 to only allow
<acronym>SSH</acronym> and web surfing. This prevents
access to any other service which uses a port other than
22 or 80.</para>
<para>The solution is to create an <acronym>SSH</acronym>
connection to a machine outside of the network's firewall
and use it to tunnel to the desired service:</para>
<screen>&prompt.user; <userinput>ssh -2 -N -f -L <replaceable>8888:music.example.com:8000 user@unfirewalled-system.example.org</replaceable></userinput>
user@unfirewalled-system.example.org's password: <userinput>*******</userinput></screen>
<para>In this example, a streaming Ogg Vorbis client can now
be pointed to <systemitem>localhost</systemitem> port
8888, which will be forwarded over to
<systemitem>music.example.com</systemitem> on port 8000,
successfully bypassing the firewall.</para>
</example>
</sect3>
</sect2>
<sect2>
<title>Enabling the SSH Server</title>
<indexterm>
<primary>OpenSSH</primary>
<secondary>enabling</secondary>
</indexterm>
<para>In addition to providing built-in <acronym>SSH</acronym>
client utilities, a &os; system can be configured as an
<acronym>SSH</acronym> server, accepting connections from
other <acronym>SSH</acronym> clients.</para>
<para>To see if <application>sshd</application> is operating,
use the &man.service.8; command:</para>
<screen>&prompt.root; <userinput>service sshd status</userinput></screen>
<para>If the service is not running, add the following line to
<filename>/etc/rc.conf</filename>.</para>
<programlisting>sshd_enable="YES"</programlisting>
<para>This will start <application>sshd</application>, the
daemon program for <application>OpenSSH</application>, the
next time the system boots. To start it now:</para>
<screen>&prompt.root; <userinput>service sshd start</userinput></screen>
<para>The first time <application>sshd</application> starts on a
&os; system, the system's host keys will be automatically
created and the fingerprint will be displayed on the console.
Provide users with the fingerprint so that they can verify it
the first time they connect to the server.</para>
<para>Refer to &man.sshd.8; for the list of available options
when starting <application>sshd</application> and a more
complete discussion about authentication, the login process,
and the various configuration files.</para>
<para>At this point, the <application>sshd</application> should
be available to all users with a username and password on
the system.</para>
</sect2>
<sect2>
<title>SSH Server Security</title>
<para>While <application>sshd</application> is the most widely
used remote administration facility for &os;, brute force
and drive by attacks are common to any system exposed to
public networks. Several additional parameters are available
to prevent the success of these attacks and will be described
in this section.</para>
<para>It is a good idea to limit which users can log into the
<acronym>SSH</acronym> server and from where using the
<literal>AllowUsers</literal> keyword in the
<application>OpenSSH</application> server configuration file.
For example, to only allow <systemitem
class="username">root</systemitem> to log in from
<systemitem class="ipaddress">192.168.1.32</systemitem>, add
this line to <filename>/etc/ssh/sshd_config</filename>:</para>
<programlisting>AllowUsers root@192.168.1.32</programlisting>
<para>To allow <systemitem class="username">admin</systemitem>
to log in from anywhere, list that user without specifying an
<acronym>IP</acronym> address:</para>
<programlisting>AllowUsers admin</programlisting>
<para>Multiple users should be listed on the same line, like
so:</para>
<programlisting>AllowUsers root@192.168.1.32 admin</programlisting>
<para>After making changes to
<filename>/etc/ssh/sshd_config</filename>,
tell <application>sshd</application> to reload its
configuration file by running:</para>
<screen>&prompt.root; <userinput>service sshd reload</userinput></screen>
<note>
<para>When this keyword is used, it is important to list each
user that needs to log into this machine. Any user that is
not specified in that line will be locked out. Also, the
keywords used in the <application>OpenSSH</application>
server configuration file are case-sensitive. If the
keyword is not spelled correctly, including its case, it
will be ignored. Always test changes to this file to make
sure that the edits are working as expected. Refer to
&man.sshd.config.5; to verify the spelling and use of the
available keywords.</para>
</note>
<para>In addition, users may be forced to use two factor
authentication via the use of a public and private key. When
required, the user may generate a key pair through the use
of &man.ssh-keygen.1; and send the administrator the public
key. This key file will be placed in the
<filename>authorized_keys</filename> as described above in
the client section. To force the users to use keys only,
the following option may be configured:</para>
<programlisting>AuthenticationMethods publickey</programlisting>
<tip>
<para>Do not confuse <filename>/etc/ssh/sshd_config</filename>
with <filename>/etc/ssh/ssh_config</filename> (note the
extra <literal>d</literal> in the first filename). The
first file configures the server and the second file
configures the client. Refer to &man.ssh.config.5; for a
listing of the available client settings.</para>
</tip>
</sect2>
</sect1>
<sect1 xml:id="fs-acl">
<info>
<title>Access Control Lists</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>ACL</primary>
</indexterm>
<para>Access Control Lists (<acronym>ACL</acronym>s) extend the
standard &unix; permission model in a &posix;.1e compatible way.
This permits an administrator to take advantage of a more
fine-grained permissions model.</para>
<para>The &os; <filename>GENERIC</filename> kernel provides
<acronym>ACL</acronym> support for <acronym>UFS</acronym> file
systems. Users who prefer to compile a custom kernel must
include the following option in their custom kernel
configuration file:</para>
<programlisting>options UFS_ACL</programlisting>
<para>If this option is not compiled in, a warning message will be
displayed when attempting to mount a file system with
<acronym>ACL</acronym> support. <acronym>ACL</acronym>s rely on
extended attributes which are natively supported in
<acronym>UFS2</acronym>.</para>
<para>This chapter describes how to enable
<acronym>ACL</acronym> support and provides some usage
examples.</para>
<sect2>
<title>Enabling <acronym>ACL</acronym> Support</title>
<para><acronym>ACL</acronym>s are enabled by the mount-time
administrative flag, <option>acls</option>, which may be added
to <filename>/etc/fstab</filename>. The mount-time flag can
also be automatically set in a persistent manner using
&man.tunefs.8; to modify a superblock <acronym>ACL</acronym>s
flag in the file system header. In general, it is preferred
to use the superblock flag for several reasons:</para>
<itemizedlist>
<listitem>
<para>The superblock flag cannot be changed by a remount
using <option>mount -u</option> as it requires a complete
<command>umount</command> and fresh
<command>mount</command>. This means that
<acronym>ACL</acronym>s cannot be enabled on the root file
system after boot. It also means that
<acronym>ACL</acronym> support on a file system cannot be
changed while the system is in use.</para>
</listitem>
<listitem>
<para>Setting the superblock flag causes the file system to
always be mounted with <acronym>ACL</acronym>s enabled,
even if there is not an <filename>fstab</filename> entry
or if the devices re-order. This prevents accidental
mounting of the file system without <acronym>ACL</acronym>
support.</para>
</listitem>
</itemizedlist>
<note>
<para>It is desirable to discourage accidental mounting
without <acronym>ACL</acronym>s enabled because nasty things
can happen if <acronym>ACL</acronym>s are enabled, then
disabled, then re-enabled without flushing the extended
attributes. In general, once <acronym>ACL</acronym>s are
enabled on a file system, they should not be disabled, as
the resulting file protections may not be compatible with
those intended by the users of the system, and re-enabling
<acronym>ACL</acronym>s may re-attach the previous
<acronym>ACL</acronym>s to files that have since had their
permissions changed, resulting in unpredictable
behavior.</para>
</note>
<para>File systems with <acronym>ACL</acronym>s enabled will
show a plus (<literal>+</literal>) sign in their permission
settings:</para>
<programlisting>drwx------ 2 robert robert 512 Dec 27 11:54 private
drwxrwx---+ 2 robert robert 512 Dec 23 10:57 directory1
drwxrwx---+ 2 robert robert 512 Dec 22 10:20 directory2
drwxrwx---+ 2 robert robert 512 Dec 27 11:57 directory3
drwxr-xr-x 2 robert robert 512 Nov 10 11:54 public_html</programlisting>
<para>In this example, <filename>directory1</filename>,
<filename>directory2</filename>, and
<filename>directory3</filename> are all taking advantage of
<acronym>ACL</acronym>s, whereas
<filename>public_html</filename> is not.</para>
</sect2>
<sect2>
<title>Using <acronym>ACL</acronym>s</title>
<para>File system <acronym>ACL</acronym>s can be viewed using
<command>getfacl</command>. For instance, to view the
<acronym>ACL</acronym> settings on
<filename>test</filename>:</para>
<screen>&prompt.user; <userinput>getfacl test</userinput>
#file:test
#owner:1001
#group:1001
user::rw-
group::r--
other::r--</screen>
<para>To change the <acronym>ACL</acronym> settings on this
file, use <command>setfacl</command>. To remove all of the
currently defined <acronym>ACL</acronym>s from a file or file
system, include <option>-k</option>. However, the preferred
method is to use <option>-b</option> as it leaves the basic
fields required for <acronym>ACL</acronym>s to work.</para>
<screen>&prompt.user; <userinput>setfacl -k test</userinput></screen>
<para>To modify the default <acronym>ACL</acronym> entries, use
<option>-m</option>:</para>
<screen>&prompt.user; <userinput>setfacl -m u:trhodes:rwx,group:web:r--,o::--- test</userinput></screen>
<para>In this example, there were no pre-defined entries, as
they were removed by the previous command. This command
restores the default options and assigns the options listed.
If a user or group is added which does not exist on the
system, an <errorname>Invalid argument</errorname> error will
be displayed.</para>
<para>Refer to &man.getfacl.1; and &man.setfacl.1; for more
information about the options available for these
commands.</para>
</sect2>
</sect1>
<sect1 xml:id="security-pkg">
<info>
<title>Monitoring Third Party Security Issues</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>pkg</primary>
</indexterm>
<para>In recent years, the security world has made many
improvements to how vulnerability assessment is handled. The
threat of system intrusion increases as third party utilities
are installed and configured for virtually any operating
system available today.</para>
<para>Vulnerability assessment is a key factor in security.
While &os; releases advisories for the base system, doing so
for every third party utility is beyond the &os; Project's
capability. There is a way to mitigate third party
vulnerabilities and warn administrators of known security
issues. A &os; add on utility known as
<application>pkg</application> includes options explicitly for
this purpose.</para>
<para><application>pkg</application> polls a database for security
issues. The database is updated and maintained by the &os;
Security Team and ports developers.</para>
<para>Please refer to <link
xlink:href="&url.books.handbook;/pkgng-intro.html">instructions</link>
for installing
<application>pkg</application>.</para>
<para>Installation provides &man.periodic.8; configuration files
for maintaining the <application>pkg</application> audit
database, and provides a programmatic method of keeping it
updated. This functionality is enabled if
<literal>daily_status_security_pkgaudit_enable</literal>
is set to <literal>YES</literal> in &man.periodic.conf.5;.
Ensure that daily security run emails, which are sent to
<systemitem class="username">root</systemitem>'s email account,
are being read.</para>
<para>After installation, and to audit third party utilities as
part of the Ports Collection at any time, an administrator may
choose to update the database and view known vulnerabilities
of installed packages by invoking:</para>
<screen>&prompt.root; <userinput>pkg audit -F</userinput></screen>
<para><application>pkg</application> displays messages
any published vulnerabilities in installed packages:</para>
<programlisting>Affected package: cups-base-1.1.22.0_1
Type of problem: cups-base -- HPGL buffer overflow vulnerability.
Reference: &lt;https://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html&gt;
1 problem(s) in your installed packages found.
You are advised to update or deinstall the affected package(s) immediately.</programlisting>
<para>By pointing a web browser to the displayed
<acronym>URL</acronym>, an administrator may obtain more
information about the vulnerability. This will include the
versions affected, by &os; port version, along with other web
sites which may contain security advisories.</para>
<para><application>pkg</application> is a powerful utility
and is extremely useful when coupled with
<package>ports-mgmt/portmaster</package>.</para>
</sect1>
<sect1 xml:id="security-advisories">
<info>
<title>&os; Security Advisories</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>&os; Security Advisories</primary>
</indexterm>
<para>Like many producers of quality operating systems, the &os;
Project has a security team which is responsible for
determining the End-of-Life (<acronym>EoL</acronym>) date for
each &os; release and to provide security updates for supported
releases which have not yet reached their
<acronym>EoL</acronym>. More information about the &os;
security team and the supported releases is available on the
<link xlink:href="&url.base;/security">&os; security
page</link>.</para>
<para>One task of the security team is to respond to reported
security vulnerabilities in the &os; operating system. Once a
vulnerability is confirmed, the security team verifies the steps
necessary to fix the vulnerability and updates the source code
with the fix. It then publishes the details as a
<quote>Security Advisory</quote>. Security
advisories are published on the <link
xlink:href="&url.base;/security/advisories.html">&os;
website</link> and mailed to the
&a.security-notifications.name;, &a.security.name;, and
&a.announce.name; mailing lists.</para>
<para>This section describes the format of a &os; security
advisory.</para>
<sect2>
<title>Format of a Security Advisory</title>
<para>Here is an example of a &os; security advisory:</para>
<programlisting>=============================================================================
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-14:04.bind Security Advisory
The FreeBSD Project
Topic: BIND remote denial of service vulnerability
Category: contrib
Module: bind
Announced: 2014-01-14
Credits: ISC
Affects: FreeBSD 8.x and FreeBSD 9.x
Corrected: 2014-01-14 19:38:37 UTC (stable/9, 9.2-STABLE)
2014-01-14 19:42:28 UTC (releng/9.2, 9.2-RELEASE-p3)
2014-01-14 19:42:28 UTC (releng/9.1, 9.1-RELEASE-p10)
2014-01-14 19:38:37 UTC (stable/8, 8.4-STABLE)
2014-01-14 19:42:28 UTC (releng/8.4, 8.4-RELEASE-p7)
2014-01-14 19:42:28 UTC (releng/8.3, 8.3-RELEASE-p14)
CVE Name: CVE-2014-0591
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit &lt;URL:http://security.FreeBSD.org/&gt;.
I. Background
BIND 9 is an implementation of the Domain Name System (DNS) protocols.
The named(8) daemon is an Internet Domain Name Server.
II. Problem Description
Because of a defect in handling queries for NSEC3-signed zones, BIND can
crash with an "INSIST" failure in name.c when processing queries possessing
certain properties. This issue only affects authoritative nameservers with
at least one NSEC3-signed zone. Recursive-only servers are not at risk.
III. Impact
An attacker who can send a specially crafted query could cause named(8)
to crash, resulting in a denial of service.
IV. Workaround
No workaround is available, but systems not running authoritative DNS service
with at least one NSEC3-signed zone using named(8) are not vulnerable.
V. Solution
Perform one of the following:
1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
[FreeBSD 8.3, 8.4, 9.1, 9.2-RELEASE and 8.4-STABLE]
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-release.patch
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-release.patch.asc
# gpg --verify bind-release.patch.asc
[FreeBSD 9.2-STABLE]
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-stable-9.patch
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-stable-9.patch.asc
# gpg --verify bind-stable-9.patch.asc
b) Execute the following commands as root:
# cd /usr/src
# patch &lt; /path/to/patch
Recompile the operating system using buildworld and installworld as
described in &lt;URL:https://www.FreeBSD.org/handbook/makeworld.html&gt;.
Restart the applicable daemons, or reboot the system.
3) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/8/ r260646
releng/8.3/ r260647
releng/8.4/ r260647
stable/9/ r260646
releng/9.1/ r260647
releng/9.2/ r260647
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
&lt;URL:https://svnweb.freebsd.org/base?view=revision&amp;revision=NNNNNN&gt;
VII. References
&lt;URL:https://kb.isc.org/article/AA-01078&gt;
&lt;URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0591&gt;
The latest revision of this advisory is available at
&lt;URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-14:04.bind.asc&gt;
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCgAGBQJS1ZTYAAoJEO1n7NZdz2rnOvQP/2/68/s9Cu35PmqNtSZVVxVG
ZSQP5EGWx/lramNf9566iKxOrLRMq/h3XWcC4goVd+gZFrvITJSVOWSa7ntDQ7TO
XcinfRZ/iyiJbs/Rg2wLHc/t5oVSyeouyccqODYFbOwOlk35JjOTMUG1YcX+Zasg
ax8RV+7Zt1QSBkMlOz/myBLXUjlTZ3Xg2FXVsfFQW5/g2CjuHpRSFx1bVNX6ysoG
9DT58EQcYxIS8WfkHRbbXKh9I1nSfZ7/Hky/kTafRdRMrjAgbqFgHkYTYsBZeav5
fYWKGQRJulYfeZQ90yMTvlpF42DjCC3uJYamJnwDIu8OhS1WRBI8fQfr9DRzmRua
OK3BK9hUiScDZOJB6OqeVzUTfe7MAA4/UwrDtTYQ+PqAenv1PK8DZqwXyxA9ThHb
zKO3OwuKOVHJnKvpOcr+eNwo7jbnHlis0oBksj/mrq2P9m2ueF9gzCiq5Ri5Syag
Wssb1HUoMGwqU0roS8+pRpNC8YgsWpsttvUWSZ8u6Vj/FLeHpiV3mYXPVMaKRhVm
067BA2uj4Th1JKtGleox+Em0R7OFbCc/9aWC67wiqI6KRyit9pYiF3npph+7D5Eq
7zPsUdDd+qc+UTiLp3liCRp5w6484wWdhZO6wRtmUgxGjNkxFoNnX8CitzF8AaqO
UWWemqWuz3lAZuORQ9KX
=OQzQ
-----END PGP SIGNATURE-----</programlisting>
<para>Every security advisory uses the following format:</para>
<itemizedlist>
<listitem>
<para>Each security advisory is signed by the
<acronym>PGP</acronym> key of the Security Officer. The
public key for the Security Officer can be verified at
<xref linkend="pgpkeys"/>.</para>
</listitem>
<listitem>
<para>The name of the security advisory always begins with
<literal>FreeBSD-SA-</literal> (for FreeBSD Security
Advisory), followed by the year in two digit format
(<literal>14:</literal>), followed by the advisory number
for that year (<literal>04.</literal>), followed by the
name of the affected application or subsystem
(<literal>bind</literal>). The advisory shown here is the
fourth advisory for 2014 and it affects
<application>BIND</application>.</para>
</listitem>
<listitem>
<para>The <literal>Topic</literal> field summarizes the
vulnerability.</para>
</listitem>
<listitem>
<para>The <literal>Category</literal> refers to the
affected part of the system which may be one of
<literal>core</literal>, <literal>contrib</literal>, or
<literal>ports</literal>. The <literal>core</literal>
category means that the vulnerability affects a core
component of the &os; operating system. The
<literal>contrib</literal> category means that the
vulnerability affects software included with &os;,
such as <application>BIND</application>. The
<literal>ports</literal> category indicates that the
vulnerability affects software available through the Ports
Collection.</para>
</listitem>
<listitem>
<para>The <literal>Module</literal> field refers to the
component location. In this example, the
<literal>bind</literal> module is affected; therefore,
this vulnerability affects an application installed with
the operating system.</para>
</listitem>
<listitem>
<para>The <literal>Announced</literal> field reflects the
date the security advisory was published. This means
that the security team has verified that the problem
exists and that a patch has been committed to the &os;
source code repository.</para>
</listitem>
<listitem>
<para>The <literal>Credits</literal> field gives credit to
the individual or organization who noticed the
vulnerability and reported it.</para>
</listitem>
<listitem>
<para>The <literal>Affects</literal> field explains which
releases of &os; are affected by this
vulnerability.</para>
</listitem>
<listitem>
<para>The <literal>Corrected</literal> field indicates the
date, time, time offset, and releases that were
corrected. The section in parentheses shows each branch
for which the fix has been merged, and the version number
of the corresponding release from that branch. The
release identifier itself includes the version number
and, if appropriate, the patch level. The patch level is
the letter <literal>p</literal> followed by a number,
indicating the sequence number of the patch, allowing
users to track which patches have already been applied to
the system.</para>
</listitem>
<listitem>
<para>The <literal>CVE Name</literal> field lists the
advisory number, if one exists, in the public <link
xlink:href="http://cve.mitre.org">cve.mitre.org</link>
security vulnerabilities database.</para>
</listitem>
<listitem>
<para>The <literal>Background</literal> field provides a
description of the affected module.</para>
</listitem>
<listitem>
<para>The <literal>Problem Description</literal> field
explains the vulnerability. This can include
information about the flawed code and how the utility
could be maliciously used.</para>
</listitem>
<listitem>
<para>The <literal>Impact</literal> field describes what
type of impact the problem could have on a system.</para>
</listitem>
<listitem>
<para>The <literal>Workaround</literal> field indicates if
a workaround is available to system administrators who
cannot immediately patch the system .</para>
</listitem>
<listitem>
<para>The <literal>Solution</literal> field provides the
instructions for patching the affected system. This is a
step by step tested and verified method for getting a
system patched and working securely.</para>
</listitem>
<listitem>
<para>The <literal>Correction Details</literal> field
displays each affected Subversion branch with the revision
number that contains the corrected code.</para>
</listitem>
<listitem>
<para>The <literal>References</literal> field offers sources
of additional information regarding the
vulnerability.</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 xml:id="security-accounting">
<info>
<title>Process Accounting</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>Process Accounting</primary>
</indexterm>
<para>Process accounting is a security method in which an
administrator may keep track of system resources used and
their allocation among users, provide for system monitoring,
and minimally track a user's commands.</para>
<para>Process accounting has both positive and negative points.
One of the positives is that an intrusion may be narrowed down
to the point of entry. A negative is the amount of logs
generated by process accounting, and the disk space they may
require. This section walks an administrator through the basics
of process accounting.</para>
<note>
<para>If more fine-grained accounting is needed, refer to
<xref linkend="audit"/>.</para>
</note>
<sect2>
<title>Enabling and Utilizing Process Accounting</title>
<para>Before using process accounting, it must be enabled using
the following commands:</para>
<screen>&prompt.root; <userinput>sysrc accounting_enable=yes</userinput>
&prompt.root; <userinput>service accounting start</userinput></screen>
<para>The accounting information is stored in files located in
<filename>/var/account</filename>, which is automatically created,
if necessary, the first time the accounting service starts.
These files contain sensitive information, including all the
commands issued by all users. Write access to the files is
limited to <systemitem class="username">root</systemitem>,
and read access is limited to <systemitem
class="username">root</systemitem> and members of the
<systemitem class="groupname">wheel</systemitem> group.
To also prevent members of <systemitem
class="groupname">wheel</systemitem> from reading the files,
change the mode of the <filename>/var/account</filename>
directory to allow access only by <systemitem
class="username">root</systemitem>.</para>
<para>Once enabled, accounting will begin to track information
such as <acronym>CPU</acronym> statistics and executed
commands. All accounting logs are in a non-human readable
format which can be viewed using <command>sa</command>. If
issued without any options, <command>sa</command> prints
information relating to the number of per-user calls, the
total elapsed time in minutes, total <acronym>CPU</acronym>
and user time in minutes, and the average number of
<acronym>I/O</acronym> operations. Refer to &man.sa.8; for
the list of available options which control the output.</para>
<para>To display the commands issued by users, use
<command>lastcomm</command>. For example, this command
prints out all usage of <command>ls</command> by <systemitem
class="username">trhodes</systemitem> on the
<literal>ttyp1</literal> terminal:</para>
<screen>&prompt.root; <userinput>lastcomm ls trhodes ttyp1</userinput></screen>
<para>Many other useful options exist and are explained in
&man.lastcomm.1;, &man.acct.5;, and &man.sa.8;.</para>
</sect2>
</sect1>
<sect1 xml:id="security-resourcelimits">
<info>
<title>Resource Limits</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>Resource limits</primary>
</indexterm>
<para>&os; provides several methods for an administrator to
limit the amount of system resources an individual may use.
Disk quotas limit the amount of disk space available to users.
Quotas are discussed in <xref linkend="quotas"/>.</para>
<indexterm>
<primary>quotas</primary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>quotas</secondary>
</indexterm>
<indexterm>
<primary>disk quotas</primary>
</indexterm>
<para>Limits to other resources, such as <acronym>CPU</acronym>
and memory, can be set using either a flat file or a command to
configure a resource limits database. The traditional method
defines login classes by editing
<filename>/etc/login.conf</filename>. While this method is
still supported, any changes require a multi-step process of
editing this file, rebuilding the resource database, making
necessary changes to <filename>/etc/master.passwd</filename>,
and rebuilding the password database. This can become time
consuming, depending upon the number of users to
configure.</para>
<para><command>rctl</command> can be used to provide a more
fine-grained method for controlling resource limits. This
command supports more than user limits as it can also be used to
set resource constraints on processes and jails.</para>
<para>This section demonstrates both methods for controlling
resources, beginning with the traditional method.</para>
<sect2 xml:id="users-limiting">
<title>Configuring Login Classes</title>
<indexterm>
<primary>limiting users</primary>
</indexterm>
<indexterm>
<primary>accounts</primary>
<secondary>limiting</secondary>
</indexterm>
<indexterm>
<primary><filename>/etc/login.conf</filename></primary>
</indexterm>
<para>In the traditional method, login classes and the resource
limits to apply to a login class are defined in
<filename>/etc/login.conf</filename>. Each user account can
be assigned to a login class, where <literal>default</literal>
is the default login class. Each login class has a set of
login capabilities associated with it. A login capability is
a
<literal><replaceable>name</replaceable>=<replaceable>value</replaceable></literal>
pair, where <replaceable>name</replaceable> is a well-known
identifier and <replaceable>value</replaceable> is an
arbitrary string which is processed accordingly depending on
the <replaceable>name</replaceable>.</para>
<note>
<para>Whenever <filename>/etc/login.conf</filename> is edited,
the <filename>/etc/login.conf.db</filename> must be updated
by executing the following command:</para>
<screen>&prompt.root; <userinput>cap_mkdb /etc/login.conf</userinput></screen>
</note>
<para>Resource limits differ from the default login capabilities
in two ways. First, for every limit, there is a
<firstterm>soft</firstterm> and <firstterm>hard</firstterm>
limit. A soft limit may be adjusted by the user or
application, but may not be set higher than the hard limit.
The hard limit may be lowered by the user, but can only be
raised by the superuser. Second, most resource limits apply
per process to a specific user.</para>
<para><xref linkend="resource-limits"/> lists the most commonly
used resource limits. All of the available resource limits
and capabilities are described in detail in
&man.login.conf.5;.</para>
<indexterm>
<primary>limiting users</primary>
<secondary>coredumpsize</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>cputime</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>filesize</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>maxproc</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>memorylocked</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>memoryuse</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>openfiles</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>sbsize</secondary>
</indexterm>
<indexterm>
<primary>limiting users</primary>
<secondary>stacksize</secondary>
</indexterm>
<table xml:id="resource-limits" frame="none" pgwide="1">
<title>Login Class Resource Limits</title>
<tgroup cols="2">
<thead>
<row>
<entry>Resource Limit</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>coredumpsize</entry>
<entry>The limit on the size of a core file generated by
a program is subordinate to other limits on disk
usage, such as <literal>filesize</literal> or disk
quotas. This limit is often used as a less severe
method of controlling disk space consumption. Since
users do not generate core files and often do not
delete them, this setting may save them from running
out of disk space should a large program
crash.</entry>
</row>
<row>
<entry>cputime</entry>
<entry>The maximum amount of <acronym>CPU</acronym> time
a user's process may consume. Offending processes
will be killed by the kernel. This is a limit on
<acronym>CPU</acronym> <emphasis>time</emphasis>
consumed, not the percentage of the
<acronym>CPU</acronym> as displayed in some of the
fields generated by <command>top</command> and
<command>ps</command>.</entry>
</row>
<row>
<entry>filesize</entry>
<entry>The maximum size of a file the user may own.
Unlike disk quotas (<xref linkend="quotas"/>), this
limit is enforced on individual files, not the set of
all files a user owns.</entry>
</row>
<row>
<entry>maxproc</entry>
<entry>The maximum number of foreground and background
processes a user can run. This limit may not be
larger than the system limit specified by
<varname>kern.maxproc</varname>. Setting this limit
too small may hinder a user's productivity as some
tasks, such as compiling a large program, start lots
of processes.</entry>
</row>
<row>
<entry>memorylocked</entry>
<entry>The maximum amount of memory a process may
request to be locked into main memory using
&man.mlock.2;. Some system-critical programs, such as
&man.amd.8;, lock into main memory so that if the
system begins to swap, they do not contribute to disk
thrashing.</entry>
</row>
<row>
<entry>memoryuse</entry>
<entry>The maximum amount of memory a process may
consume at any given time. It includes both core
memory and swap usage. This is not a catch-all limit
for restricting memory consumption, but is a good
start.</entry>
</row>
<row>
<entry>openfiles</entry>
<entry>The maximum number of files a process may have
open. In &os;, files are used to represent sockets
and <acronym>IPC</acronym> channels, so be careful not
to set this too low. The system-wide limit for this
is defined by
<varname>kern.maxfiles</varname>.</entry>
</row>
<row>
<entry>sbsize</entry>
<entry>The limit on the amount of network memory a user
may consume. This can be generally used to limit
network communications.</entry>
</row>
<row>
<entry>stacksize</entry>
<entry>The maximum size of a process stack. This alone
is not sufficient to limit the amount of memory a
program may use, so it should be used in conjunction
with other limits.</entry>
</row>
</tbody>
</tgroup>
</table>
<para>There are a few other things to remember when setting
resource limits:</para>
<itemizedlist>
<listitem>
<para>Processes started at system startup by
<filename>/etc/rc</filename> are assigned to the
<literal>daemon</literal> login class.</para>
</listitem>
<listitem>
<para>Although the default
<filename>/etc/login.conf</filename> is a good source of
reasonable values for most limits, they may not be
appropriate for every system. Setting a limit too high
may open the system up to abuse, while setting it too low
may put a strain on productivity.</para>
</listitem>
<listitem>
<para><application>&xorg;</application> takes a lot of
resources and encourages users to run more programs
simultaneously.</para>
</listitem>
<listitem>
<para>Many limits apply to individual processes, not the
user as a whole. For example, setting
<varname>openfiles</varname> to <literal>50</literal>
means that each process the user runs may open up to
<literal>50</literal> files. The total amount of files a
user may open is the value of <literal>openfiles</literal>
multiplied by the value of <literal>maxproc</literal>.
This also applies to memory consumption.</para>
</listitem>
</itemizedlist>
<para>For further information on resource limits and login
classes and capabilities in general, refer to
&man.cap.mkdb.1;, &man.getrlimit.2;, and
&man.login.conf.5;.</para>
</sect2>
<sect2>
<title>Enabling and Configuring Resource Limits</title>
<para>The <varname>kern.racct.enable</varname> tunable must be
set to a non-zero value. Custom kernels require specific
configuration:</para>
<programlisting>options RACCT
options RCTL</programlisting>
<para>Once the system has rebooted into the new kernel,
<command>rctl</command> may be used to set rules for the
system.</para>
<para>Rule syntax is controlled through the use of a subject,
subject-id, resource, and action, as seen in this example
rule:</para>
<programlisting>user:trhodes:maxproc:deny=10/user</programlisting>
<para>In this rule, the subject is <literal>user</literal>, the
subject-id is <literal>trhodes</literal>, the resource,
<literal>maxproc</literal>, is the maximum number of
processes, and the action is <literal>deny</literal>, which
blocks any new processes from being created. This means that
the user, <literal>trhodes</literal>, will be constrained to
no greater than <literal>10</literal> processes. Other
possible actions include logging to the console, passing a
notification to &man.devd.8;, or sending a sigterm to the
process.</para>
<para>Some care must be taken when adding rules. Since this
user is constrained to <literal>10</literal> processes, this
example will prevent the user from performing other tasks
after logging in and executing a
<command>screen</command> session. Once a resource limit has
been hit, an error will be printed, as in this example:</para>
<screen>&prompt.user; <userinput>man test</userinput>
/usr/bin/man: Cannot fork: Resource temporarily unavailable
eval: Cannot fork: Resource temporarily unavailable</screen>
<para>As another example, a jail can be prevented from exceeding
a memory limit. This rule could be written as:</para>
<screen>&prompt.root; <userinput>rctl -a jail:httpd:memoryuse:deny=2G/jail</userinput></screen>
<para>Rules will persist across reboots if they have been added
to <filename>/etc/rctl.conf</filename>. The format is a rule,
without the preceding command. For example, the previous rule
could be added as:</para>
<programlisting># Block jail from using more than 2G memory:
jail:httpd:memoryuse:deny=2G/jail</programlisting>
<para>To remove a rule, use <command>rctl</command> to remove it
from the list:</para>
<screen>&prompt.root; <userinput>rctl -r user:trhodes:maxproc:deny=10/user</userinput></screen>
<para>A method for removing all rules is documented in
&man.rctl.8;. However, if removing all rules for a single
user is required, this command may be issued:</para>
<screen>&prompt.root; <userinput>rctl -r user:trhodes</userinput></screen>
<para>Many other resources exist which can be used to exert
additional control over various <literal>subjects</literal>.
See &man.rctl.8; to learn about them.</para>
</sect2>
</sect1>
<sect1 xml:id="security-sudo">
<info>
<title>Shared Administration with Sudo</title>
<authorgroup>
<author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm>
<primary>Security</primary>
<secondary>Sudo</secondary>
</indexterm>
<para>System administrators often need the ability to grant
enhanced permissions to users so they may perform privileged
tasks. The idea that team members are provided access
to a &os; system to perform their specific tasks opens up unique
challenges to every administrator. These team members only
need a subset of access beyond normal end user levels; however,
they almost always tell management they are unable to
perform their tasks without superuser access. Thankfully, there
is no reason to provide such access to end users because tools
exist to manage this exact requirement.</para>
<para>Up to this point, the security chapter has covered
permitting access to authorized users and attempting to prevent
unauthorized access. Another problem arises once authorized
users have access to the system resources. In many cases, some
users may need access to application startup scripts, or a team
of administrators need to maintain the system. Traditionally,
the standard users and groups, file permissions, and even the
&man.su.1; command would manage this access. And as
applications required more access, as more users needed to use
system resources, a better solution was required. The most used
application is currently <application>Sudo</application>.</para>
<para><application>Sudo</application> allows administrators
to configure more rigid access to system commands
and provide for some advanced logging features.
As a tool, it is available from the Ports Collection as
<package role="port">security/sudo</package> or by use of
the &man.pkg.8; utility. To use the &man.pkg.8; tool:</para>
<screen>&prompt.root; <userinput>pkg install sudo</userinput></screen>
<para>After the installation is complete, the installed
<command>visudo</command> will open the configuration file with
a text editor. Using <command>visudo</command> is highly
recommended as it comes with a built in syntax checker to verify
there are no errors before the file is saved.</para>
<para>The configuration file is made up of several small sections
which allow for extensive configuration. In the following
example, web application maintainer, user1, needs to start,
stop, and restart the web application known as
<replaceable>webservice</replaceable>. To
grant this user permission to perform these tasks, add
this line to the end of
<filename>/usr/local/etc/sudoers</filename>:</para>
<programlisting>user1 ALL=(ALL) /usr/sbin/service webservice *</programlisting>
<para>The user may now start <replaceable>webservice</replaceable>
using this command:</para>
<screen>&prompt.user; <userinput>sudo /usr/sbin/service <replaceable>webservice</replaceable> start</userinput></screen>
<para>While this configuration allows a single user access to the
<application>webservice</application> service; however, in most
organizations, there is an entire web team in charge of managing
the service. A single line can also give access to an entire
group. These steps will create a web group, add a user to this
group, and allow all members of the group to manage the
service:</para>
<screen>&prompt.root; <userinput>pw groupadd -g 6001 -n webteam</userinput></screen>
<para>Using the same &man.pw.8; command, the user is added to
the webteam group:</para>
<screen>&prompt.root; <userinput>pw groupmod -m user1 -n webteam</userinput></screen>
<para>Finally, this line in
<filename>/usr/local/etc/sudoers</filename> allows any
member of the webteam group to manage
<replaceable>webservice</replaceable>:</para>
<programlisting>%webteam ALL=(ALL) /usr/sbin/service webservice *</programlisting>
<para>Unlike &man.su.1;, <application>Sudo</application> only
requires the end user password. This adds an advantage where
users will not need shared passwords, a finding in most security
audits and just bad all the way around.</para>
<para>Users permitted to run applications with
<application>Sudo</application> only enter their own passwords.
This is more secure and gives better control than &man.su.1;,
where the <systemitem class="username">root</systemitem>
password is entered and the user acquires all
<systemitem class="username">root</systemitem>
permissions.</para>
<tip>
<para>Most organizations are moving or have moved toward a two
factor authentication model. In these cases, the user may not
have a password to enter. <application>Sudo</application>
provides for these cases with the <literal>NOPASSWD</literal>
variable. Adding it to the configuration above will allow all
members of the <replaceable>webteam</replaceable> group to
manage the service without the password requirement:</para>
<programlisting>%webteam ALL=(ALL) NOPASSWD: /usr/sbin/service webservice *</programlisting>
</tip>
<sect2 xml:id="security-sudo-loggin">
<title>Logging Output</title>
<para>An advantage to implementing
<application>Sudo</application> is the ability to enable
session logging. Using the built in log mechanisms
and the included <application>sudoreplay</application>
command, all commands initiated through
<application>Sudo</application> are logged for later
verification. To enable this feature, add a default log
directory entry, this example uses a user variable.
Several other log filename conventions exist, consult the
manual page for <application>sudoreplay</application> for
additional information.</para>
<programlisting>Defaults iolog_dir=/var/log/sudo-io/%{user}</programlisting>
<tip>
<para>This directory will be created automatically after the
logging is configured. It is best to let the system create
directory with default permissions just to be safe. In
addition, this entry will also log administrators who use
the <application>sudoreplay</application> command. To
change this behavior, read and uncomment the logging options
inside <filename>sudoers</filename>.</para>
</tip>
<para>Once this directive has been added to the
<filename>sudoers</filename> file, any user configuration can
be updated with the request to log access. In the example
shown, the updated <replaceable>webteam</replaceable> entry
would have the following additional changes:</para>
<programlisting>%webteam ALL=(ALL) NOPASSWD: LOG_INPUT: LOG_OUTPUT: /usr/sbin/service webservice *</programlisting>
<para>From this point on, all <replaceable>webteam</replaceable>
members altering the status of the
<replaceable>webservice</replaceable> application
will be logged. The list of previous and current sessions
can be displayed with:</para>
<screen>&prompt.root; <userinput>sudoreplay -l</userinput></screen>
<para>In the output, to replay a specific session, search for
the <literal>TSID=</literal> entry, and pass that to
<application>sudoreplay</application> with no other options to
replay the session at normal speed. For example:</para>
<screen>&prompt.root; <userinput>sudoreplay user1/00/00/02</userinput></screen>
<warning>
<para>While sessions are logged, any administrator is able to
remove sessions and leave only a question of why they had
done so. It is worthwhile to add a daily check through an
intrusion detection system (<acronym>IDS</acronym>) or
similar software so that other administrators are alerted to
manual alterations.</para>
</warning>
<para>The <command>sudoreplay</command> is extremely extendable.
Consult the documentation for more information.</para>
</sect2>
</sect1>
</chapter>