character set, they may be replaced/re-encoded. Try to inhibit auto-conversion to UTF-8, until we (inevitably?) switch to el_GR.UTF-8 some time in the future. Obtained from: FreeBSD Greek Documentation Project
4996 lines
210 KiB
Text
4996 lines
210 KiB
Text
<!--
|
||
|
||
Το Εγχειρίδιο του FreeBSD: Ασφάλεια
|
||
|
||
The FreeBSD Greek Documentation Project
|
||
|
||
$FreeBSD$
|
||
|
||
%SOURCE% en_US.ISO8859-1/books/handbook/security/chapter.sgml
|
||
%SRCID% 1.1
|
||
|
||
-->
|
||
|
||
<chapter id="security">
|
||
<chapterinfo>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Matthew</firstname>
|
||
<surname>Dillon</surname>
|
||
<contrib>Το μεγαλύτερο μέρος αυτού του κεφαλαίου προέρχεται από την
|
||
σελίδα του manual της security(7) από τον </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</chapterinfo>
|
||
|
||
<title>Ασφάλεια</title>
|
||
<indexterm><primary>ασφάλεια</primary></indexterm>
|
||
|
||
<sect1 id="security-synopsis">
|
||
<title>Σύνοψη</title>
|
||
|
||
<para>Το κεφάλαιο αυτό παρέχει μια βασική εισαγωγή στις έννοιες της
|
||
ασφάλειας συστήματος, κάποιους γενικά καλούς κανόνες, και ορισμένα
|
||
προχωρημένα θέματα σχετικά με το &os;. Αρκετά από τα θέματα που
|
||
καλύπτονται εδώ, μπορούν να εφαρμοστούν το ίδιο καλά τόσο στο ίδιο το
|
||
σύστημα, όσο και για ασφάλεια μέσω Internet. Το Internet δεν είναι
|
||
πλέον ένα <quote>φιλικό</quote> μέρος στο οποίο καθένας θέλει να είναι
|
||
ο ευγενικός σας γείτονας. Η ανάγκη ασφάλισης του συστήματος σας είναι
|
||
επιτακτική για να προστατέψετε τα δεδομένα σας,την πνευματική σας
|
||
ιδιοκτησία, το χρόνο σας, και πολλά περισσότερα από τα χέρια των χάκερς
|
||
και των ομοίων τους.</para>
|
||
|
||
<para>Το &os; παρέχει μια σειρά από βοηθητικά προγράμματα και μηχανισμούς
|
||
για να εξασφαλίσει την ακεραιότητα και την ασφάλεια του συστήματος σας
|
||
και του δικτύου.</para>
|
||
|
||
<para>Αφού διαβάσετε αυτό το κεφάλαιο, θα ξέρετε:</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Βασικές έννοιες για την ασφάλεια, σε σχέση με το &os;.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Στοιχεία σχετικά με τους διάφορους μηχανισμούς κρυπτογράφησης
|
||
που είναι διαθέσιμοι στο &os;, όπως το <acronym>DES</acronym> και
|
||
το <acronym>MD5</acronym>.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να ρυθμίσετε το σύστημα σας για κωδικούς μιας χρήσης.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να ρυθμίσετε <acronym>TCP</acronym> Wrappers για χρήση με
|
||
την <command>inetd</command>.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να ρυθμίσετε τον <application>KerberosIV</application> σε
|
||
&os; εκδόσεις πριν τη 5.0.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να ρυθμίσετε τον <application>Kerberos5</application> στο
|
||
&os;.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να ρυθμίσετε το IPsec και να δημιουργήσετε ένα
|
||
<acronym>VPN</acronym> μεταξύ μηχανημάτων &os;/&windows;.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να ρυθμίσετε και να χρησιμοποιήσετε την κατά &os; υλοποίηση
|
||
<acronym>SSH</acronym> του <application>OpenSSH</application>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Τι είναι τα <acronym>ACL</acronym>s στο σύστημα αρχείων και πως
|
||
να τα χρησιμοποιήσετε.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να χρησιμοποιήσετε το βοηθητικό πρόγραμμα
|
||
<application>Portaudit</application> για να ελέγξετε λογισμικό
|
||
τρίτου κατασκευαστή που έχει εγκατασταθεί μέσω της συλλογής Ports.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Πως να χρησιμοποιήσετε τις δημοσιεύσεις security advisories
|
||
του &os;.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Θα έχετε μια ιδέα για το τι είναι το Process Accounting και πως
|
||
να το ενεργοποιήσετε στο &os;.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>Πριν διαβάσετε αυτό το κεφάλαιο, θα πρέπει:</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Να κατανοείτε βασικές έννοιες του &os; και του Internet.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>Πρόσθετα θέματα σχετικά με την ασφάλεια καλύπτονται σε ολόκληρο το
|
||
βιβλίο. Για παράδειγμα, ο Υποχρεωτικός Έλεγχος Πρόσβασης συζητείται
|
||
στο <xref linkend="mac"> και τα Internet Firewalls συζητούνται στο
|
||
<xref linkend="firewalls">.</para>
|
||
</sect1>
|
||
|
||
<sect1 id="security-intro">
|
||
<title>Introduction</title>
|
||
|
||
<para>Security is a function that begins and ends with the system
|
||
administrator. While all BSD &unix; multi-user systems have some
|
||
inherent security, the job of building and maintaining additional
|
||
security mechanisms to keep those users <quote>honest</quote> is
|
||
probably one of the single largest undertakings of the sysadmin.
|
||
Machines are only as secure as you make them, and security concerns
|
||
are ever competing with the human necessity for convenience. &unix;
|
||
systems, in general, are capable of running a huge number of
|
||
simultaneous processes and many of these processes operate as
|
||
servers — meaning that external entities can connect and talk
|
||
to them. As yesterday's mini-computers and mainframes become
|
||
today's desktops, and as computers become networked and
|
||
inter-networked, security becomes an even bigger issue.</para>
|
||
|
||
<para>System security also pertains to dealing with various forms of
|
||
attack, including attacks that attempt to crash, or otherwise make a
|
||
system unusable, but do not attempt to compromise the
|
||
<username>root</username> account (<quote>break root</quote>).
|
||
Security concerns
|
||
can be split up into several categories:</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Denial of service attacks.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>User account compromises.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Root compromise through accessible servers.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Root compromise via user accounts.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Backdoor creation.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<indexterm>
|
||
<primary>DoS attacks</primary>
|
||
<see>Denial of Service (DoS)</see>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary>security</primary>
|
||
<secondary>DoS attacks</secondary>
|
||
<see>Denial of Service (DoS)</see>
|
||
</indexterm>
|
||
<indexterm><primary>Denial of Service (DoS)</primary></indexterm>
|
||
|
||
<para>A denial of service attack is an action that deprives the
|
||
machine of needed resources. Typically, DoS attacks are
|
||
brute-force mechanisms that attempt to crash or otherwise make a
|
||
machine unusable by overwhelming its servers or network stack. Some
|
||
DoS attacks try to take advantage of bugs in the networking
|
||
stack to crash a machine with a single packet. The latter can only
|
||
be fixed by applying a bug fix to the kernel. Attacks on servers
|
||
can often be fixed by properly specifying options to limit the load
|
||
the servers incur on the system under adverse conditions.
|
||
Brute-force network attacks are harder to deal with. A
|
||
spoofed-packet attack, for example, is nearly impossible to stop,
|
||
short of cutting your system off from the Internet. It may not be
|
||
able to take your machine down, but it can saturate your
|
||
Internet connection.</para>
|
||
|
||
<indexterm>
|
||
<primary>security</primary>
|
||
<secondary>account compromises</secondary>
|
||
</indexterm>
|
||
|
||
<para>A user account compromise is even more common than a DoS
|
||
attack. Many sysadmins still run standard
|
||
<application>telnetd</application>, <application>rlogind</application>,
|
||
<application>rshd</application>,
|
||
and <application>ftpd</application> servers on their machines.
|
||
These servers, by default, do
|
||
not operate over encrypted connections. The result is that if you
|
||
have any moderate-sized user base, one or more of your users logging
|
||
into your system from a remote location (which is the most common
|
||
and convenient way to login to a system) will have his or her
|
||
password sniffed. The attentive system admin will analyze his
|
||
remote access logs looking for suspicious source addresses even for
|
||
successful logins.</para>
|
||
|
||
<para>One must always assume that once an attacker has access to a
|
||
user account, the attacker can break <username>root</username>.
|
||
However, the reality is that in a well secured and maintained system,
|
||
access to a user account does not necessarily give the attacker
|
||
access to <username>root</username>. The distinction is important
|
||
because without access to <username>root</username> the attacker
|
||
cannot generally hide his tracks and may, at best, be able to do
|
||
nothing more than mess with the user's files, or crash the machine.
|
||
User account compromises are very common because users tend not to
|
||
take the precautions that sysadmins take.</para>
|
||
|
||
<indexterm>
|
||
<primary>security</primary>
|
||
<secondary>backdoors</secondary>
|
||
</indexterm>
|
||
|
||
<para>System administrators must keep in mind that there are
|
||
potentially many ways to break <username>root</username> on a machine.
|
||
The attacker may know the <username>root</username> password,
|
||
the attacker may find a bug in a root-run server and be able
|
||
to break <username>root</username> over a network
|
||
connection to that server, or the attacker may know of a bug in
|
||
a suid-root program that allows the attacker to break
|
||
<username>root</username> once he has broken into a user's account.
|
||
If an attacker has found a way to break <username>root</username>
|
||
on a machine, the attacker may not have a need
|
||
to install a backdoor. Many of the <username>root</username> holes
|
||
found and closed to date involve a considerable amount of work
|
||
by the attacker to cleanup after himself, so most attackers install
|
||
backdoors. A backdoor provides the attacker with a way to easily
|
||
regain <username>root</username> access to the system, but it
|
||
also gives the smart system administrator a convenient way
|
||
to detect the intrusion.
|
||
Making it impossible for an attacker to install a backdoor may
|
||
actually be detrimental to your security, because it will not
|
||
close off the hole the attacker found to break in the first
|
||
place.</para>
|
||
|
||
|
||
<para>Security remedies should always be implemented with a
|
||
multi-layered <quote>onion peel</quote> approach and can be
|
||
categorized as follows:</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Securing <username>root</username> and staff accounts.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Securing <username>root</username>–run servers
|
||
and suid/sgid binaries.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Securing user accounts.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Securing the password file.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Securing the kernel core, raw devices, and
|
||
file systems.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Quick detection of inappropriate changes made to the
|
||
system.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Paranoia.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>The next section of this chapter will cover the above bullet
|
||
items in greater depth.</para>
|
||
</sect1>
|
||
|
||
<sect1 id="securing-freebsd">
|
||
<title>Securing &os;</title>
|
||
<indexterm>
|
||
<primary>security</primary>
|
||
<secondary>securing &os;</secondary>
|
||
</indexterm>
|
||
|
||
<note>
|
||
<title>Command vs. Protocol</title>
|
||
<para>Throughout this document, we will use
|
||
<application>bold</application> text to refer to an
|
||
application, and a <command>monospaced</command> font to refer
|
||
to specific commands. Protocols will use a normal font. This
|
||
typographical distinction is useful for instances such as ssh,
|
||
since it is
|
||
a protocol as well as command.</para>
|
||
</note>
|
||
|
||
<para>The sections that follow will cover the methods of securing your
|
||
&os; system that were mentioned in the <link
|
||
linkend="security-intro">last section</link> of this chapter.</para>
|
||
|
||
<sect2 id="securing-root-and-staff">
|
||
<title>Securing the <username>root</username> Account and
|
||
Staff Accounts</title>
|
||
<indexterm>
|
||
<primary><command>su</command></primary>
|
||
</indexterm>
|
||
|
||
<para>First off, do not bother securing staff accounts if you have
|
||
not secured the <username>root</username> account.
|
||
Most systems have a password assigned to the <username>root</username>
|
||
account. The first thing you do is assume
|
||
that the password is <emphasis>always</emphasis> compromised.
|
||
This does not mean that you should remove the password. The
|
||
password is almost always necessary for console access to the
|
||
machine. What it does mean is that you should not make it
|
||
possible to use the password outside of the console or possibly
|
||
even with the &man.su.1; command. For example, make sure that
|
||
your ptys are specified as being insecure in the
|
||
<filename>/etc/ttys</filename> file so that direct
|
||
<username>root</username> logins
|
||
via <command>telnet</command> or <command>rlogin</command> are
|
||
disallowed. If using other login services such as
|
||
<application>sshd</application>, make sure that direct
|
||
<username>root</username> logins are disabled there as well.
|
||
You can do this by editing
|
||
your <filename>/etc/ssh/sshd_config</filename> file, and making
|
||
sure that <literal>PermitRootLogin</literal> is set to
|
||
<literal>NO</literal>. Consider every access method —
|
||
services such as FTP often fall through the cracks.
|
||
Direct <username>root</username> logins should only be allowed
|
||
via the system console.</para>
|
||
<indexterm>
|
||
<primary><groupname>wheel</groupname></primary>
|
||
</indexterm>
|
||
|
||
<para>Of course, as a sysadmin you have to be able to get to
|
||
<username>root</username>, so we open up a few holes.
|
||
But we make sure these holes require additional password
|
||
verification to operate. One way to make <username>root</username>
|
||
accessible is to add appropriate staff accounts to the
|
||
<groupname>wheel</groupname> group (in
|
||
<filename>/etc/group</filename>). The staff members placed in the
|
||
<groupname>wheel</groupname> group are allowed to
|
||
<command>su</command> to <username>root</username>.
|
||
You should never give staff
|
||
members native <groupname>wheel</groupname> access by putting them in the
|
||
<groupname>wheel</groupname> group in their password entry. Staff
|
||
accounts should be placed in a <groupname>staff</groupname> group, and
|
||
then added to the <groupname>wheel</groupname> group via the
|
||
<filename>/etc/group</filename> file. Only those staff members
|
||
who actually need to have <username>root</username> access
|
||
should be placed in the
|
||
<groupname>wheel</groupname> group. It is also possible, when using
|
||
an authentication method such as Kerberos, to use Kerberos'
|
||
<filename>.k5login</filename> file in the <username>root</username>
|
||
account to allow a &man.ksu.1; to <username>root</username>
|
||
without having to place anyone at all in the
|
||
<groupname>wheel</groupname> group. This may be the better solution
|
||
since the <groupname>wheel</groupname> mechanism still allows an
|
||
intruder to break <username>root</username> if the intruder
|
||
has gotten hold of your
|
||
password file and can break into a staff account. While having
|
||
the <groupname>wheel</groupname> mechanism is better than having
|
||
nothing at all, it is not necessarily the safest option.</para>
|
||
|
||
<!-- XXX:
|
||
This will need updating depending on the outcome of PR bin/71147.
|
||
Personally I know what I'd like to see, which puts this in definite
|
||
need of a rewrite, but we'll have to wait and see. ceri@
|
||
-->
|
||
|
||
<para>An indirect way to secure staff accounts, and ultimately
|
||
<username>root</username> access is to use an alternative
|
||
login access method and
|
||
do what is known as <quote>starring</quote> out the encrypted
|
||
password for the staff accounts. Using the &man.vipw.8;
|
||
command, one can replace each instance of an encrypted password
|
||
with a single <quote><literal>*</literal></quote> character.
|
||
This command will update the <filename>/etc/master.passwd</filename>
|
||
file and user/password database to disable password-authenticated
|
||
logins.</para>
|
||
|
||
<para>A staff account entry such as:</para>
|
||
|
||
<programlisting>foobar:R9DT/Fa1/LV9U:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh</programlisting>
|
||
|
||
<para>Should be changed to this:</para>
|
||
|
||
<programlisting>foobar:*:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh</programlisting>
|
||
|
||
<para>This change will prevent normal logins from occurring,
|
||
since the encrypted password will never match
|
||
<quote><literal>*</literal></quote>. With this done,
|
||
staff members must use
|
||
another mechanism to authenticate themselves such as
|
||
&man.kerberos.1; or &man.ssh.1; using a public/private key
|
||
pair. When using something like Kerberos, one generally must
|
||
secure the machines which run the Kerberos servers and your
|
||
desktop workstation. When using a public/private key pair
|
||
with ssh, one must generally secure
|
||
the machine used to login <emphasis>from</emphasis> (typically
|
||
one's workstation). An additional layer of protection can be
|
||
added to the key pair by password protecting the key pair when
|
||
creating it with &man.ssh-keygen.1;. Being able to
|
||
<quote>star</quote> out the passwords for staff accounts also
|
||
guarantees that staff members can only login through secure
|
||
access methods that you have set up. This forces all staff
|
||
members to use secure, encrypted connections for all of their
|
||
sessions, which closes an important hole used by many
|
||
intruders: sniffing the network from an unrelated,
|
||
less secure machine.</para>
|
||
|
||
<para>The more indirect security mechanisms also assume that you are
|
||
logging in from a more restrictive server to a less restrictive
|
||
server. For example, if your main box is running all sorts of
|
||
servers, your workstation should not be running any. In order for
|
||
your workstation to be reasonably secure you should run as few
|
||
servers as possible, up to and including no servers at all, and
|
||
you should run a password-protected screen blanker. Of course,
|
||
given physical access to a workstation an attacker can break any
|
||
sort of security you put on it. This is definitely a problem that
|
||
you should consider, but you should also consider the fact that the
|
||
vast majority of break-ins occur remotely, over a network, from
|
||
people who do not have physical access to your workstation or
|
||
servers.</para>
|
||
<indexterm><primary>KerberosIV</primary></indexterm>
|
||
|
||
<para>Using something like Kerberos also gives you the ability to
|
||
disable or change the password for a staff account in one place,
|
||
and have it immediately affect all the machines on which the staff
|
||
member may have an account. If a staff member's account gets
|
||
compromised, the ability to instantly change his password on all
|
||
machines should not be underrated. With discrete passwords,
|
||
changing a password on N machines can be a mess. You can also
|
||
impose re-passwording restrictions with Kerberos: not only can a
|
||
Kerberos ticket be made to timeout after a while, but the Kerberos
|
||
system can require that the user choose a new password after a
|
||
certain period of time (say, once a month).</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Securing Root-run Servers and SUID/SGID Binaries</title>
|
||
|
||
<indexterm>
|
||
<primary><command>ntalk</command></primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary><command>comsat</command></primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary><command>finger</command></primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary>sandboxes</primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary><application>sshd</application></primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary><application>telnetd</application></primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary><application>rshd</application></primary>
|
||
</indexterm>
|
||
<indexterm>
|
||
<primary><application>rlogind</application></primary>
|
||
</indexterm>
|
||
|
||
<para>The prudent sysadmin only runs the servers he needs to, no
|
||
more, no less. Be aware that third party servers are often the
|
||
most bug-prone. For example, running an old version of
|
||
<application>imapd</application> or
|
||
<application>popper</application> is like giving a universal
|
||
<username>root</username> ticket out to the entire world.
|
||
Never run a server that you have not checked out carefully.
|
||
Many servers do not need to be run as <username>root</username>.
|
||
For example, the <application>ntalk</application>,
|
||
<application>comsat</application>, and
|
||
<application>finger</application> daemons can be run in special
|
||
user <firstterm>sandboxes</firstterm>. A sandbox is not perfect,
|
||
unless you go through a large amount of trouble, but the onion
|
||
approach to security still stands: If someone is able to break
|
||
in through a server running in a sandbox, they still have to
|
||
break out of the sandbox. The more layers the attacker must
|
||
break through, the lower the likelihood of his success. Root
|
||
holes have historically been found in virtually every server
|
||
ever run as <username>root</username>, including basic system servers.
|
||
If you are running a machine through which people only login via
|
||
<application>sshd</application> and never login via
|
||
<application>telnetd</application> or
|
||
<application>rshd</application> or
|
||
<application>rlogind</application>, then turn off those
|
||
services!</para>
|
||
|
||
<para>&os; now defaults to running
|
||
<application>ntalkd</application>,
|
||
<application>comsat</application>, and
|
||
<application>finger</application> in a sandbox. Another program
|
||
which may be a candidate for running in a sandbox is &man.named.8;.
|
||
<filename>/etc/defaults/rc.conf</filename> includes the arguments
|
||
necessary to run <application>named</application> in a sandbox in a
|
||
commented-out form. Depending on whether you are installing a new
|
||
system or upgrading an existing system, the special user accounts
|
||
used by these sandboxes may not be installed. The prudent
|
||
sysadmin would research and implement sandboxes for servers
|
||
whenever possible.</para>
|
||
<indexterm>
|
||
<primary><application>sendmail</application></primary>
|
||
</indexterm>
|
||
|
||
<para>There are a number of other servers that typically do not run
|
||
in sandboxes: <application>sendmail</application>,
|
||
<application>popper</application>,
|
||
<application>imapd</application>, <application>ftpd</application>,
|
||
and others. There are alternatives to some of these, but
|
||
installing them may require more work than you are willing to
|
||
perform (the convenience factor strikes again). You may have to
|
||
run these servers as <username>root</username> and rely on other
|
||
mechanisms to detect break-ins that might occur through them.</para>
|
||
|
||
<para>The other big potential <username>root</username> holes in a
|
||
system are the
|
||
suid-root and sgid binaries installed on the system. Most of
|
||
these binaries, such as <application>rlogin</application>, reside
|
||
in <filename>/bin</filename>, <filename>/sbin</filename>,
|
||
<filename>/usr/bin</filename>, or <filename>/usr/sbin</filename>.
|
||
While nothing is 100% safe, the system-default suid and sgid
|
||
binaries can be considered reasonably safe. Still,
|
||
<username>root</username> holes are occasionally found in these
|
||
binaries. A <username>root</username> hole was found in
|
||
<literal>Xlib</literal> in 1998 that made
|
||
<application>xterm</application> (which is typically suid)
|
||
vulnerable. It is better to be safe than sorry and the prudent
|
||
sysadmin will restrict suid binaries, that only staff should run,
|
||
to a special group that only staff can access, and get rid of
|
||
(<command>chmod 000</command>) any suid binaries that nobody uses.
|
||
A server with no display generally does not need an
|
||
<application>xterm</application> binary. Sgid binaries can be
|
||
almost as dangerous. If an intruder can break an sgid-kmem binary,
|
||
the intruder might be able to read <filename>/dev/kmem</filename>
|
||
and thus read the encrypted password file, potentially compromising
|
||
any passworded account. Alternatively an intruder who breaks
|
||
group <literal>kmem</literal> can monitor keystrokes sent through
|
||
ptys, including ptys used by users who login through secure
|
||
methods. An intruder that breaks the <groupname>tty</groupname>
|
||
group can write to
|
||
almost any user's tty. If a user is running a terminal program or
|
||
emulator with a keyboard-simulation feature, the intruder can
|
||
potentially generate a data stream that causes the user's terminal
|
||
to echo a command, which is then run as that user.</para>
|
||
</sect2>
|
||
|
||
<sect2 id="secure-users">
|
||
<title>Securing User Accounts</title>
|
||
|
||
<para>User accounts are usually the most difficult to secure. While
|
||
you can impose draconian access restrictions on your staff and
|
||
<quote>star</quote> out their passwords, you may not be able to
|
||
do so with any general user accounts you might have. If you do
|
||
have sufficient control, then you may win out and be able to secure
|
||
the user accounts properly. If not, you simply have to be more
|
||
vigilant in your monitoring of those accounts. Use of
|
||
ssh and Kerberos for user accounts is
|
||
more problematic, due to the extra administration and technical
|
||
support required, but still a very good solution compared to a
|
||
encrypted password file.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Securing the Password File</title>
|
||
|
||
<para>The only sure fire way is to star out as many
|
||
passwords as you can and use ssh or
|
||
Kerberos for access to those accounts. Even though the encrypted
|
||
password file (<filename>/etc/spwd.db</filename>) can only be read
|
||
by <username>root</username>, it may be possible for an intruder
|
||
to obtain read access to that file even if the attacker cannot
|
||
obtain root-write access.</para>
|
||
|
||
<para>Your security scripts should always check for and report
|
||
changes to the password file (see the <link
|
||
linkend="security-integrity">Checking file integrity</link> section
|
||
below).</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Securing the Kernel Core, Raw Devices, and
|
||
File systems</title>
|
||
|
||
<para>If an attacker breaks <username>root</username> he can do
|
||
just about anything, but
|
||
there are certain conveniences. For example, most modern kernels
|
||
have a packet sniffing device driver built in. Under &os; it
|
||
is called the <devicename>bpf</devicename> device. An intruder
|
||
will commonly attempt to run a packet sniffer on a compromised
|
||
machine. You do not need to give the intruder the capability and
|
||
most systems do not have the need for the
|
||
<devicename>bpf</devicename> device compiled in.</para>
|
||
|
||
<indexterm>
|
||
<primary><command>sysctl</command></primary>
|
||
</indexterm>
|
||
<para>But even if you turn off the <devicename>bpf</devicename>
|
||
device, you still have
|
||
<filename>/dev/mem</filename> and
|
||
<filename>/dev/kmem</filename>
|
||
to worry about. For that matter, the intruder can still write to
|
||
raw disk devices. Also, there is another kernel feature called
|
||
the module loader, &man.kldload.8;. An enterprising intruder can
|
||
use a KLD module to install his own <devicename>bpf</devicename>
|
||
device, or other sniffing
|
||
device, on a running kernel. To avoid these problems you have to
|
||
run the kernel at a higher secure level, at least securelevel 1.
|
||
The securelevel can be set with a <command>sysctl</command> on
|
||
the <varname>kern.securelevel</varname> variable. Once you have
|
||
set the securelevel to 1, write access to raw devices will be
|
||
denied and special <command>chflags</command> flags,
|
||
such as <literal>schg</literal>,
|
||
will be enforced. You must also ensure that the
|
||
<literal>schg</literal> flag is set on critical startup binaries,
|
||
directories, and script files — everything that gets run up
|
||
to the point where the securelevel is set. This might be overdoing
|
||
it, and upgrading the system is much more difficult when you
|
||
operate at a higher secure level. You may compromise and run the
|
||
system at a higher secure level but not set the
|
||
<literal>schg</literal> flag for every system file and directory
|
||
under the sun. Another possibility is to simply mount
|
||
<filename>/</filename> and <filename>/usr</filename> read-only.
|
||
It should be noted that being too draconian in what you attempt to
|
||
protect may prevent the all-important detection of an
|
||
intrusion.</para>
|
||
</sect2>
|
||
|
||
<sect2 id="security-integrity">
|
||
<title>Checking File Integrity: Binaries, Configuration Files,
|
||
Etc.</title>
|
||
|
||
<para>When it comes right down to it, you can only protect your core
|
||
system configuration and control files so much before the
|
||
convenience factor rears its ugly head. For example, using
|
||
<command>chflags</command> to set the <literal>schg</literal> bit
|
||
on most of the files in <filename>/</filename> and
|
||
<filename>/usr</filename> is probably counterproductive, because
|
||
while it may protect the files, it also closes a detection window.
|
||
The last layer of your security onion is perhaps the most
|
||
important — detection. The rest of your security is pretty
|
||
much useless (or, worse, presents you with a false sense of
|
||
security) if you cannot detect potential intrusions. Half the job
|
||
of the onion is to slow down the attacker, rather than stop him, in
|
||
order to be able to catch him in the act.</para>
|
||
|
||
<para>The best way to detect an intrusion is to look for modified,
|
||
missing, or unexpected files. The best way to look for modified
|
||
files is from another (often centralized) limited-access system.
|
||
Writing your security scripts on the extra-secure limited-access
|
||
system makes them mostly invisible to potential attackers, and this
|
||
is important. In order to take maximum advantage you generally
|
||
have to give the limited-access box significant access to the
|
||
other machines in the business, usually either by doing a
|
||
read-only NFS export of the other machines to the limited-access
|
||
box, or by setting up ssh key-pairs to
|
||
allow the limited-access box to ssh to
|
||
the other machines. Except for its network traffic, NFS is the
|
||
least visible method — allowing you to monitor the
|
||
file systems on each client box virtually undetected. If your
|
||
limited-access server is connected to the client boxes through a
|
||
switch, the NFS method is often the better choice. If your
|
||
limited-access server is connected to the client boxes through a
|
||
hub, or through several layers of routing, the NFS method may be
|
||
too insecure (network-wise) and using
|
||
ssh may be the better choice even with
|
||
the audit-trail tracks that ssh
|
||
lays.</para>
|
||
|
||
<para>Once you have given a limited-access box at least read access to the
|
||
client systems it is supposed to monitor, you must write scripts
|
||
to do the actual monitoring. Given an NFS mount, you can write
|
||
scripts out of simple system utilities such as &man.find.1; and
|
||
&man.md5.1;. It is best to physically md5 the client-box files
|
||
at least once a day, and to test control files such as those
|
||
found in <filename>/etc</filename> and
|
||
<filename>/usr/local/etc</filename> even more often. When
|
||
mismatches are found, relative to the base md5 information the
|
||
limited-access machine knows is valid, it should scream at a
|
||
sysadmin to go check it out. A good security script will also
|
||
check for inappropriate suid binaries and for new or deleted files
|
||
on system partitions such as <filename>/</filename> and
|
||
<filename>/usr</filename>.</para>
|
||
|
||
<para>When using ssh rather than NFS,
|
||
writing the security script is much more difficult. You
|
||
essentially have to <command>scp</command> the scripts to the client
|
||
box in order to
|
||
run them, making them visible, and for safety you also need to
|
||
<command>scp</command> the binaries (such as find) that those
|
||
scripts use. The <application>ssh</application> client on the
|
||
client box may already be compromised. All in all, using
|
||
ssh may be necessary when running over
|
||
insecure links, but it is also a lot harder to deal with.</para>
|
||
|
||
<para>A good security script will also check for changes to user and
|
||
staff members access configuration files:
|
||
<filename>.rhosts</filename>, <filename>.shosts</filename>,
|
||
<filename>.ssh/authorized_keys</filename> and so forth,
|
||
files that might fall outside the purview of the
|
||
<literal>MD5</literal> check.</para>
|
||
|
||
<para>If you have a huge amount of user disk space, it may take too
|
||
long to run through every file on those partitions. In this case,
|
||
setting mount flags to disallow suid binaries and devices on those
|
||
partitions is a good idea. The <literal>nodev</literal> and
|
||
<literal>nosuid</literal> options (see &man.mount.8;) are what you
|
||
want to look into. You should probably scan them anyway, at least
|
||
once a week, since the object of this layer is to detect a break-in
|
||
attempt, whether or not the attempt succeeds.</para>
|
||
|
||
<para>Process accounting (see &man.accton.8;) is a relatively
|
||
low-overhead feature of the operating system which might help
|
||
as a post-break-in evaluation mechanism. It is especially
|
||
useful in tracking down how an intruder has actually broken into
|
||
a system, assuming the file is still intact after the break-in has
|
||
occured.</para>
|
||
|
||
<para>Finally, security scripts should process the log files, and the
|
||
logs themselves should be generated in as secure a manner as
|
||
possible — remote syslog can be very useful. An intruder
|
||
will try to cover his tracks, and log files are critical to the
|
||
sysadmin trying to track down the time and method of the initial
|
||
break-in. One way to keep a permanent record of the log files is
|
||
to run the system console to a serial port and collect the
|
||
information to a secure machine monitoring the consoles.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Paranoia</title>
|
||
|
||
<para>A little paranoia never hurts. As a rule, a sysadmin can add
|
||
any number of security features, as long as they do not affect
|
||
convenience, and can add security features that
|
||
<emphasis>do</emphasis> affect convenience with some added thought.
|
||
Even more importantly, a security administrator should mix it up a
|
||
bit — if you use recommendations such as those given by this
|
||
document verbatim, you give away your methodologies to the
|
||
prospective attacker who also has access to this document.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Denial of Service Attacks</title>
|
||
<indexterm><primary>Denial of Service (DoS)</primary></indexterm>
|
||
|
||
<para>This section covers Denial of Service attacks. A DoS attack
|
||
is typically a packet attack. While there is not much you can do
|
||
about modern spoofed packet attacks that saturate your network,
|
||
you can generally limit the damage by ensuring that the attacks
|
||
cannot take down your servers by:</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Limiting server forks.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Limiting springboard attacks (ICMP response attacks, ping
|
||
broadcast, etc.).</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Overloading the Kernel Route Cache.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>A common DoS attack scenario is attacking a forking server and
|
||
making it spawning so many child processes that the host system
|
||
eventually runs out of memory, file descriptors, etc. and then
|
||
grinds to a halt. <application>inetd</application>
|
||
(see &man.inetd.8;) has several
|
||
options to limit this sort of attack. It should be noted that
|
||
while it is possible to prevent a machine from going down, it is
|
||
not generally possible to prevent a service from being disrupted
|
||
by the attack. Read the <application>inetd</application> manual
|
||
page carefully and pay
|
||
specific attention to the <option>-c</option>, <option>-C</option>,
|
||
and <option>-R</option> options. Note that spoofed-IP attacks
|
||
will circumvent the <option>-C</option> option to
|
||
<application>inetd</application>, so
|
||
typically a combination of options must be used. Some standalone
|
||
servers have self-fork-limitation parameters.</para>
|
||
|
||
<para><application>Sendmail</application> has its
|
||
<option>-OMaxDaemonChildren</option> option, which tends to work
|
||
much better than trying to use <application>Sendmail</application>'s load limiting options
|
||
due to the load lag. You should specify a
|
||
<literal>MaxDaemonChildren</literal> parameter, when you start
|
||
<application>sendmail</application>; high enough to handle your
|
||
expected load, but not so high that the computer cannot handle that
|
||
number of <application>Sendmail</application> instances without falling on
|
||
its face. It is also prudent to run <application>Sendmail</application> in queued mode
|
||
(<option>-ODeliveryMode=queued</option>) and to run the daemon
|
||
(<command>sendmail -bd</command>) separate from the queue-runs
|
||
(<command>sendmail -q15m</command>). If you still want real-time
|
||
delivery you can run the queue at a much lower interval, such as
|
||
<option>-q1m</option>, but be sure to specify a reasonable
|
||
<literal>MaxDaemonChildren</literal> option for
|
||
<emphasis>that</emphasis> <application>Sendmail</application> to prevent cascade failures.</para>
|
||
|
||
<para><application>Syslogd</application> can be attacked directly
|
||
and it is strongly recommended that you use the <option>-s</option>
|
||
option whenever possible, and the <option>-a</option> option
|
||
otherwise.</para>
|
||
|
||
<para>You should also be fairly careful with connect-back services
|
||
such as <application>TCP Wrapper</application>'s reverse-identd,
|
||
which can be attacked directly. You generally do not want to use
|
||
the reverse-ident feature of
|
||
<application>TCP Wrapper</application> for this reason.</para>
|
||
|
||
<para>It is a very good idea to protect internal services from
|
||
external access by firewalling them off at your border routers.
|
||
The idea here is to prevent saturation attacks from outside your
|
||
LAN, not so much to protect internal services from network-based
|
||
<username>root</username> compromise.
|
||
Always configure an exclusive firewall, i.e.,
|
||
<quote>firewall everything <emphasis>except</emphasis> ports A, B,
|
||
C, D, and M-Z</quote>. This way you can firewall off all of your
|
||
low ports except for certain specific services such as
|
||
<application>named</application> (if you are primary for a zone),
|
||
<application>ntalkd</application>,
|
||
<application>sendmail</application>, and other Internet-accessible
|
||
services. If you try to configure the firewall the other way
|
||
— as an inclusive or permissive firewall, there is a good
|
||
chance that you will forget to <quote>close</quote> a couple of
|
||
services, or that you will add a new internal service and forget
|
||
to update the firewall. You can still open up the high-numbered
|
||
port range on the firewall, to allow permissive-like operation,
|
||
without compromising your low ports. Also take note that &os;
|
||
allows you to control the range of port numbers used for dynamic
|
||
binding, via the various <varname>net.inet.ip.portrange</varname>
|
||
<command>sysctl</command>'s (<command>sysctl -a | fgrep
|
||
portrange</command>), which can also ease the complexity of your
|
||
firewall's configuration. For example, you might use a normal
|
||
first/last range of 4000 to 5000, and a hiport range of 49152 to
|
||
65535, then block off everything under 4000 in your firewall
|
||
(except for certain specific Internet-accessible ports, of
|
||
course).</para>
|
||
|
||
<para>Another common DoS attack is called a springboard attack
|
||
— to attack a server in a manner that causes the server to
|
||
generate responses which overloads the server, the local
|
||
network, or some other machine. The most common attack of this
|
||
nature is the <emphasis>ICMP ping broadcast attack</emphasis>.
|
||
The attacker spoofs ping packets sent to your LAN's broadcast
|
||
address with the source IP address set to the actual machine they
|
||
wish to attack. If your border routers are not configured to
|
||
stomp on ping packets to broadcast addresses, your LAN winds up
|
||
generating sufficient responses to the spoofed source address to
|
||
saturate the victim, especially when the attacker uses the same
|
||
trick on several dozen broadcast addresses over several dozen
|
||
different networks at once. Broadcast attacks of over a hundred
|
||
and twenty megabits have been measured. A second common
|
||
springboard attack is against the ICMP error reporting system.
|
||
By constructing packets that generate ICMP error responses, an
|
||
attacker can saturate a server's incoming network and cause the
|
||
server to saturate its outgoing network with ICMP responses. This
|
||
type of attack can also crash the server by running it out of
|
||
memory, especially if the server cannot drain the ICMP responses
|
||
it generates fast enough.
|
||
Use the <application>sysctl</application>
|
||
variable <literal>net.inet.icmp.icmplim</literal> to limit these attacks.
|
||
The last major class of springboard
|
||
attacks is related to certain internal
|
||
<application>inetd</application> services such as the
|
||
udp echo service. An attacker simply spoofs a UDP packet with the
|
||
source address being server A's echo port, and the destination
|
||
address being server B's echo port, where server A and B are both
|
||
on your LAN. The two servers then bounce this one packet back and
|
||
forth between each other. The attacker can overload both servers
|
||
and their LANs simply by injecting a few packets in this manner.
|
||
Similar problems exist with the internal
|
||
<application>chargen</application> port. A
|
||
competent sysadmin will turn off all of these inetd-internal test
|
||
services.</para>
|
||
|
||
<para>Spoofed packet attacks may also be used to overload the kernel
|
||
route cache. Refer to the <varname>net.inet.ip.rtexpire</varname>,
|
||
<varname>rtminexpire</varname>, and <varname>rtmaxcache</varname>
|
||
<command>sysctl</command> parameters. A spoofed packet attack
|
||
that uses a random source IP will cause the kernel to generate a
|
||
temporary cached route in the route table, viewable with
|
||
<command>netstat -rna | fgrep W3</command>. These routes
|
||
typically timeout in 1600 seconds or so. If the kernel detects
|
||
that the cached route table has gotten too big it will dynamically
|
||
reduce the <varname>rtexpire</varname> but will never decrease it
|
||
to less than <varname>rtminexpire</varname>. There are two
|
||
problems:</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>The kernel does not react quickly enough when a lightly
|
||
loaded server is suddenly attacked.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>The <varname>rtminexpire</varname> is not low enough for
|
||
the kernel to survive a sustained attack.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>If your servers are connected to the Internet via a T3 or
|
||
better, it may be prudent to manually override both
|
||
<varname>rtexpire</varname> and <varname>rtminexpire</varname>
|
||
via &man.sysctl.8;. Never set either parameter to zero (unless
|
||
you want to crash the machine). Setting both
|
||
parameters to 2 seconds should be sufficient to protect the route
|
||
table from attack.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Access Issues with Kerberos and SSH</title>
|
||
<indexterm><primary><command>ssh</command></primary></indexterm>
|
||
<indexterm><primary>KerberosIV</primary></indexterm>
|
||
|
||
<para>There are a few issues with both Kerberos and
|
||
ssh that need to be addressed if
|
||
you intend to use them. Kerberos 5 is an excellent
|
||
authentication protocol, but there are bugs in the kerberized
|
||
<application>telnet</application> and
|
||
<application>rlogin</application> applications that make them
|
||
unsuitable for dealing with binary streams. Also, by default
|
||
Kerberos does not encrypt a session unless you use the
|
||
<option>-x</option> option. <application>ssh</application>
|
||
encrypts everything by default.</para>
|
||
|
||
<para>Ssh works quite well in every
|
||
respect except that it forwards encryption keys by default. What
|
||
this means is that if you have a secure workstation holding keys
|
||
that give you access to the rest of the system, and you
|
||
ssh to an insecure machine, your keys
|
||
are usable. The actual keys themselves are not exposed, but
|
||
ssh installs a forwarding port for the
|
||
duration of your login, and if an attacker has broken
|
||
<username>root</username> on the
|
||
insecure machine he can utilize that port to use your keys to gain
|
||
access to any other machine that your keys unlock.</para>
|
||
|
||
<para>We recommend that you use ssh in
|
||
combination with Kerberos whenever possible for staff logins.
|
||
<application>Ssh</application> can be compiled with Kerberos
|
||
support. This reduces your reliance on potentially exposed
|
||
ssh keys while at the same time
|
||
protecting passwords via Kerberos. Ssh
|
||
keys should only be used for automated tasks from secure machines
|
||
(something that Kerberos is unsuited to do). We also recommend that
|
||
you either turn off key-forwarding in the
|
||
ssh configuration, or that you make use
|
||
of the <literal>from=IP/DOMAIN</literal> option that
|
||
ssh allows in its
|
||
<filename>authorized_keys</filename> file to make the key only
|
||
usable to entities logging in from specific machines.</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="crypt">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Bill</firstname>
|
||
<surname>Swingle</surname>
|
||
<contrib>Parts rewritten and updated by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
<!-- 21 Mar 2000 -->
|
||
</sect1info>
|
||
|
||
<title>DES, MD5, and Crypt</title>
|
||
<indexterm>
|
||
<primary>security</primary>
|
||
<secondary>crypt</secondary>
|
||
</indexterm>
|
||
|
||
<indexterm><primary>crypt</primary></indexterm>
|
||
<indexterm><primary>DES</primary></indexterm>
|
||
<indexterm><primary>MD5</primary></indexterm>
|
||
|
||
<para>Every user on a &unix; system has a password associated with
|
||
their account. It seems obvious that these passwords need to be
|
||
known only to the user and the actual operating system. In
|
||
order to keep these passwords secret, they are encrypted with
|
||
what is known as a <quote>one-way hash</quote>, that is, they can
|
||
only be easily encrypted but not decrypted. In other words, what
|
||
we told you a moment ago was obvious is not even true: the
|
||
operating system itself does not <emphasis>really</emphasis> know
|
||
the password. It only knows the <emphasis>encrypted</emphasis>
|
||
form of the password. The only way to get the
|
||
<quote>plain-text</quote> password is by a brute force search of the
|
||
space of possible passwords.</para>
|
||
|
||
<para>Unfortunately the only secure way to encrypt passwords when
|
||
&unix; came into being was based on DES, the Data Encryption
|
||
Standard. This was not such a problem for users resident in
|
||
the US, but since the source code for DES could not be exported
|
||
outside the US, &os; had to find a way to both comply with
|
||
US law and retain compatibility with all the other &unix;
|
||
variants that still used DES.</para>
|
||
|
||
<para>The solution was to divide up the encryption libraries
|
||
so that US users could install the DES libraries and use
|
||
DES but international users still had an encryption method
|
||
that could be exported abroad. This is how &os; came to
|
||
use MD5 as its default encryption method. MD5 is believed to
|
||
be more secure than DES, so installing DES is offered primarily
|
||
for compatibility reasons.</para>
|
||
|
||
<sect2>
|
||
<title>Recognizing Your Crypt Mechanism</title>
|
||
|
||
<para>Currently the library supports DES, MD5 and Blowfish hash
|
||
functions. By default &os; uses MD5 to encrypt
|
||
passwords.</para>
|
||
|
||
<para>It is pretty easy to identify which encryption method
|
||
&os; is set up to use. Examining the encrypted passwords in
|
||
the <filename>/etc/master.passwd</filename> file is one way.
|
||
Passwords encrypted with the MD5 hash are longer than those
|
||
encrypted with the DES hash and also begin with the characters
|
||
<literal>$1$</literal>. Passwords starting with
|
||
<literal>$2a$</literal> are encrypted with the
|
||
Blowfish hash function. DES password strings do not
|
||
have any particular identifying characteristics, but they are
|
||
shorter than MD5 passwords, and are coded in a 64-character
|
||
alphabet which does not include the <literal>$</literal>
|
||
character, so a relatively short string which does not begin with
|
||
a dollar sign is very likely a DES password.</para>
|
||
|
||
<para>The password format used for new passwords is controlled
|
||
by the <literal>passwd_format</literal> login capability in
|
||
<filename>/etc/login.conf</filename>, which takes values of
|
||
<literal>des</literal>, <literal>md5</literal> or
|
||
<literal>blf</literal>. See the &man.login.conf.5; manual page
|
||
for more information about login capabilities.</para>
|
||
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 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 OPIE (One-time Passwords
|
||
In Everything), which uses the MD5 hash by default.</para>
|
||
|
||
<para>There are three different sorts of passwords which we will discuss
|
||
below. The first is your usual &unix; style or
|
||
Kerberos password; we will call this a <quote>&unix; password</quote>.
|
||
The second sort is the one-time password which is generated by the OPIE
|
||
&man.opiekey.1; program and accepted by the
|
||
&man.opiepasswd.1; program
|
||
and the login prompt; we will
|
||
call this a <quote>one-time password</quote>. The final sort of
|
||
password is the secret password which you give to the
|
||
<command>opiekey</command> program (and
|
||
sometimes the
|
||
<command>opiepasswd</command> programs)
|
||
which it uses to generate
|
||
one-time passwords; we will call it a <quote>secret password</quote>
|
||
or just unqualified <quote>password</quote>.</para>
|
||
|
||
<para>The secret password does not have anything to do with your &unix;
|
||
password; they can be the same but this is not recommended.
|
||
OPIE secret passwords are not limited to 8 characters like old
|
||
&unix; passwords<footnote><para>Under &os; the standard login
|
||
password may be up to 128 characters in length.</para></footnote>,
|
||
they can be as long as you like. Passwords of six or
|
||
seven word long phrases are fairly common. For the most part, the
|
||
OPIE system operates completely independently of the &unix;
|
||
password system.</para>
|
||
|
||
<para>Besides the password, there are two other pieces of data that
|
||
are important to OPIE. One is what is known as the
|
||
<quote>seed</quote> or <quote>key</quote>, consisting of two letters
|
||
and five digits. The other is what is called the <quote>iteration
|
||
count</quote>, a number between 1 and 100. OPIE creates the
|
||
one-time password by concatenating the seed and the secret password,
|
||
then applying the MD5 hash as many times as specified by the
|
||
iteration count and turning the result into six short English words.
|
||
These six English words are your one-time password. The
|
||
authentication system (primarily PAM) 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 1, OPIE must be
|
||
reinitialized.</para>
|
||
|
||
<para>There are a few programs involved in each system
|
||
which we will discuss below. The
|
||
<command>opiekey</command> program accepts an iteration
|
||
count, a seed, and a secret password, and generates a one-time
|
||
password or a consecutive list of one-time passwords. The
|
||
<command>opiepasswd</command>
|
||
program is used to initialize OPIE,
|
||
and to change passwords, iteration counts, or seeds; it
|
||
takes either a secret passphrase, or an iteration count,
|
||
seed, and a one-time password. The
|
||
<command>opieinfo</command> program will examine the
|
||
relevant credentials files
|
||
(<filename>/etc/opiekeys</filename>) and print out the invoking user's
|
||
current iteration count and seed.</para>
|
||
|
||
<para>There are four different sorts of operations we will cover. The
|
||
first is using
|
||
<command>opiepasswd</command> over a secure connection to set up
|
||
one-time-passwords for the first time, or to change your password
|
||
or seed. The second operation is using
|
||
<command>opiepasswd</command> over an insecure connection, in
|
||
conjunction with <command>opiekey</command>
|
||
over a secure connection, to do the same. The third is using
|
||
<command>opiekey</command> to log in over
|
||
an insecure connection. The fourth is using
|
||
<command>opiekey</command> to generate a number of keys which
|
||
can be written down or printed out to carry with you when going to
|
||
some location without secure connections to anywhere.</para>
|
||
|
||
<sect2>
|
||
<title>Secure Connection Initialization</title>
|
||
<para>To initialize OPIE for the first time, execute the
|
||
<command>opiepasswd</command> command:</para>
|
||
|
||
<screen>&prompt.user; <userinput>opiepasswd -c</userinput>
|
||
[grimreaper] ~ $ opiepasswd -f -c
|
||
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>At the <prompt>Enter new secret pass phrase:</prompt> or
|
||
<prompt>Enter secret password:</prompt> prompts, you
|
||
should enter a password or phrase. Remember, this is not the
|
||
password that you will use to login with, this is used to generate
|
||
your one-time login keys. The <quote>ID</quote> line gives the
|
||
parameters of your particular instance: your login name, the
|
||
iteration count, and seed. When logging in the system
|
||
will remember these parameters and present them back to you so you
|
||
do not have to remember them. The last line gives the particular
|
||
one-time password which corresponds to those parameters and your
|
||
secret password; if you were to re-login immediately, this
|
||
one-time password is the one you would use.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Insecure Connection Initialization</title>
|
||
|
||
<para>To initialize or change your secret password over an
|
||
insecure connection, you will need to already have a secure
|
||
connection to some place where you can run
|
||
<command>opiekey</command>; this might be in the form of a shell
|
||
prompt on a machine you
|
||
trust. You will also need to make up an iteration count (100 is
|
||
probably a good value), and you may make up your own seed or use a
|
||
randomly-generated one. Over on the insecure connection (to the
|
||
machine you are initializing), use <command>opiepasswd</command>:</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>.
|
||
Then before entering an
|
||
access password, move over to your 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: Don't use opiekey from telnet or dial-in sessions.
|
||
Enter secret pass phrase:
|
||
GAME GAG WELT OUT DOWN CHAT
|
||
</screen>
|
||
|
||
<para>Now switch back over to the insecure connection, and copy the
|
||
one-time password generated over to the relevant program.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Generating a Single One-time Password</title>
|
||
|
||
<para>Once you have initialized OPIE and login, you will be
|
||
presented with a prompt like this:</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><username></userinput>
|
||
otp-md5 498 gr4269 ext
|
||
Password: </screen>
|
||
|
||
<para>As a side note, the OPIE prompts have a useful feature
|
||
(not shown here): if you press <keycap>Return</keycap>
|
||
at the password prompt, the
|
||
prompter will turn echo on, so you can see what you are
|
||
typing. This can be extremely useful if you are attempting to
|
||
type in a password by hand, such as from a printout.</para>
|
||
|
||
<indexterm><primary>MS-DOS</primary></indexterm>
|
||
<indexterm><primary>Windows</primary></indexterm>
|
||
<indexterm><primary>MacOS</primary></indexterm>
|
||
|
||
<para>At this point you need to generate your one-time password to
|
||
answer this login prompt. This must be done on a trusted system
|
||
that you can run
|
||
<command>opiekey</command> on. (There are versions of these for DOS,
|
||
&windows; and &macos; as well.) They need the iteration count and
|
||
the seed as command line options. You can cut-and-paste these
|
||
right from the login prompt on the machine that you are logging
|
||
in to.</para>
|
||
|
||
<para>On the trusted system:</para>
|
||
|
||
<screen>&prompt.user; <userinput>opiekey 498 to4268</userinput>
|
||
Using the MD5 algorithm to compute response.
|
||
Reminder: Don't use opiekey from telnet or dial-in sessions.
|
||
Enter secret pass phrase:
|
||
GAME GAG WELT OUT DOWN CHAT</screen>
|
||
|
||
<para>Now that you have your one-time password you can continue
|
||
logging in.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Generating Multiple One-time Passwords</title>
|
||
|
||
<para>Sometimes you have to go places where you do not have
|
||
access to a trusted machine or secure connection. In this case,
|
||
it is possible to use the
|
||
<command>opiekey</command> command to
|
||
generate a number of one-time passwords beforehand to be printed
|
||
out and taken with you. For example:</para>
|
||
|
||
<screen>&prompt.user; <userinput>opiekey -n 5 30 zz99999</userinput>
|
||
Using the MD5 algorithm to compute response.
|
||
Reminder: Don't use opiekey from telnet or dial-in sessions.
|
||
Enter secret pass phrase: <userinput><secret password></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, the
|
||
<option>30</option> specifies what the last iteration number
|
||
should be. Note that these are printed out in
|
||
<emphasis>reverse</emphasis> order of eventual use. If you are
|
||
really paranoid, you might want to write the results down by hand;
|
||
otherwise you can cut-and-paste into <command>lpr</command>. Note
|
||
that each line shows both the iteration count and the one-time
|
||
password; you may still find it handy to scratch off passwords as
|
||
you use them.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Restricting Use of &unix; Passwords</title>
|
||
|
||
<para>OPIE 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.
|
||
Please check &man.opieaccess.5;
|
||
for more information on this file and which security considerations
|
||
you should be aware of when using it.</para>
|
||
|
||
<para>Here is a sample <filename>opieaccess</filename> file:</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-OPIE logins.</para>
|
||
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="tcpwrappers">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
<surname>Rhodes</surname>
|
||
<contrib>Written by: </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
|
||
<indexterm><primary>TCP Wrappers</primary></indexterm>
|
||
|
||
<title>TCP Wrappers</title>
|
||
|
||
<para>Anyone familiar with &man.inetd.8; has probably heard
|
||
of <acronym>TCP</acronym> Wrappers at some point. But few
|
||
individuals seem to fully comprehend its usefulness in a
|
||
network environment. It seems that everyone wants to
|
||
install a firewall to handle network connections. While a
|
||
firewall has a wide variety of uses, there are some things
|
||
that a firewall not handle such as sending text back to the
|
||
connection originator. The <acronym>TCP</acronym> software
|
||
does this and much more. In the next few sections many of
|
||
the <acronym>TCP</acronym> Wrappers features will be discussed,
|
||
and, when applicable, example configuration lines will be
|
||
provided.</para>
|
||
|
||
<para>The <acronym>TCP</acronym> Wrappers software extends the
|
||
abilities of <command>inetd</command> to provide support for
|
||
every server daemon under its control. Using this method it
|
||
is possible to provide logging support, return messages to
|
||
connections, permit a daemon to only accept internal connections,
|
||
etc. While some of these features can be provided by implementing
|
||
a firewall, this will add not only an extra layer of protection
|
||
but go beyond the amount of control a firewall can
|
||
provide.</para>
|
||
|
||
<para>The added functionality of <acronym>TCP</acronym> Wrappers
|
||
should not be considered a replacement for a good firewall.
|
||
<acronym>TCP</acronym> Wrappers can be used in conjunction
|
||
with a firewall or other security enhancements though and
|
||
it can serve nicely as an extra layer of protection
|
||
for the system.</para>
|
||
|
||
<para>Since this is an extension to the configuration of
|
||
<command>inetd</command>, the reader is expected have
|
||
read the <link linkend="network-inetd">inetd configuration</link>
|
||
section.</para>
|
||
|
||
<note>
|
||
<para>While programs run by &man.inetd.8; are not exactly
|
||
<quote>daemons</quote>, they have traditionally been called
|
||
daemons. This is the term we will use in this section too.</para>
|
||
</note>
|
||
|
||
<sect2>
|
||
<title>Initial Configuration</title>
|
||
|
||
<para>The only requirement of using <acronym>TCP</acronym>
|
||
Wrappers in &os; is to ensure the <command>inetd</command>
|
||
server is started from <filename>rc.conf</filename> with the
|
||
<option>-Ww</option> option; this is the default setting. Of
|
||
course, proper configuration of
|
||
<filename>/etc/hosts.allow</filename> is also expected, but
|
||
&man.syslogd.8; will throw messages in the system logs in
|
||
these cases.</para>
|
||
|
||
<note>
|
||
<para>Unlike other implementations of <acronym>TCP</acronym>
|
||
Wrappers, the use of <filename>hosts.deny</filename> has
|
||
been deprecated. 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 be permitted or blocked depending on the
|
||
options in <filename>/etc/hosts.allow</filename>. The default
|
||
configuration in &os; is to allow a connection to every daemon
|
||
started with <command>inetd</command>. Changing this will be
|
||
discussed only after the basic configuration is covered.</para>
|
||
|
||
<para>Basic configuration usually takes the form of
|
||
<literal>daemon : address : action</literal>. Where
|
||
<literal>daemon</literal> is the daemon name which
|
||
<command>inetd</command> started. The
|
||
<literal>address</literal> can be a valid hostname, an
|
||
<acronym>IP</acronym> address or an IPv6 address enclosed in
|
||
brackets ([ ]). The action field can be either allow
|
||
or deny to grant or deny access appropriately. Keep in mind
|
||
that configuration works off a first rule match semantic,
|
||
meaning that the configuration file is scanned in ascending
|
||
order for a matching rule. When a match is found the rule
|
||
is applied and the search process will halt.</para>
|
||
|
||
<para>Several other options exist but they will be explained
|
||
in a later section. A simple configuration line may easily be
|
||
constructed from that information alone. For example, to
|
||
allow <acronym>POP</acronym>3 connections via the
|
||
<filename role="package">mail/qpopper</filename> 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>After adding this line, <command>inetd</command> will need
|
||
restarted. This can be accomplished by use of the &man.kill.1;
|
||
command, or with the <parameter>restart</parameter> parameter
|
||
with <filename>/etc/rc.d/inetd</filename>.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Advanced Configuration</title>
|
||
|
||
<para><acronym>TCP</acronym> Wrappers has advanced
|
||
options too; they will allow for more control over the
|
||
way connections are handled. In some cases it may be
|
||
a good idea to return a comment to certain hosts or
|
||
daemon connections. In other cases, perhaps a log file
|
||
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 <literal>wildcards</literal>,
|
||
expansion characters and external command execution. The
|
||
next two sections are written to cover these situations.</para>
|
||
|
||
<sect3>
|
||
<title>External Commands</title>
|
||
|
||
<para>Suppose that a situation occurs where a connection
|
||
should be denied yet a reason should be sent to the
|
||
individual who attempted to establish that connection. How
|
||
could it be done? That action can be made possible by
|
||
using the <option>twist</option> option. When a connection
|
||
attempt is made, <option>twist</option> will be called to
|
||
execute a shell command or script. An example already exists
|
||
in the <filename>hosts.allow</filename> file:</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>This example shows that the message,
|
||
<quote>You are not allowed to use <literal>daemon</literal>
|
||
from <literal>hostname</literal>.</quote> will be returned
|
||
for any daemon not previously configured in the access file.
|
||
This is extremely useful for sending a reply back to the
|
||
connection initiator right after the established connection
|
||
is dropped. Note that any message returned
|
||
<emphasis>must</emphasis> be wrapped in quote
|
||
<literal>"</literal> characters; there are no exceptions to
|
||
this rule.</para>
|
||
|
||
<warning>
|
||
<para>It may be possible to launch a denial of service attack
|
||
on the server if an attacker, or group of attackers could
|
||
flood these daemons with connection requests.</para>
|
||
</warning>
|
||
|
||
<para>Another possibility is to use the <option>spawn</option>
|
||
option in these cases. Like <option>twist</option>, the
|
||
<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 individual who established the
|
||
connection. For an example, consider the following
|
||
configuration line:</para>
|
||
|
||
<programlisting># We do not allow connections from example.com:
|
||
ALL : .example.com \
|
||
: spawn (/bin/echo %a from %h attempted to access %d >> \
|
||
/var/log/connections.log) \
|
||
: deny</programlisting>
|
||
|
||
<para>This will deny all connection attempts from the
|
||
<hostid role="fqdn">*.example.com</hostid> domain;
|
||
simultaneously logging the hostname, <acronym>IP</acronym>
|
||
address and the daemon which they attempted to access in the
|
||
<filename>/var/log/connections.log</filename> file.</para>
|
||
|
||
<para>Aside from the already explained substitution characters
|
||
above, e.g. %a, a few others exist. See the
|
||
&man.hosts.access.5; manual page for the complete list.</para>
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Wildcard Options</title>
|
||
|
||
<para>Thus far the <literal>ALL</literal> example has been used
|
||
continuously throughout the examples. Other options exist
|
||
which could extend the functionality a bit further. For
|
||
instance, <literal>ALL</literal> may be used to match every
|
||
instance of either a daemon, domain or an
|
||
<acronym>IP</acronym> address. Another wildcard available is
|
||
<literal>PARANOID</literal> which may be used to match any
|
||
host which provides an <acronym>IP</acronym> address that may
|
||
be forged. In other words, <literal>paranoid</literal> may
|
||
be used to define an action to be taken whenever a connection
|
||
is made from an <acronym>IP</acronym> address that differs
|
||
from its hostname. The following example may shed some more
|
||
light on this discussion:</para>
|
||
|
||
<programlisting># Block possibly spoofed requests to sendmail:
|
||
sendmail : PARANOID : deny</programlisting>
|
||
|
||
<para>In that example all connection requests to
|
||
<command>sendmail</command> which have an
|
||
<acronym>IP</acronym> address that varies from its hostname
|
||
will be denied.</para>
|
||
|
||
<caution>
|
||
<para>Using the <literal>PARANOID</literal> may severely
|
||
cripple servers if the client or server has a broken
|
||
<acronym>DNS</acronym> setup. Administrator discretion
|
||
is advised.</para>
|
||
</caution>
|
||
|
||
<para>To learn more about wildcards and their associated
|
||
functionality, see the &man.hosts.access.5; manual
|
||
page.</para>
|
||
|
||
<para>Before any of the specific configuration lines above will
|
||
work, the first configuration line should be commented out
|
||
in <filename>hosts.allow</filename>. This was noted at the
|
||
beginning of this section.</para>
|
||
</sect3>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="kerberosIV">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Mark</firstname>
|
||
<surname>Murray</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Mark</firstname>
|
||
<surname>Dapoz</surname>
|
||
<contrib>Based on a contribution by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
|
||
<title><application>KerberosIV</application></title>
|
||
|
||
<para>Kerberos is a network add-on system/protocol that allows users to
|
||
authenticate themselves through the services of a secure server.
|
||
Services such as remote login, remote copy, secure inter-system file
|
||
copying and other high-risk tasks are made considerably safer and more
|
||
controllable.</para>
|
||
|
||
<para>The following instructions can be used as a guide on how to set up
|
||
Kerberos as distributed for &os;. However, you should refer to the
|
||
relevant manual pages for a complete description.</para>
|
||
|
||
<sect2>
|
||
<title>Installing <application>KerberosIV</application></title>
|
||
|
||
<indexterm><primary>MIT</primary></indexterm>
|
||
<indexterm>
|
||
<primary>KerberosIV</primary>
|
||
<secondary>installing</secondary>
|
||
</indexterm>
|
||
<para>Kerberos is an optional component of &os;. The easiest
|
||
way to install this software is by selecting the <literal>krb4</literal> or
|
||
<literal>krb5</literal> distribution in <application>sysinstall</application>
|
||
during the initial installation of &os;. This will install
|
||
the <quote>eBones</quote> (KerberosIV) or <quote>Heimdal</quote> (Kerberos5)
|
||
implementation of Kerberos. These implementations are
|
||
included because they are developed outside the USA/Canada and
|
||
were thus available to system owners outside those countries
|
||
during the era of restrictive export controls on cryptographic
|
||
code from the USA.</para>
|
||
|
||
<para>Alternatively, the MIT implementation of Kerberos is
|
||
available from the Ports Collection as
|
||
<filename role="package">security/krb5</filename>.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Creating the Initial Database</title>
|
||
|
||
<para>This is done on the Kerberos server only. First make sure that
|
||
you do not have any old Kerberos databases around. You should change
|
||
to the directory <filename>/etc/kerberosIV</filename> and check that
|
||
only the following files are present:</para>
|
||
|
||
<screen>&prompt.root; <userinput>cd /etc/kerberosIV</userinput>
|
||
&prompt.root; <userinput>ls</userinput>
|
||
README krb.conf krb.realms</screen>
|
||
|
||
<para>If any additional files (such as <filename>principal.*</filename>
|
||
or <filename>master_key</filename>) exist, then use the
|
||
<command>kdb_destroy</command> command to destroy the old Kerberos
|
||
database, or if Kerberos is not running, simply delete the extra
|
||
files.</para>
|
||
|
||
<para>You should now edit the <filename>krb.conf</filename> and
|
||
<filename>krb.realms</filename> files to define your Kerberos realm.
|
||
In this case the realm will be <literal>EXAMPLE.COM</literal> and the
|
||
server is <hostid role="fqdn">grunt.example.com</hostid>. We edit
|
||
or create the <filename>krb.conf</filename> file:</para>
|
||
|
||
<screen>&prompt.root; <userinput>cat krb.conf</userinput>
|
||
EXAMPLE.COM
|
||
EXAMPLE.COM grunt.example.com admin server
|
||
CS.BERKELEY.EDU okeeffe.berkeley.edu
|
||
ATHENA.MIT.EDU kerberos.mit.edu
|
||
ATHENA.MIT.EDU kerberos-1.mit.edu
|
||
ATHENA.MIT.EDU kerberos-2.mit.edu
|
||
ATHENA.MIT.EDU kerberos-3.mit.edu
|
||
LCS.MIT.EDU kerberos.lcs.mit.edu
|
||
TELECOM.MIT.EDU bitsy.mit.edu
|
||
ARC.NASA.GOV trident.arc.nasa.gov</screen>
|
||
|
||
<para>In this case, the other realms do not need to be there. They are
|
||
here as an example of how a machine may be made aware of multiple
|
||
realms. You may wish to not include them for simplicity.</para>
|
||
|
||
<para>The first line names the realm in which this system works. The
|
||
other lines contain realm/host entries. The first item on a line is a
|
||
realm, and the second is a host in that realm that is acting as a
|
||
<quote>key distribution center</quote>. The words <literal>admin
|
||
server</literal> following a host's name means that host also
|
||
provides an administrative database server. For further explanation
|
||
of these terms, please consult the Kerberos manual pages.</para>
|
||
|
||
<para>Now we have to add <hostid role="fqdn">grunt.example.com</hostid>
|
||
to the <literal>EXAMPLE.COM</literal> realm and also add an entry to
|
||
put all hosts in the <hostid role="domainname">.example.com</hostid>
|
||
domain in the <literal>EXAMPLE.COM</literal> realm. The
|
||
<filename>krb.realms</filename> file would be updated as
|
||
follows:</para>
|
||
|
||
<screen>&prompt.root; <userinput>cat krb.realms</userinput>
|
||
grunt.example.com EXAMPLE.COM
|
||
.example.com EXAMPLE.COM
|
||
.berkeley.edu CS.BERKELEY.EDU
|
||
.MIT.EDU ATHENA.MIT.EDU
|
||
.mit.edu ATHENA.MIT.EDU</screen>
|
||
|
||
<para>Again, the other realms do not need to be there. They are here as
|
||
an example of how a machine may be made aware of multiple realms. You
|
||
may wish to remove them to simplify things.</para>
|
||
|
||
<para>The first line puts the <emphasis>specific</emphasis> system into
|
||
the named realm. The rest of the lines show how to default systems of
|
||
a particular subdomain to a named realm.</para>
|
||
|
||
<para>Now we are ready to create the database. This only needs to run
|
||
on the Kerberos server (or Key Distribution Center). Issue the
|
||
<command>kdb_init</command> command to do this:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kdb_init</userinput>
|
||
<prompt>Realm name [default ATHENA.MIT.EDU ]:</prompt> <userinput>EXAMPLE.COM</userinput>
|
||
You will be prompted for the database Master Password.
|
||
It is important that you NOT FORGET this password.
|
||
|
||
<prompt>Enter Kerberos master key:</prompt> </screen>
|
||
|
||
<para>Now we have to save the key so that servers on the local machine
|
||
can pick it up. Use the <command>kstash</command> command to do
|
||
this:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kstash</userinput>
|
||
|
||
<prompt>Enter Kerberos master key:</prompt>
|
||
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!</screen>
|
||
|
||
<para>This saves the encrypted master password in
|
||
<filename>/etc/kerberosIV/master_key</filename>.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Making It All Run</title>
|
||
|
||
<indexterm>
|
||
<primary>KerberosIV</primary>
|
||
<secondary>initial startup</secondary>
|
||
</indexterm>
|
||
|
||
<para>Two principals need to be added to the database for
|
||
<emphasis>each</emphasis> system that will be secured with Kerberos.
|
||
Their names are <literal>kpasswd</literal> and <literal>rcmd</literal>.
|
||
These two principals are made for each system, with the instance being
|
||
the name of the individual system.</para>
|
||
|
||
<para>These daemons, <application>kpasswd</application> and
|
||
<application>rcmd</application> allow other systems to change Kerberos
|
||
passwords and run commands like &man.rcp.1;,
|
||
&man.rlogin.1; and &man.rsh.1;.</para>
|
||
|
||
<para>Now let us add these entries:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kdb_edit</userinput>
|
||
Opening database...
|
||
|
||
<prompt>Enter Kerberos master key:</prompt>
|
||
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!
|
||
Previous or default values are in [brackets] ,
|
||
enter return to leave the same, or new value.
|
||
|
||
<prompt>Principal name:</prompt> <userinput>passwd</userinput>
|
||
<prompt>Instance:</prompt> <userinput>grunt</userinput>
|
||
|
||
<Not found>, <prompt>Create [y] ?</prompt> <userinput>y</userinput>
|
||
|
||
Principal: passwd, Instance: grunt, kdc_key_ver: 1
|
||
<prompt>New Password:</prompt> <---- enter RANDOM here
|
||
Verifying password
|
||
|
||
<prompt>New Password:</prompt> <---- enter RANDOM here
|
||
|
||
<prompt>Random password [y] ?</prompt> <userinput>y</userinput>
|
||
|
||
Principal's new key version = 1
|
||
<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
|
||
<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt>
|
||
<prompt>Attributes [ 0 ] ?</prompt>
|
||
Edit O.K.
|
||
<prompt>Principal name:</prompt> <userinput>rcmd</userinput>
|
||
<prompt>Instance:</prompt> <userinput>grunt</userinput>
|
||
|
||
<Not found>, <prompt>Create [y] ?</prompt>
|
||
|
||
Principal: rcmd, Instance: grunt, kdc_key_ver: 1
|
||
<prompt>New Password:</prompt> <---- enter RANDOM here
|
||
Verifying password
|
||
|
||
<prompt>New Password:</prompt> <---- enter RANDOM here
|
||
|
||
<prompt>Random password [y] ?</prompt>
|
||
|
||
Principal's new key version = 1
|
||
<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
|
||
<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt>
|
||
<prompt>Attributes [ 0 ] ?</prompt>
|
||
Edit O.K.
|
||
<prompt>Principal name:</prompt> <---- null entry here will cause an exit</screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Creating the Server File</title>
|
||
|
||
<para>We now have to extract all the instances which define the
|
||
services on each machine. For this we use the
|
||
<command>ext_srvtab</command> command. This will create a file
|
||
which must be copied or moved <emphasis>by secure
|
||
means</emphasis> to each Kerberos client's
|
||
<filename>/etc</filename> directory. This file must
|
||
be present on each server and client, and is crucial to the
|
||
operation of Kerberos.</para>
|
||
|
||
|
||
<screen>&prompt.root; <userinput>ext_srvtab grunt</userinput>
|
||
<prompt>Enter Kerberos master key:</prompt>
|
||
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!
|
||
Generating 'grunt-new-srvtab'....</screen>
|
||
|
||
<para>Now, this command only generates a temporary file which must be
|
||
renamed to <filename>srvtab</filename> so that all the servers can pick
|
||
it up. Use the &man.mv.1; command to move it into place on
|
||
the original system:</para>
|
||
|
||
<screen>&prompt.root; <userinput>mv grunt-new-srvtab srvtab</userinput></screen>
|
||
|
||
<para>If the file is for a client system, and the network is not deemed
|
||
safe, then copy the
|
||
<filename><replaceable>client</replaceable>-new-srvtab</filename> to
|
||
removable media and transport it by secure physical means. Be sure to
|
||
rename it to <filename>srvtab</filename> in the client's
|
||
<filename>/etc</filename> directory, and make sure it is
|
||
mode 600:</para>
|
||
|
||
<screen>&prompt.root; <userinput>mv grumble-new-srvtab srvtab</userinput>
|
||
&prompt.root; <userinput>chmod 600 srvtab</userinput></screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Populating the Database</title>
|
||
|
||
<para>We now have to add some user entries into the database. First
|
||
let us create an entry for the user <username>jane</username>. Use the
|
||
<command>kdb_edit</command> command to do this:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kdb_edit</userinput>
|
||
Opening database...
|
||
|
||
<prompt>Enter Kerberos master key:</prompt>
|
||
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!
|
||
Previous or default values are in [brackets] ,
|
||
enter return to leave the same, or new value.
|
||
|
||
<prompt>Principal name:</prompt> <userinput>jane</userinput>
|
||
<prompt>Instance:</prompt>
|
||
|
||
<Not found>, <prompt>Create [y] ?</prompt> <userinput>y</userinput>
|
||
|
||
Principal: jane, Instance: , kdc_key_ver: 1
|
||
<prompt>New Password:</prompt> <---- enter a secure password here
|
||
Verifying password
|
||
|
||
<prompt>New Password:</prompt> <---- re-enter the password here
|
||
Principal's new key version = 1
|
||
<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
|
||
<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt>
|
||
<prompt>Attributes [ 0 ] ?</prompt>
|
||
Edit O.K.
|
||
<prompt>Principal name:</prompt> <---- null entry here will cause an exit</screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Testing It All Out</title>
|
||
|
||
<para>First we have to start the Kerberos daemons. Note that if you
|
||
have correctly edited your <filename>/etc/rc.conf</filename> then this
|
||
will happen automatically when you reboot. This is only necessary on
|
||
the Kerberos server. Kerberos clients will automatically get what
|
||
they need from the <filename>/etc/kerberosIV</filename>
|
||
directory.</para>
|
||
|
||
<screen>&prompt.root; <userinput>kerberos &</userinput>
|
||
Kerberos server starting
|
||
Sleep forever on error
|
||
Log file is /var/log/kerberos.log
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!
|
||
|
||
Current Kerberos master key version is 1
|
||
Local realm: EXAMPLE.COM
|
||
&prompt.root; <userinput>kadmind -n &</userinput>
|
||
KADM Server KADM0.0A initializing
|
||
Please do not use 'kill -9' to kill this job, use a
|
||
regular kill instead
|
||
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!</screen>
|
||
|
||
<para>Now we can try using the <command>kinit</command> command to get a
|
||
ticket for the ID <username>jane</username> that we created
|
||
above:</para>
|
||
|
||
<screen>&prompt.user; <userinput>kinit jane</userinput>
|
||
MIT Project Athena (grunt.example.com)
|
||
Kerberos Initialization for "jane"
|
||
<prompt>Password:</prompt> </screen>
|
||
|
||
<para>Try listing the tokens using <command>klist</command> to see if we
|
||
really have them:</para>
|
||
|
||
<screen>&prompt.user; <userinput>klist</userinput>
|
||
Ticket file: /tmp/tkt245
|
||
Principal: jane@EXAMPLE.COM
|
||
|
||
Issued Expires Principal
|
||
Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.EXAMPLE.COM@EXAMPLE.COM</screen>
|
||
|
||
<para>Now try changing the password using &man.passwd.1; to
|
||
check if the <application>kpasswd</application> daemon can get
|
||
authorization to the Kerberos database:</para>
|
||
|
||
<screen>&prompt.user; <userinput>passwd</userinput>
|
||
realm EXAMPLE.COM
|
||
<prompt>Old password for jane:</prompt>
|
||
<prompt>New Password for jane:</prompt>
|
||
Verifying password
|
||
<prompt>New Password for jane:</prompt>
|
||
Password changed.</screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Adding <command>su</command> Privileges</title>
|
||
|
||
<para>Kerberos allows us to give <emphasis>each</emphasis> user
|
||
who needs <username>root</username> privileges their own
|
||
<emphasis>separate</emphasis> &man.su.1; password.
|
||
We could now add an ID which is authorized to
|
||
&man.su.1; to <username>root</username>. This is
|
||
controlled by having an instance of <username>root</username>
|
||
associated with a principal. Using <command>kdb_edit</command>
|
||
we can create the entry <literal>jane.root</literal> in the
|
||
Kerberos database:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kdb_edit</userinput>
|
||
Opening database...
|
||
|
||
<prompt>Enter Kerberos master key:</prompt>
|
||
|
||
Current Kerberos master key version is 1.
|
||
|
||
Master key entered. BEWARE!
|
||
Previous or default values are in [brackets] ,
|
||
enter return to leave the same, or new value.
|
||
|
||
<prompt>Principal name:</prompt> <userinput>jane</userinput>
|
||
<prompt>Instance:</prompt> <userinput>root</userinput>
|
||
|
||
<Not found>, Create [y] ? y
|
||
|
||
Principal: jane, Instance: root, kdc_key_ver: 1
|
||
<prompt>New Password:</prompt> <---- enter a SECURE password here
|
||
Verifying password
|
||
|
||
<prompt>New Password:</prompt> <---- re-enter the password here
|
||
|
||
Principal's new key version = 1
|
||
<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
|
||
<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt> <userinput>12</userinput> <--- Keep this short!
|
||
<prompt>Attributes [ 0 ] ?</prompt>
|
||
Edit O.K.
|
||
<prompt>Principal name:</prompt> <---- null entry here will cause an exit</screen>
|
||
|
||
<para>Now try getting tokens for it to make sure it works:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kinit jane.root</userinput>
|
||
MIT Project Athena (grunt.example.com)
|
||
Kerberos Initialization for "jane.root"
|
||
<prompt>Password:</prompt></screen>
|
||
|
||
<para>Now we need to add the user to <username>root</username>'s
|
||
<filename>.klogin</filename> file:</para>
|
||
|
||
<screen>&prompt.root; <userinput>cat /root/.klogin</userinput>
|
||
jane.root@EXAMPLE.COM</screen>
|
||
|
||
<para>Now try doing the &man.su.1;:</para>
|
||
|
||
<screen>&prompt.user; <userinput>su</userinput>
|
||
<prompt>Password:</prompt></screen>
|
||
|
||
<para>and take a look at what tokens we have:</para>
|
||
|
||
<screen>&prompt.root; <userinput>klist</userinput>
|
||
Ticket file: /tmp/tkt_root_245
|
||
Principal: jane.root@EXAMPLE.COM
|
||
|
||
Issued Expires Principal
|
||
May 2 20:43:12 May 3 04:43:12 krbtgt.EXAMPLE.COM@EXAMPLE.COM</screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Using Other Commands</title>
|
||
|
||
<para>In an earlier example, we created a principal called
|
||
<literal>jane</literal> with an instance <literal>root</literal>.
|
||
This was based on a user with the same name as the principal, and this
|
||
is a Kerberos default; that a
|
||
<literal><principal>.<instance></literal> of the form
|
||
<literal><username>.</literal><username>root</username> will allow
|
||
that <literal><username></literal> to &man.su.1; to
|
||
<username>root</username> if the necessary entries are in the
|
||
<filename>.klogin</filename> file in <username>root</username>'s
|
||
home directory:</para>
|
||
|
||
<screen>&prompt.root; <userinput>cat /root/.klogin</userinput>
|
||
jane.root@EXAMPLE.COM</screen>
|
||
|
||
<para>Likewise, if a user has in their own home directory lines of the
|
||
form:</para>
|
||
|
||
<screen>&prompt.user; <userinput>cat ~/.klogin</userinput>
|
||
jane@EXAMPLE.COM
|
||
jack@EXAMPLE.COM</screen>
|
||
|
||
<para>This allows anyone in the <literal>EXAMPLE.COM</literal> realm
|
||
who has authenticated themselves as <username>jane</username> or
|
||
<username>jack</username> (via <command>kinit</command>, see above)
|
||
to access to <username>jane</username>'s
|
||
account or files on this system (<hostid>grunt</hostid>) via
|
||
&man.rlogin.1;, &man.rsh.1; or
|
||
&man.rcp.1;.</para>
|
||
|
||
<para>For example, <username>jane</username> now logs into another system using
|
||
Kerberos:</para>
|
||
|
||
<screen>&prompt.user; <userinput>kinit</userinput>
|
||
MIT Project Athena (grunt.example.com)
|
||
<prompt>Password:</prompt>
|
||
&prompt.user; <userinput>rlogin grunt</userinput>
|
||
Last login: Mon May 1 21:14:47 from grumble
|
||
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
|
||
The Regents of the University of California. All rights reserved.
|
||
|
||
FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995</screen>
|
||
|
||
<para>Or <username>jack</username> logs into <username>jane</username>'s account on the same machine
|
||
(<username>jane</username> having
|
||
set up the <filename>.klogin</filename> file as above, and the person
|
||
in charge of Kerberos having set up principal
|
||
<emphasis>jack</emphasis> with a null instance):</para>
|
||
|
||
<screen>&prompt.user; <userinput>kinit</userinput>
|
||
&prompt.user; <userinput>rlogin grunt -l jane</userinput>
|
||
MIT Project Athena (grunt.example.com)
|
||
<prompt>Password:</prompt>
|
||
Last login: Mon May 1 21:16:55 from grumble
|
||
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
|
||
The Regents of the University of California. All rights reserved.
|
||
FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995</screen>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="kerberos5">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tillman</firstname>
|
||
<surname>Hodgson</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Mark</firstname>
|
||
<surname>Murray</surname>
|
||
<contrib>Based on a contribution by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
|
||
<title><application>Kerberos5</application></title>
|
||
|
||
<para>Every &os; release beyond &os;-5.1 includes support
|
||
only for <application>Kerberos5</application>. Hence
|
||
<application>Kerberos5</application> is the only version
|
||
included, and its configuration is similar in many aspects
|
||
to that of <application>KerberosIV</application>. The following
|
||
information only applies to
|
||
<application>Kerberos5</application> in post &os;-5.0
|
||
releases. Users who wish to use the
|
||
<application>KerberosIV</application> package may install the
|
||
<filename role="package">security/krb4</filename> port.</para>
|
||
|
||
<para><application>Kerberos</application> is a network add-on
|
||
system/protocol that allows users to authenticate themselves
|
||
through the services of a secure server. Services such as remote
|
||
login, remote copy, secure inter-system file copying and other
|
||
high-risk tasks are made considerably safer and more
|
||
controllable.</para>
|
||
|
||
<para><application>Kerberos</application> can be described as an
|
||
identity-verifying proxy system. It can also be described as a
|
||
trusted third-party authentication system.
|
||
<application>Kerberos</application> provides only one
|
||
function — the secure authentication of users on the network.
|
||
It does not provide authorization functions (what users are
|
||
allowed to do) or auditing functions (what those users did).
|
||
After a client and server have used
|
||
<application>Kerberos</application> to prove their identity, they
|
||
can also encrypt all of their communications to assure privacy
|
||
and data integrity as they go about their business.</para>
|
||
|
||
<para>Therefore it is highly recommended that
|
||
<application>Kerberos</application> be used with other security
|
||
methods which provide authorization and audit services.</para>
|
||
|
||
<para>The following instructions can be used as a guide on how to set
|
||
up <application>Kerberos</application> as distributed for &os;.
|
||
However, you should refer to the relevant manual pages for a complete
|
||
description.</para>
|
||
|
||
<para>For purposes of demonstrating a <application>Kerberos</application>
|
||
installation, the various name spaces will be handled as follows:</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The <acronym>DNS</acronym> domain (<quote>zone</quote>)
|
||
will be example.org.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>The <application>Kerberos</application> realm will be
|
||
EXAMPLE.ORG.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<note>
|
||
<para>Please use real domain names when setting up
|
||
<application>Kerberos</application> even if you intend to run
|
||
it internally. This avoids <acronym>DNS</acronym> problems
|
||
and assures inter-operation with other
|
||
<application>Kerberos</application> realms.</para>
|
||
</note>
|
||
|
||
<sect2>
|
||
<title>History</title>
|
||
<indexterm>
|
||
<primary>Kerberos5</primary>
|
||
<secondary>history</secondary>
|
||
</indexterm>
|
||
|
||
<para><application>Kerberos</application> was created by
|
||
<acronym>MIT</acronym> as a solution to network security problems.
|
||
The <application>Kerberos</application> protocol uses strong
|
||
cryptography so that a client can prove its identity to a server
|
||
(and vice versa) across an insecure network connection.</para>
|
||
|
||
<para><application>Kerberos</application> is both the name of a
|
||
network authentication protocol and an adjective to describe
|
||
programs that implement the program
|
||
(<application>Kerberos</application> telnet, for example). The
|
||
current version of the protocol is version 5, described in
|
||
<acronym>RFC</acronym> 1510.</para>
|
||
|
||
<para>Several free implementations of this protocol are available,
|
||
covering a wide range of operating systems. The Massachusetts
|
||
Institute of Technology (<acronym>MIT</acronym>), where
|
||
<application>Kerberos</application> was originally developed,
|
||
continues to develop their <application>Kerberos</application>
|
||
package. It is commonly used in the <acronym>US</acronym>
|
||
as a cryptography product, as such it
|
||
has historically been affected by <acronym>US</acronym> export
|
||
regulations. The <acronym>MIT</acronym>
|
||
<application>Kerberos</application> is available as a port
|
||
(<filename role="package">security/krb5</filename>). Heimdal
|
||
<application>Kerberos</application> is another version 5
|
||
implementation, and was explicitly developed outside of the
|
||
<acronym>US</acronym> to avoid export
|
||
regulations (and is thus often included in non-commercial &unix;
|
||
variants). The Heimdal <application>Kerberos</application>
|
||
distribution is available as a port
|
||
(<filename role="package">security/heimdal</filename>), and a
|
||
minimal installation of it is included in the base &os;
|
||
install.</para>
|
||
|
||
<para>In order to reach the widest audience, these instructions assume
|
||
the use of the Heimdal distribution included in &os;.</para>
|
||
|
||
</sect2>
|
||
|
||
<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 — it is the
|
||
computer that issues <application>Kerberos</application> tickets.
|
||
The <acronym>KDC</acronym> is considered <quote>trusted</quote> by
|
||
all other computers in the <application>Kerberos</application>
|
||
realm, and thus has heightened security concerns.</para>
|
||
|
||
<para>Note that while running the <application>Kerberos</application>
|
||
server requires very few computing resources, a dedicated machine
|
||
acting only as a <acronym>KDC</acronym> is recommended for security
|
||
reasons.</para>
|
||
|
||
<para>To begin setting up a <acronym>KDC</acronym>, ensure that your
|
||
<filename>/etc/rc.conf</filename> file contains the correct
|
||
settings to act as a <acronym>KDC</acronym> (you may need to adjust
|
||
paths to reflect your own system):</para>
|
||
|
||
<programlisting>kerberos5_server_enable="YES"
|
||
kadmind5_server_enable="YES"</programlisting>
|
||
|
||
<para>Next we will set up your <application>Kerberos</application>
|
||
config file, <filename>/etc/krb5.conf</filename>:</para>
|
||
|
||
<programlisting>[libdefaults]
|
||
default_realm = EXAMPLE.ORG
|
||
[realms]
|
||
EXAMPLE.ORG = {
|
||
kdc = kerberos.example.org
|
||
admin_server = kerberos.example.org
|
||
}
|
||
[domain_realm]
|
||
.example.org = EXAMPLE.ORG</programlisting>
|
||
|
||
<para>Note that this <filename>/etc/krb5.conf</filename> file implies
|
||
that your <acronym>KDC</acronym> will have the fully-qualified
|
||
hostname of <hostid role="fqdn">kerberos.example.org</hostid>.
|
||
You will need to add a CNAME (alias) entry to your zone file to
|
||
accomplish this if your <acronym>KDC</acronym> has a different
|
||
hostname.</para>
|
||
|
||
<note>
|
||
<para>For large networks with a properly configured
|
||
<acronym>BIND</acronym> <acronym>DNS</acronym> server, the
|
||
above example could be trimmed to:</para>
|
||
|
||
<programlisting>[libdefaults]
|
||
default_realm = EXAMPLE.ORG</programlisting>
|
||
|
||
<para>With the following lines being appended to the
|
||
<hostid role="fqdn">example.org</hostid> zonefile:</para>
|
||
|
||
<programlisting>_kerberos._udp IN SRV 01 00 88 kerberos.example.org.
|
||
_kerberos._tcp IN SRV 01 00 88 kerberos.example.org.
|
||
_kpasswd._udp IN SRV 01 00 464 kerberos.example.org.
|
||
_kerberos-adm._tcp IN SRV 01 00 749 kerberos.example.org.
|
||
_kerberos IN TXT EXAMPLE.ORG</programlisting></note>
|
||
|
||
<note>
|
||
<para>For clients to be able to find the
|
||
<application>Kerberos</application> services, you
|
||
<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 DNS server.</para>
|
||
</note>
|
||
|
||
<para>Next we will create the <application>Kerberos</application>
|
||
database. This database contains the keys of all principals encrypted
|
||
with a master password. You are not
|
||
required to remember this password, it will be stored in a file
|
||
(<filename>/var/heimdal/m-key</filename>). To create the master
|
||
key, run <command>kstash</command> and enter a password.</para>
|
||
|
||
<para>Once the master key has been created, you can initialize the
|
||
database using the <command>kadmin</command> program with the
|
||
<literal>-l</literal> option (standing for <quote>local</quote>).
|
||
This option instructs <command>kadmin</command> to modify the
|
||
database files directly rather than going through the
|
||
<command>kadmind</command> network service. This handles the
|
||
chicken-and-egg problem of trying to connect to the database
|
||
before it is created. Once you have the <command>kadmin</command>
|
||
prompt, use the <command>init</command> command to create your
|
||
realms initial database.</para>
|
||
|
||
<para>Lastly, while still in <command>kadmin</command>, create your
|
||
first principal using the <command>add</command> command. Stick
|
||
to the defaults options for the principal for now, you can always
|
||
change them later with the <command>modify</command> command.
|
||
Note that you can use the <literal>?</literal> command at any
|
||
prompt to see the available options.</para>
|
||
|
||
<para>A sample database creation session is shown below:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kstash</userinput>
|
||
Master key: <userinput>xxxxxxxx</userinput>
|
||
Verifying password - Master key: <userinput>xxxxxxxx</userinput>
|
||
|
||
&prompt.root; <userinput>kadmin -l</userinput>
|
||
kadmin> <userinput>init EXAMPLE.ORG</userinput>
|
||
Realm max ticket life [unlimited]:
|
||
kadmin> <userinput>add tillman</userinput>
|
||
Max ticket life [unlimited]:
|
||
Max renewable life [unlimited]:
|
||
Attributes []:
|
||
Password: <userinput>xxxxxxxx</userinput>
|
||
Verifying password - Password: <userinput>xxxxxxxx</userinput></screen>
|
||
|
||
<para>Now it is time to start up the <acronym>KDC</acronym> services.
|
||
Run <command>/etc/rc.d/kerberos start</command> and
|
||
<command>/etc/rc.d/kadmind start</command> to bring up the
|
||
services. Note that you will not have any kerberized daemons running
|
||
at this point but you should be able to confirm the that the
|
||
<acronym>KDC</acronym> is functioning by obtaining and listing a
|
||
ticket for the principal (user) that you just created from the
|
||
command-line of the <acronym>KDC</acronym> itself:</para>
|
||
|
||
<screen>&prompt.user; <userinput>kinit <replaceable>tillman</replaceable></userinput>
|
||
tillman@EXAMPLE.ORG's Password:
|
||
|
||
&prompt.user; <userinput>klist</userinput>
|
||
Credentials cache: FILE:<filename>/tmp/krb5cc_500</filename>
|
||
Principal: tillman@EXAMPLE.ORG
|
||
|
||
Issued Expires Principal
|
||
Aug 27 15:37:58 Aug 28 01:37:58 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG</screen>
|
||
|
||
<para>The ticket can then be revoked when you have
|
||
finished:</para>
|
||
|
||
<screen>&prompt.user; <userinput>k5destroy</userinput></screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title><application>Kerberos</application> enabling a server with
|
||
Heimdal services</title>
|
||
|
||
<indexterm>
|
||
<primary>Kerberos5</primary>
|
||
<secondary>enabling services</secondary>
|
||
</indexterm>
|
||
|
||
<para>First, we need a copy of the <application>Kerberos</application>
|
||
configuration file, <filename>/etc/krb5.conf</filename>. To do
|
||
so, simply copy it over to the client computer from the
|
||
<acronym>KDC</acronym> in a secure fashion (using network utilities,
|
||
such as &man.scp.1;, or physically via a
|
||
floppy disk).</para>
|
||
|
||
<para>Next you need a <filename>/etc/krb5.keytab</filename> file.
|
||
This is the major difference between a server providing
|
||
<application>Kerberos</application> enabled daemons and a
|
||
workstation — the server must have a
|
||
<filename>keytab</filename> file. This file
|
||
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.
|
||
This explicitly means that transferring it via a clear text
|
||
channel, such as <acronym>FTP</acronym>, is a very bad idea.</para>
|
||
|
||
<para>Typically, you transfer to the <filename>keytab</filename>
|
||
to the server using the <command>kadmin</command> program.
|
||
This is handy because you also need to create the host principal
|
||
(the <acronym>KDC</acronym> end of the
|
||
<filename>krb5.keytab</filename>) using
|
||
<command>kadmin</command>.</para>
|
||
|
||
<para>Note that you must have already obtained a ticket and that this
|
||
ticket must be allowed to use the <command>kadmin</command>
|
||
interface in the <filename>kadmind.acl</filename>. See the section
|
||
titled <quote>Remote administration</quote> in the Heimdal info
|
||
pages (<command>info heimdal</command>) for details on designing
|
||
access control lists. If you do not want to enable remote
|
||
<command>kadmin</command> access, you can simply securely connect
|
||
to the <acronym>KDC</acronym> (via local console,
|
||
&man.ssh.1; or <application>Kerberos</application>
|
||
&man.telnet.1;) and perform administration locally
|
||
using <command>kadmin -l</command>.</para>
|
||
|
||
<para>After installing the <filename>/etc/krb5.conf</filename> file,
|
||
you can use <command>kadmin</command> from the
|
||
<application>Kerberos</application> server. The
|
||
<command>add --random-key</command> command will let you add the
|
||
server's host principal, and the <command>ext</command> command
|
||
will allow you to extract the server's host principal to its own
|
||
keytab. For example:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kadmin</userinput>
|
||
kadmin><userinput> add --random-key host/myserver.example.org</userinput>
|
||
Max ticket life [unlimited]:
|
||
Max renewable life [unlimited]:
|
||
Attributes []:
|
||
kadmin><userinput> ext host/myserver.example.org</userinput>
|
||
kadmin><userinput> exit</userinput></screen>
|
||
|
||
<para>Note that the <command>ext</command> command (short for
|
||
<quote>extract</quote>) stores the extracted key in
|
||
<filename>/etc/krb5.keytab</filename> by default.</para>
|
||
|
||
<para>If you do not have <command>kadmind</command> running on the
|
||
<acronym>KDC</acronym> (possibly for security reasons) and thus
|
||
do not have access to <command>kadmin</command> remotely, you
|
||
can add the host principal
|
||
(<username>host/myserver.EXAMPLE.ORG</username>) directly on the
|
||
<acronym>KDC</acronym> and then extract it to a temporary file
|
||
(to avoid over-writing the <filename>/etc/krb5.keytab</filename>
|
||
on the <acronym>KDC</acronym>) using something like this:</para>
|
||
|
||
<screen>&prompt.root; <userinput>kadmin</userinput>
|
||
kadmin><userinput> ext --keytab=/tmp/example.keytab host/myserver.example.org</userinput>
|
||
kadmin><userinput> exit</userinput></screen>
|
||
|
||
<para>You can then securely copy the keytab to the server
|
||
computer (using <command>scp</command> or a floppy, for
|
||
example). Be sure to specify a non-default keytab name
|
||
to avoid over-writing the keytab on the
|
||
<acronym>KDC</acronym>.</para>
|
||
|
||
<para>At this point your server can communicate with the
|
||
<acronym>KDC</acronym> (due to its <filename>krb5.conf</filename>
|
||
file) and it can prove its own identity (due to the
|
||
<filename>krb5.keytab</filename> file). It is now ready for
|
||
you to enable some <application>Kerberos</application> services.
|
||
For this example we will enable the <command>telnet</command>
|
||
service by putting a line like this into your
|
||
<filename>/etc/inetd.conf</filename> and then restarting the
|
||
&man.inetd.8; service with
|
||
<command>/etc/rc.d/inetd restart</command>:</para>
|
||
|
||
<programlisting>telnet stream tcp nowait root /usr/libexec/telnetd telnetd -a user</programlisting>
|
||
|
||
<para>The critical bit is that the <command>-a</command>
|
||
(for authentication) type is set to user. Consult the
|
||
&man.telnetd.8; manual page for more details.</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title><application>Kerberos</application> enabling a client with Heimdal</title>
|
||
|
||
<indexterm>
|
||
<primary>Kerberos5</primary>
|
||
<secondary>configure clients</secondary>
|
||
</indexterm>
|
||
|
||
<para>Setting up a client computer is almost trivially easy. As
|
||
far as <application>Kerberos</application> configuration goes,
|
||
you only need the <application>Kerberos</application>
|
||
configuration file, located at <filename>/etc/krb5.conf</filename>.
|
||
Simply securely copy it over to the client computer from the
|
||
<acronym>KDC</acronym>.</para>
|
||
|
||
<para>Test your client computer by attempting to use
|
||
<command>kinit</command>, <command>klist</command>, and
|
||
<command>kdestroy</command> from the client to obtain, show, and
|
||
then delete a ticket for the principal you created above. You
|
||
should also be able to use <application>Kerberos</application>
|
||
applications to connect to <application>Kerberos</application>
|
||
enabled servers, though if that does not work and obtaining a
|
||
ticket does the problem is likely with the server and not with
|
||
the client or the <acronym>KDC</acronym>.</para>
|
||
|
||
<para>When testing an application like <command>telnet</command>,
|
||
try using a packet sniffer (such as &man.tcpdump.1;)
|
||
to confirm that your password is not sent in the clear. Try
|
||
using <command>telnet</command> with the <literal>-x</literal>
|
||
option, which encrypts the entire data stream (similar to
|
||
<command>ssh</command>).</para>
|
||
|
||
<para>Various non-core <application>Kerberos</application> client
|
||
applications are also installed by default. This is where the
|
||
<quote>minimal</quote> nature of the base Heimdal installation is
|
||
felt: <command>telnet</command> is the only
|
||
<application>Kerberos</application> enabled service.</para>
|
||
|
||
<para>The Heimdal port adds some of the missing client applications:
|
||
<application>Kerberos</application> enabled versions of
|
||
<command>ftp</command>, <command>rsh</command>,
|
||
<command>rcp</command>, <command>rlogin</command>, and a few
|
||
other less common programs. The <acronym>MIT</acronym> port also
|
||
contains a full suite of <application>Kerberos</application>
|
||
client applications.</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>User configuration files: <filename>.k5login</filename> and <filename>.k5users</filename></title>
|
||
|
||
<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 (such as
|
||
<username>tillman@EXAMPLE.ORG</username>) mapped to a local
|
||
user account (such as a local account named
|
||
<username>tillman</username>). Client applications such as
|
||
<command>telnet</command> usually do not require a user name
|
||
or a principal.</para>
|
||
|
||
<para>Occasionally, however, you want to grant access to a local
|
||
user account to someone who does not have a matching
|
||
<application>Kerberos</application> principal. For example,
|
||
<username>tillman@EXAMPLE.ORG</username> may need access to the
|
||
local user account <username>webdevelopers</username>. Other
|
||
principals may also need access to that local account.</para>
|
||
|
||
<para>The <filename>.k5login</filename> and
|
||
<filename>.k5users</filename> files, placed in a users home
|
||
directory, can be used similar to a powerful combination of
|
||
<filename>.hosts</filename> and <filename>.rhosts</filename>,
|
||
solving this problem. For example, if a
|
||
<filename>.k5login</filename> with the following
|
||
contents:</para>
|
||
|
||
<screen>tillman@example.org
|
||
jdoe@example.org</screen>
|
||
|
||
<para>Were to be placed into the home directory of the local user
|
||
<username>webdevelopers</username> then both principals listed
|
||
would have access to that account without requiring a shared
|
||
password.</para>
|
||
|
||
<para>Reading the manual pages for these commands is recommended.
|
||
Note that the <command>ksu</command> manual page covers
|
||
<filename>.k5users</filename>.</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title><application>Kerberos</application> Tips, Tricks, and Troubleshooting</title>
|
||
|
||
<indexterm>
|
||
<primary>Kerberos5</primary>
|
||
<secondary>troubleshooting</secondary>
|
||
</indexterm>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>When using either the Heimdal or <acronym>MIT</acronym>
|
||
<application>Kerberos</application> ports ensure that your
|
||
<envar>PATH</envar> environment variable lists the
|
||
<application>Kerberos</application> versions of the client
|
||
applications before the system versions.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Do all the computers in your realm have synchronized
|
||
time settings? If not, authentication may fail.
|
||
<xref linkend="network-ntp"> describes how to synchronize
|
||
clocks using <acronym>NTP</acronym>.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para><acronym>MIT</acronym> and Heimdal inter-operate nicely.
|
||
Except for <command>kadmin</command>, the protocol for
|
||
which is not standardized.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>If you change your hostname, you also need to change your
|
||
<username>host/</username> principal and update your keytab.
|
||
This also applies to special keytab entries like the
|
||
<username>www/</username> principal used for Apache's
|
||
<filename role="package">www/mod_auth_kerb</filename>.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>All hosts in your realm must be resolvable (both forwards
|
||
and reverse) in <acronym>DNS</acronym> (or
|
||
<filename>/etc/hosts</filename> as a minimum). CNAMEs
|
||
will work, but the A and PTR records must be correct and in
|
||
place. The error message is not very intuitive:
|
||
<errorname>Kerberos5 refuses authentication because Read req
|
||
failed: Key table entry not found</errorname>.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Some operating systems that may being acting as clients
|
||
to your <acronym>KDC</acronym> do not set the permissions
|
||
for <command>ksu</command> to be setuid
|
||
<username>root</username>. This means that
|
||
<command>ksu</command> does not work, which is a good
|
||
security idea but annoying. This is not a
|
||
<acronym>KDC</acronym> error.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>With <acronym>MIT</acronym>
|
||
<application>Kerberos</application>, if you want to allow a
|
||
principal to have a ticket life longer than the default ten
|
||
hours, you must use <command>modify_principal</command> in
|
||
<command>kadmin</command> to change the maxlife of both the
|
||
principal in question and the <username>krbtgt</username>
|
||
principal. Then the principal can use the
|
||
<literal>-l</literal> option with <command>kinit</command>
|
||
to request a ticket with a longer lifetime.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<note><para>If you run a packet sniffer on your
|
||
<acronym>KDC</acronym> to add in troubleshooting and then
|
||
run <command>kinit</command> from a workstation, you will
|
||
notice that your <acronym>TGT</acronym> is sent
|
||
immediately upon running <command>kinit</command> —
|
||
even before you type your password! The explanation is
|
||
that the <application>Kerberos</application> server freely
|
||
transmits a <acronym>TGT</acronym> (Ticket Granting
|
||
Ticket) to any unauthorized request; however, every
|
||
<acronym>TGT</acronym> is encrypted in a key derived from
|
||
the user's password. Therefore, when a user types their
|
||
password it is not being sent to the <acronym>KDC</acronym>,
|
||
it is being 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 ticket-granting ticket, which is actually
|
||
encrypted with the <application>Kerberos</application>
|
||
server's own key. This second layer of encryption is
|
||
unknown to the user, but it is what allows the
|
||
<application>Kerberos</application> server to verify
|
||
the authenticity of each <acronym>TGT</acronym>.</para></note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>If you want to use long ticket lifetimes (a week, for
|
||
example) and you are using <application>OpenSSH</application>
|
||
to connect to the machine where your ticket is stored, make
|
||
sure that <application>Kerberos</application>
|
||
<option>TicketCleanup</option> is set to <literal>no</literal>
|
||
in your <filename>sshd_config</filename> or else your tickets
|
||
will be deleted when you log out.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Remember that host principals can have a longer ticket
|
||
lifetime as well. If your user principal has a lifetime of a
|
||
week but the host you are connecting to has a lifetime of nine
|
||
hours, you will have an expired host principal in your cache
|
||
and the ticket cache will not work as expected.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>When setting up a <filename>krb5.dict</filename> file to
|
||
prevent specific bad passwords from being used (the manual page
|
||
for <command>kadmind</command> covers this briefly), remember
|
||
that it only applies to principals that have a password policy
|
||
assigned to them. The <filename>krb5.dict</filename> files
|
||
format is simple: one string per line. Creating a symbolic
|
||
link to <filename>/usr/share/dict/words</filename> might be
|
||
useful.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Differences with the <acronym>MIT</acronym> port</title>
|
||
|
||
<para>The major difference between the <acronym>MIT</acronym>
|
||
and Heimdal installs relates to the <command>kadmin</command>
|
||
program which has a different (but equivalent) set of commands
|
||
and uses a different protocol. This has a large implications
|
||
if your <acronym>KDC</acronym> is <acronym>MIT</acronym> as you
|
||
will not be able to use the Heimdal <command>kadmin</command>
|
||
program to administer your <acronym>KDC</acronym> remotely
|
||
(or vice versa, for that matter).</para>
|
||
|
||
<para>The client applications may also take slightly different
|
||
command line options to accomplish the same tasks. Following
|
||
the instructions on the <acronym>MIT</acronym>
|
||
<application>Kerberos</application> web site
|
||
(<ulink url="http://web.mit.edu/Kerberos/www/"></ulink>)
|
||
is recommended. Be careful of path issues: the
|
||
<acronym>MIT</acronym> port installs into
|
||
<filename>/usr/local/</filename> by default, and the
|
||
<quote>normal</quote> system applications may be run instead
|
||
of <acronym>MIT</acronym> if your <envar>PATH</envar>
|
||
environment variable lists the system directories first.</para>
|
||
|
||
<note><para>With the <acronym>MIT</acronym>
|
||
<filename role="package">security/krb5</filename> port
|
||
that is provided by &os;, be sure to read the
|
||
<filename>/usr/local/share/doc/krb5/README.FreeBSD</filename>
|
||
file installed by the port if you want to understand why logins
|
||
via <command>telnetd</command> and <command>klogind</command>
|
||
behave somewhat oddly. Most importantly, correcting the
|
||
<quote>incorrect permissions on cache file</quote> behavior
|
||
requires that the <command>login.krb5</command> binary be used
|
||
for authentication so that it can properly change ownership for
|
||
the forwarded credentials.</para></note>
|
||
|
||
<para>The <filename>rc.conf</filename> must also be modified
|
||
to contain the following configuration:</para>
|
||
|
||
<programlisting>kerberos5_server="/usr/local/sbin/krb5kdc"
|
||
kadmind5_server="/usr/local/sbin/kadmind"
|
||
kerberos5_server_enable="YES"
|
||
kadmind5_server_enable="YES"</programlisting>
|
||
|
||
<para>This is done because the applications for
|
||
<acronym>MIT</acronym> kerberos installs binaries in the
|
||
<filename role="directory">/usr/local</filename>
|
||
hierarchy.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Mitigating limitations found in <application>Kerberos</application></title>
|
||
|
||
<indexterm>
|
||
<primary>Kerberos5</primary>
|
||
<secondary>limitations and shortcomings</secondary>
|
||
</indexterm>
|
||
|
||
<sect3>
|
||
<title><application>Kerberos</application> is an all-or-nothing approach</title>
|
||
|
||
<para>Every service enabled on the network must be modified to
|
||
work with <application>Kerberos</application> (or be otherwise
|
||
secured against network attacks) or else the users credentials
|
||
could be stolen and re-used. An example of this would be
|
||
<application>Kerberos</application> enabling all remote shells
|
||
(via <command>rsh</command> and <command>telnet</command>, for
|
||
example) but not converting the <acronym>POP3</acronym> mail
|
||
server which sends passwords in plain text.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title><application>Kerberos</application> is intended for single-user workstations</title>
|
||
|
||
<para>In a multi-user environment,
|
||
<application>Kerberos</application> is less secure.
|
||
This is because it stores the tickets in the
|
||
<filename>/tmp</filename> directory, which is readable by all
|
||
users. If a user is sharing a computer with several other
|
||
people simultaneously (i.e. multi-user), it is possible that
|
||
the user's tickets can be stolen (copied) by another
|
||
user.</para>
|
||
|
||
<para>This can be overcome with the <literal>-c</literal>
|
||
filename command-line option or (preferably) the
|
||
<envar>KRB5CCNAME</envar> environment variable, but this
|
||
is rarely done. In principal, storing the ticket in the users
|
||
home directory and using simple file permissions can mitigate
|
||
this problem.</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>The KDC is a single point of failure</title>
|
||
|
||
<para>By design, the <acronym>KDC</acronym> must be as secure as
|
||
the master password database is contained on it. The
|
||
<acronym>KDC</acronym> should have absolutely no other
|
||
services running on it and should be physically secured. The
|
||
danger is high because <application>Kerberos</application>
|
||
stores all passwords encrypted with the same key (the
|
||
<quote>master</quote> key), which in turn is stored as a file
|
||
on the <acronym>KDC</acronym>.</para>
|
||
|
||
<para>As a side note, a compromised master key is not quite as
|
||
bad as one might normally 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 your <acronym>KDC</acronym> is secure, an attacker
|
||
cannot do much with the master key.</para>
|
||
|
||
<para>Additionally, if the <acronym>KDC</acronym> is unavailable
|
||
(perhaps due to a denial of service attack or network problems)
|
||
the network services are unusable as authentication can not be
|
||
performed, a recipe for a denial-of-service attack. This can
|
||
alleviated with multiple <acronym>KDC</acronym>s (a single
|
||
master and one or more slaves) and with careful implementation
|
||
of secondary or fall-back authentication
|
||
(<acronym>PAM</acronym> is excellent for this).</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title><application>Kerberos</application> Shortcomings</title>
|
||
|
||
<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> (for example) could record all user
|
||
names and passwords. Something like
|
||
<filename role="package">security/tripwire</filename> or
|
||
other file system integrity checking tools can alleviate
|
||
this.</para>
|
||
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Resources and further information</title>
|
||
|
||
<indexterm>
|
||
<primary>Kerberos5</primary>
|
||
<secondary>external resources</secondary>
|
||
</indexterm>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><ulink
|
||
url="http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html">
|
||
The <application>Kerberos</application> FAQ</ulink></para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para><ulink url="http://web.mit.edu/Kerberos/www/dialogue.html">Designing
|
||
an Authentication System: a Dialog in Four Scenes</ulink></para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para><ulink url="http://www.ietf.org/rfc/rfc1510.txt?number=1510">RFC 1510,
|
||
The <application>Kerberos</application> Network Authentication Service
|
||
(V5)</ulink></para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para><ulink url="http://web.mit.edu/Kerberos/www/"><acronym>MIT</acronym>
|
||
<application>Kerberos</application> home page</ulink></para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para><ulink url="http://www.pdc.kth.se/heimdal/">Heimdal
|
||
<application>Kerberos</application> home page</ulink></para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="openssl">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
<surname>Rhodes</surname>
|
||
<contrib>Written by: </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
<title>OpenSSL</title>
|
||
<indexterm>
|
||
<primary>security</primary>
|
||
<secondary>OpenSSL</secondary>
|
||
</indexterm>
|
||
|
||
<para>One feature that many users overlook is the
|
||
<application>OpenSSL</application> toolkit included
|
||
in &os;. <application>OpenSSL</application> provides an
|
||
encryption transport layer on top of the normal communications
|
||
layer; thus allowing it to be intertwined with many network
|
||
applications and services.</para>
|
||
|
||
<para>Some uses of <application>OpenSSL</application> may include
|
||
encrypted authentication of mail clients, web based transactions
|
||
such as credit card payments and more. Many ports such as
|
||
<filename role="package">www/apache13-ssl</filename>, and
|
||
<filename role="package">mail/sylpheed-claws</filename>
|
||
will offer compilation support for building with
|
||
<application>OpenSSL</application>.</para>
|
||
|
||
<note>
|
||
<para>In most cases the Ports Collection will attempt to build
|
||
the <filename role="package">security/openssl</filename> port
|
||
unless the <makevar>WITH_OPENSSL_BASE</makevar> make variable
|
||
is explicitly set to <quote>yes</quote>.</para>
|
||
</note>
|
||
|
||
<para>The version of <application>OpenSSL</application> included
|
||
in &os; supports Secure Sockets Layer v2/v3 (SSLv2/SSLv3),
|
||
Transport Layer Security v1 (TLSv1) network security protocols
|
||
and can be used as a general cryptographic library.</para>
|
||
|
||
<note>
|
||
<para>While <application>OpenSSL</application> supports the
|
||
<acronym>IDEA</acronym> algorithm, it is disabled by default
|
||
due to United States patents. To use it, the license should
|
||
be reviewed and, if the restrictions are acceptable, the
|
||
<makevar>MAKE_IDEA</makevar> variable must be set in
|
||
<filename>make.conf</filename>.</para>
|
||
</note>
|
||
|
||
<para>One of the most common uses of
|
||
<application>OpenSSL</application> is to provide certificates for
|
||
use with software applications. These certificates ensure
|
||
that the credentials of the company or individual are valid
|
||
and not fraudulent. If the certificate in question has
|
||
not been verified by one of the several <quote>Certificate Authorities</quote>,
|
||
or <acronym>CA</acronym>s, a warning is usually produced. A
|
||
Certificate Authority is a company, such as <ulink url="http://www.verisign.com">VeriSign</ulink>, which will
|
||
sign certificates in order to validate credentials of individuals
|
||
or companies. This process has a cost associated with it and
|
||
is definitely not a requirement for using certificates; however,
|
||
it can put some of the more paranoid users at ease.</para>
|
||
|
||
<sect2>
|
||
<title>Generating Certificates</title>
|
||
|
||
<indexterm>
|
||
<primary>OpenSSL</primary>
|
||
<secondary>certificate generation</secondary>
|
||
</indexterm>
|
||
|
||
<para>To generate a certificate, the following command is
|
||
available:</para>
|
||
|
||
<screen>&prompt.root; <userinput>openssl req -new -nodes -out req.pem -keyout cert.pem</userinput>
|
||
Generating a 1024 bit RSA private key
|
||
................++++++
|
||
.......................................++++++
|
||
writing new private key to 'cert.pem'
|
||
-----
|
||
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 []:<userinput><replaceable>SOME PASSWORD</replaceable></userinput>
|
||
An optional company name []:<userinput><replaceable>Another Name</replaceable></userinput></screen>
|
||
|
||
<para>Notice the response directly after the
|
||
<quote>Common Name</quote> prompt shows a domain name.
|
||
This prompt requires a server name to be entered for
|
||
verification purposes; placing anything but a domain name
|
||
would yield a useless certificate. Other options, for
|
||
instance expire time, alternate encryption algorithms, etc.
|
||
are available. A complete list may be obtained by viewing
|
||
the &man.openssl.1; manual page.</para>
|
||
|
||
<para>Two files should now exist in
|
||
the directory in which the aforementioned command was issued.
|
||
The certificate request, <filename>req.pem</filename>, may be
|
||
sent to a certificate authority who will validate the credentials
|
||
that you entered, sign the request and return the certificate to
|
||
you. The second file created will be named <filename>cert.pem</filename>
|
||
and is the private key for the certificate and should be
|
||
protected at all costs; if this falls in the hands of others it
|
||
can be used to impersonate you (or your server).</para>
|
||
|
||
<para>In cases where 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 dsaparam -rand -genkey -out <filename>myRSA.key</filename> 1024</userinput></screen>
|
||
|
||
<para>Next, generate the <acronym>CA</acronym> key:</para>
|
||
|
||
<screen>&prompt.root; <userinput>openssl gendsa -des3 -out <filename>myca.key</filename> <filename>myRSA.key</filename></userinput></screen>
|
||
|
||
<para>Use this key to create the certificate:</para>
|
||
|
||
<screen>&prompt.root; <userinput>openssl req -new -x509 -days 365 -key <filename>myca.key</filename> -out <filename>new.crt</filename></userinput></screen>
|
||
|
||
<para>Two new files should appear in the directory: a certificate
|
||
authority signature file, <filename>myca.key</filename> and the
|
||
certificate itself, <filename>new.crt</filename>. These should
|
||
be placed in a directory, preferably under
|
||
<filename class="directory">/etc</filename>, which is readable
|
||
only by <username>root</username>. Permissions of 0700 should be fine for this and
|
||
they can be set with the <command>chmod</command>
|
||
utility.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Using Certificates, an Example</title>
|
||
|
||
<para>So what can these files do? A good use would be to
|
||
encrypt connections to the <application>Sendmail</application>
|
||
<acronym>MTA</acronym>. This would dissolve the use of clear
|
||
text authentication for users who send mail via the local
|
||
<acronym>MTA</acronym>.</para>
|
||
|
||
<note>
|
||
<para>This is not the best use in the world as some
|
||
<acronym>MUA</acronym>s will present the user with an
|
||
error if they have not installed the certificate locally.
|
||
Refer to the documentation included with the software for
|
||
more information on certificate installation.</para>
|
||
</note>
|
||
|
||
<para>The following lines should be placed inside the
|
||
local <filename>.mc</filename> file:</para>
|
||
|
||
<programlisting>dnl SSL Options
|
||
define(`confCACERT_PATH',`/etc/certs')dnl
|
||
define(`confCACERT',`/etc/certs/new.crt')dnl
|
||
define(`confSERVER_CERT',`/etc/certs/new.crt')dnl
|
||
define(`confSERVER_KEY',`/etc/certs/myca.key')dnl
|
||
define(`confTLS_SRV_OPTIONS', `V')dnl</programlisting>
|
||
|
||
<para>Where <filename class="directory">/etc/certs/</filename>
|
||
is the directory to be used for storing the certificate
|
||
and key files locally. The last few requirements are a rebuild
|
||
of the local <filename>.cf</filename> file. This is easily
|
||
achieved by typing <command>make</command>
|
||
<parameter>install</parameter> within the
|
||
<filename class="directory">/etc/mail</filename>
|
||
directory. Follow that up with <command>make</command>
|
||
<parameter>restart</parameter> which should start the
|
||
<application>Sendmail</application> daemon.</para>
|
||
|
||
<para>If all went well there will be no error messages in the
|
||
<filename>/var/log/maillog</filename> file and
|
||
<application>Sendmail</application> will show up in the process
|
||
list.</para>
|
||
|
||
<para>For a simple test, simply connect to the mail server
|
||
using the &man.telnet.1; utility:</para>
|
||
|
||
<screen>&prompt.root; <userinput>telnet <replaceable>example.com</replaceable> 25</userinput>
|
||
Trying 192.0.34.166...
|
||
Connected to <hostid role="fqdn">example.com</hostid>.
|
||
Escape character is '^]'.
|
||
220 <hostid role="fqdn">example.com</hostid> ESMTP Sendmail 8.12.10/8.12.10; Tue, 31 Aug 2004 03:41:22 -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 <hostid role="fqdn">example.com</hostid> closing connection
|
||
Connection closed by foreign host.</screen>
|
||
|
||
<para>If the <quote>STARTTLS</quote> line appears in the output
|
||
then everything is working correctly.</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="ipsec">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Nik</firstname>
|
||
<surname>Clayton</surname>
|
||
<affiliation>
|
||
<address><email>nik@FreeBSD.org</email></address>
|
||
</affiliation>
|
||
<contrib>Written by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
|
||
<indexterm>
|
||
<primary>IPsec</primary>
|
||
</indexterm>
|
||
|
||
<title>VPN over IPsec</title>
|
||
<para>Creating a VPN between two networks, separated by the
|
||
Internet, using FreeBSD gateways.</para>
|
||
|
||
<sect2>
|
||
<sect2info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Hiten M.</firstname>
|
||
<surname>Pandya</surname>
|
||
<affiliation>
|
||
<address><email>hmp@FreeBSD.org</email></address>
|
||
</affiliation>
|
||
<contrib>Written by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect2info>
|
||
|
||
<title>Understanding IPsec</title>
|
||
|
||
<para>This section will guide you through the process of setting
|
||
up IPsec, and to use it in an environment which consists of
|
||
FreeBSD and <application>µsoft.windows; 2000/XP</application>
|
||
machines, to make them communicate securely. In order to set up
|
||
IPsec, it is necessary that you are familiar with the concepts
|
||
of building a custom kernel (see
|
||
<xref linkend="kernelconfig">).</para>
|
||
|
||
<para><emphasis>IPsec</emphasis> is a protocol which sits on top
|
||
of the Internet Protocol (IP) layer. It allows two or more
|
||
hosts to communicate in a secure manner (hence the name). The
|
||
FreeBSD IPsec <quote>network stack</quote> is based on the
|
||
<ulink url="http://www.kame.net/">KAME</ulink> implementation,
|
||
which has support for both protocol families, IPv4 and
|
||
IPv6.</para>
|
||
|
||
<note>
|
||
<para>FreeBSD contains a <quote>hardware
|
||
accelerated</quote> IPsec stack, known as <quote>Fast
|
||
IPsec</quote>, that was obtained from OpenBSD. It employs
|
||
cryptographic hardware (whenever possible) via the
|
||
&man.crypto.4; subsystem to optimize the performance of IPsec.
|
||
This subsystem is new, and does not support all the features
|
||
that are available in the KAME version of IPsec. However, in
|
||
order to enable hardware-accelerated IPsec, the following
|
||
kernel option has to be added to your kernel configuration
|
||
file:</para>
|
||
|
||
<indexterm>
|
||
<primary>kernel options</primary>
|
||
<secondary>FAST_IPSEC</secondary>
|
||
</indexterm>
|
||
|
||
<screen>
|
||
options FAST_IPSEC # new IPsec (cannot define w/ IPSEC)
|
||
</screen>
|
||
|
||
<para> Note, that it is not currently possible to use the
|
||
<quote>Fast IPsec</quote> subsystem in lieu of the KAME
|
||
implementation of IPsec. Consult the &man.fast.ipsec.4;
|
||
manual page for more information.</para>
|
||
</note>
|
||
|
||
<note>
|
||
<para>To let firewalls properly track state for &man.gif.4;
|
||
tunnels too, you have to enable the
|
||
<option>IPSEC_FILTERGIF</option> in your kernel
|
||
configuration:</para>
|
||
|
||
<screen>
|
||
options IPSEC_FILTERGIF #filter ipsec packets from a tunnel
|
||
</screen>
|
||
</note>
|
||
|
||
<indexterm>
|
||
<primary>IPsec</primary>
|
||
<secondary>ESP</secondary>
|
||
</indexterm>
|
||
|
||
<indexterm>
|
||
<primary>IPsec</primary>
|
||
<secondary>AH</secondary>
|
||
</indexterm>
|
||
|
||
<para>IPsec consists of two sub-protocols:</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><emphasis>Encapsulated Security Payload
|
||
(ESP)</emphasis>, protects the IP packet data from third
|
||
party interference, by encrypting the contents using
|
||
symmetric cryptography algorithms (like Blowfish,
|
||
3DES).</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><emphasis>Authentication Header (AH)</emphasis>,
|
||
protects the IP packet header from third party interference
|
||
and spoofing, by computing a cryptographic checksum and
|
||
hashing the IP 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>
|
||
</itemizedlist>
|
||
|
||
<para><acronym>ESP</acronym> and <acronym>AH</acronym> can
|
||
either be used together or separately, depending on the
|
||
environment.</para>
|
||
|
||
<indexterm>
|
||
<primary>VPN</primary>
|
||
</indexterm>
|
||
|
||
<indexterm>
|
||
<primary>virtual private network</primary>
|
||
<see>VPN</see>
|
||
</indexterm>
|
||
|
||
<para>IPsec can either be used to directly encrypt the traffic
|
||
between two hosts (known as <emphasis>Transport
|
||
Mode</emphasis>); or to build <quote>virtual tunnels</quote>
|
||
between two subnets, which could be used for secure
|
||
communication between two corporate networks (known as
|
||
<emphasis>Tunnel Mode</emphasis>). The latter is more commonly
|
||
known as a <emphasis>Virtual Private Network (VPN)</emphasis>.
|
||
The &man.ipsec.4; manual page should be consulted for detailed
|
||
information on the IPsec subsystem in FreeBSD.</para>
|
||
|
||
<para>To add IPsec support to your kernel, add the following
|
||
options to your kernel configuration file:</para>
|
||
|
||
<indexterm>
|
||
<primary>kernel options</primary>
|
||
<secondary>IPSEC</secondary>
|
||
</indexterm>
|
||
|
||
<indexterm>
|
||
<primary>kernel options</primary>
|
||
<secondary>IPSEC_ESP</secondary>
|
||
</indexterm>
|
||
|
||
<screen>
|
||
options IPSEC #IP security
|
||
options IPSEC_ESP #IP security (crypto; define w/ IPSEC)
|
||
</screen>
|
||
|
||
<indexterm>
|
||
<primary>kernel options</primary>
|
||
<secondary>IPSEC_DEBUG</secondary>
|
||
</indexterm>
|
||
|
||
<para>If IPsec debugging support is desired, the following
|
||
kernel option should also be added:</para>
|
||
|
||
<screen>
|
||
options IPSEC_DEBUG #debug for IP security
|
||
</screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>The Problem</title>
|
||
|
||
<para>There is no standard for what constitutes a VPN. VPNs can
|
||
be implemented using a number of different technologies, each of
|
||
which have their own strengths and weaknesses. This section
|
||
presents a scenario, and the strategies used for implementing a
|
||
VPN for this scenario.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>The Scenario: Two networks, connected to the Internet, to
|
||
behave as one</title>
|
||
|
||
<indexterm>
|
||
<primary>VPN</primary>
|
||
<secondary>creating</secondary>
|
||
</indexterm>
|
||
|
||
<para>The premise is as follows:</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>You have at least two sites</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Both sites are using IP internally</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Both sites are connected to the Internet, through a
|
||
gateway that is running FreeBSD.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The gateway on each network has at least one public IP
|
||
address.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The internal addresses of the two networks can be
|
||
public or private IP addresses, it does not matter. You can
|
||
be running NAT on the gateway machine if necessary.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The internal IP addresses of the two networks
|
||
<emphasis>do not collide</emphasis>. While I expect it is
|
||
theoretically possible to use a combination of VPN
|
||
technology and NAT to get this to work, I expect it to be a
|
||
configuration nightmare.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>If you find that you are trying to connect two networks,
|
||
both of which, internally, use the same private IP address range
|
||
(e.g. both of them use <hostid
|
||
role="ipaddr">192.168.1.x</hostid>), then one of the networks will
|
||
have to be renumbered.</para>
|
||
|
||
<para>The network topology might look something like this:</para>
|
||
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="security/ipsec-network" align="center">
|
||
</imageobject>
|
||
|
||
<textobject>
|
||
<literallayout class="monospaced">Network #1 [ Internal Hosts ] Private Net, 192.168.1.2-254
|
||
[ Win9x/NT/2K ]
|
||
[ UNIX ]
|
||
|
|
||
|
|
||
.---[fxp1]---. Private IP, 192.168.1.1
|
||
| FreeBSD |
|
||
`---[fxp0]---' Public IP, A.B.C.D
|
||
|
|
||
|
|
||
-=-=- Internet -=-=-
|
||
|
|
||
|
|
||
.---[fxp0]---. Public IP, W.X.Y.Z
|
||
| FreeBSD |
|
||
`---[fxp1]---' Private IP, 192.168.2.1
|
||
|
|
||
|
|
||
Network #2 [ Internal Hosts ]
|
||
[ Win9x/NT/2K ] Private Net, 192.168.2.2-254
|
||
[ UNIX ]</literallayout>
|
||
</textobject>
|
||
</mediaobject>
|
||
|
||
<para>Notice the two public IP addresses. I will use the letters to
|
||
refer to them in the rest of this article. Anywhere you see those
|
||
letters in this article, replace them with your own public IP
|
||
addresses. Note also that internally, the two gateway
|
||
machines have .1 IP addresses, and that the two networks have
|
||
different private IP addresses (<hostid
|
||
role="ipaddr">192.168.1.x</hostid> and <hostid
|
||
role="ipaddr">192.168.2.x</hostid> respectively). All the
|
||
machines on the private networks have been configured to use the
|
||
<hostid role="ipaddr">.1</hostid> machine as their default
|
||
gateway.</para>
|
||
|
||
<para>The intention is that, from a network point of view, each
|
||
network should view the machines on the other network as though
|
||
they were directly attached the same router -- albeit a slightly
|
||
slow router with an occasional tendency to drop packets.</para>
|
||
|
||
<para>This means that (for example), machine <hostid
|
||
role="ipaddr">192.168.1.20</hostid> should be able to run</para>
|
||
|
||
<programlisting>ping 192.168.2.34</programlisting>
|
||
|
||
<para>and have it work, transparently. &windows; machines should
|
||
be able to see the machines on the other network, browse file
|
||
shares, and so on, in exactly the same way that they can browse
|
||
machines on the local network.</para>
|
||
|
||
<para>And the whole thing has to be secure. This means that
|
||
traffic between the two networks has to be encrypted.</para>
|
||
|
||
<para>Creating a VPN between these two networks is a multi-step
|
||
process. The stages are as follows:</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Create a <quote>virtual</quote> network link between the two
|
||
networks, across the Internet. Test it, using tools like
|
||
&man.ping.8;, to make sure it works.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Apply security policies to ensure that traffic between
|
||
the two networks is transparently encrypted and decrypted as
|
||
necessary. Test this, using tools like &man.tcpdump.1;, to
|
||
ensure that traffic is encrypted.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Configure additional software on the FreeBSD gateways,
|
||
to allow &windows; machines to see one another across the
|
||
VPN.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<sect3>
|
||
<title>Step 1: Creating and testing a <quote>virtual</quote>
|
||
network link</title>
|
||
|
||
<para>Suppose that you were logged in to the gateway machine on
|
||
network #1 (with public IP address <hostid
|
||
role="ipaddr">A.B.C.D</hostid>, private IP address <hostid
|
||
role="ipaddr">192.168.1.1</hostid>), and you ran <command>ping
|
||
192.168.2.1</command>, which is the private address of the machine
|
||
with IP address <hostid role="ipaddr">W.X.Y.Z</hostid>. What
|
||
needs to happen in order for this to work?</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>The gateway machine needs to know how to reach <hostid
|
||
role="ipaddr">192.168.2.1</hostid>. In other words, it needs
|
||
to have a route to <hostid
|
||
role="ipaddr">192.168.2.1</hostid>.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Private IP addresses, such as those in the <hostid
|
||
role="ipaddr">192.168.x</hostid> range are not supposed to
|
||
appear on the Internet at large. Instead, each packet you
|
||
send to <hostid role="ipaddr">192.168.2.1</hostid> will need
|
||
to be wrapped up inside another packet. This packet will need
|
||
to appear to be from <hostid role="ipaddr">A.B.C.D</hostid>,
|
||
and it will have to be sent to <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid>. This process is called
|
||
<firstterm>encapsulation</firstterm>.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Once this packet arrives at <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid> it will need to
|
||
<quote>unencapsulated</quote>, and delivered to <hostid
|
||
role="ipaddr">192.168.2.1</hostid>.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>You can think of this as requiring a <quote>tunnel</quote>
|
||
between the two networks. The two <quote>tunnel mouths</quote> are the IP
|
||
addresses <hostid role="ipaddr">A.B.C.D</hostid> and <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid>, and the tunnel must be told the
|
||
addresses of the private IP addresses that will be allowed to pass
|
||
through it. The tunnel is used to transfer traffic with private
|
||
IP addresses across the public Internet.</para>
|
||
|
||
<para>This tunnel is created by using the generic interface, or
|
||
<devicename>gif</devicename> devices on FreeBSD. As you can
|
||
imagine, the <devicename>gif</devicename> interface on each
|
||
gateway host must be configured with four IP addresses; two for
|
||
the public IP addresses, and two for the private IP
|
||
addresses.</para>
|
||
|
||
<para>Support for the gif device must be compiled in to the
|
||
&os; kernel on both machines. You can do this by adding the
|
||
line:</para>
|
||
|
||
<programlisting>device gif</programlisting>
|
||
|
||
<para>to the kernel configuration files on both machines, and
|
||
then compile, install, and reboot as normal.</para>
|
||
|
||
<para>Configuring the tunnel is a two step process. First the
|
||
tunnel must be told what the outside (or public) IP addresses
|
||
are, using &man.ifconfig.8;. Then the private IP addresses must be
|
||
configured using &man.ifconfig.8;.</para>
|
||
|
||
<para>On the gateway machine on network #1 you would run the
|
||
following commands to configure the tunnel.</para>
|
||
|
||
<screen>&prompt.root; <userinput>ifconfig <replaceable>gif0</replaceable> create</userinput>
|
||
&prompt.root; <userinput>ifconfig <replaceable>gif0</replaceable> tunnel <replaceable>A.B.C.D</replaceable> <replaceable>W.X.Y.Z</replaceable></userinput>
|
||
&prompt.root; <userinput>ifconfig <replaceable>gif0</replaceable> inet <replaceable>192.168.1.1</replaceable> <replaceable>192.168.2.1</replaceable> netmask <replaceable>0xffffffff</replaceable></userinput>
|
||
</screen>
|
||
|
||
<para>On the other gateway machine you run the same commands,
|
||
but with the order of the IP addresses reversed.</para>
|
||
|
||
<screen>&prompt.root; <userinput>ifconfig <replaceable>gif0</replaceable> create</userinput>
|
||
&prompt.root; <userinput>ifconfig <replaceable>gif0</replaceable> tunnel <replaceable>W.X.Y.Z</replaceable> <replaceable>A.B.C.D</replaceable></userinput>
|
||
&prompt.root; <userinput>ifconfig <replaceable>gif0</replaceable> inet <replaceable>192.168.2.1</replaceable> <replaceable>192.168.1.1</replaceable> netmask <replaceable>0xffffffff</replaceable></userinput>
|
||
</screen>
|
||
|
||
<para>You can then run:</para>
|
||
|
||
<programlisting>ifconfig gif0</programlisting>
|
||
|
||
<para>to see the configuration. For example, on the network #1
|
||
gateway, you would see this:</para>
|
||
|
||
<screen>&prompt.root; <userinput>ifconfig gif0</userinput>
|
||
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
|
||
tunnel inet A.B.C.D --> W.X.Y.Z
|
||
inet 192.168.1.1 --> 192.168.2.1 netmask 0xffffffff
|
||
</screen>
|
||
|
||
<para>As you can see, a tunnel has been created between the
|
||
physical addresses <hostid role="ipaddr">A.B.C.D</hostid> and
|
||
<hostid role="ipaddr">W.X.Y.Z</hostid>, and the traffic allowed
|
||
through the tunnel is that between <hostid
|
||
role="ipaddr">192.168.1.1</hostid> and <hostid
|
||
role="ipaddr">192.168.2.1</hostid>.</para>
|
||
|
||
<para>This will also have added an entry to the routing table
|
||
on both machines, which you can examine with the command <command>netstat -rn</command>.
|
||
This output is from the gateway host on network #1.</para>
|
||
|
||
<screen>&prompt.root; <userinput>netstat -rn</userinput>
|
||
Routing tables
|
||
|
||
Internet:
|
||
Destination Gateway Flags Refs Use Netif Expire
|
||
...
|
||
192.168.2.1 192.168.1.1 UH 0 0 gif0
|
||
...
|
||
</screen>
|
||
|
||
<para>As the <quote>Flags</quote> value indicates, this is a
|
||
host route, which means that each gateway knows how to reach the
|
||
other gateway, but they do not know how to reach the rest of
|
||
their respective networks. That problem will be fixed
|
||
shortly.</para>
|
||
|
||
<para>It is likely that you are running a firewall on both
|
||
machines. This will need to be circumvented for your VPN
|
||
traffic. You might want to allow all traffic between both
|
||
networks, or you might want to include firewall rules that
|
||
protect both ends of the VPN from one another.</para>
|
||
|
||
<para>It greatly simplifies testing if you configure the
|
||
firewall to allow all traffic through the VPN. You can always
|
||
tighten things up later. If you are using &man.ipfw.8; on the
|
||
gateway machines then a command like</para>
|
||
|
||
<programlisting>ipfw add 1 allow ip from any to any via gif0</programlisting>
|
||
|
||
<para>will allow all traffic between the two end points of the
|
||
VPN, without affecting your other firewall rules. Obviously
|
||
you will need to run this command on both gateway hosts.</para>
|
||
|
||
<para>This is sufficient to allow each gateway machine to ping
|
||
the other. On <hostid role="ipaddr">192.168.1.1</hostid>, you
|
||
should be able to run</para>
|
||
|
||
<programlisting>ping 192.168.2.1</programlisting>
|
||
|
||
<para>and get a response, and you should be able to do the same
|
||
thing on the other gateway machine.</para>
|
||
|
||
<para>However, you will not be able to reach internal machines
|
||
on either network yet. This is because of the routing --
|
||
although the gateway machines know how to reach one another,
|
||
they do not know how to reach the network behind each one.</para>
|
||
|
||
<para>To solve this problem you must add a static route on each
|
||
gateway machine. The command to do this on the first gateway
|
||
would be:</para>
|
||
|
||
<programlisting>route add 192.168.2.0 192.168.2.1 netmask 0xffffff00
|
||
</programlisting>
|
||
|
||
<para>This says <quote>In order to reach the hosts on the
|
||
network <hostid role="ipaddr">192.168.2.0</hostid>, send the
|
||
packets to the host <hostid
|
||
role="ipaddr">192.168.2.1</hostid></quote>. You will need to
|
||
run a similar command on the other gateway, but with the
|
||
<hostid role="ipaddr">192.168.1.x</hostid> addresses
|
||
instead.</para>
|
||
|
||
<para>IP traffic from hosts on one network will now be able to
|
||
reach hosts on the other network.</para>
|
||
|
||
<para>That has now created two thirds of a VPN between the two
|
||
networks, in as much as it is <quote>virtual</quote> and it is a
|
||
<quote>network</quote>. It is not private yet. You can test
|
||
this using &man.ping.8; and &man.tcpdump.1;. Log in to the
|
||
gateway host and run</para>
|
||
|
||
<programlisting>tcpdump dst host 192.168.2.1</programlisting>
|
||
|
||
<para>In another log in session on the same host run</para>
|
||
|
||
<programlisting>ping 192.168.2.1</programlisting>
|
||
|
||
<para>You will see output that looks something like this:</para>
|
||
|
||
<programlisting>
|
||
16:10:24.018080 192.168.1.1 > 192.168.2.1: icmp: echo request
|
||
16:10:24.018109 192.168.1.1 > 192.168.2.1: icmp: echo reply
|
||
16:10:25.018814 192.168.1.1 > 192.168.2.1: icmp: echo request
|
||
16:10:25.018847 192.168.1.1 > 192.168.2.1: icmp: echo reply
|
||
16:10:26.028896 192.168.1.1 > 192.168.2.1: icmp: echo request
|
||
16:10:26.029112 192.168.1.1 > 192.168.2.1: icmp: echo reply
|
||
</programlisting>
|
||
|
||
<para>As you can see, the ICMP messages are going back and forth
|
||
unencrypted. If you had used the <option>-s</option> parameter to
|
||
&man.tcpdump.1; to grab more bytes of data from the packets you
|
||
would see more information.</para>
|
||
|
||
<para>Obviously this is unacceptable. The next section will
|
||
discuss securing the link between the two networks so that
|
||
all traffic is automatically encrypted.</para>
|
||
|
||
<itemizedlist>
|
||
<title>Summary:</title>
|
||
<listitem>
|
||
<para>Configure both kernels with <quote>device gif</quote>.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Edit <filename>/etc/rc.conf</filename> on gateway host
|
||
#1 and add the following lines (replacing IP addresses as
|
||
necessary).</para>
|
||
<programlisting>gif_interfaces="gif0"
|
||
gifconfig_gif0="A.B.C.D W.X.Y.Z"
|
||
ifconfig_gif0="inet 192.168.1.1 192.168.2.1 netmask 0xffffffff"
|
||
static_routes="vpn"
|
||
route_vpn="192.168.2.0 192.168.2.1 netmask 0xffffff00"
|
||
</programlisting>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Edit your firewall script
|
||
(<filename>/etc/rc.firewall</filename>, or similar) on both
|
||
hosts, and add</para>
|
||
|
||
<programlisting>ipfw add 1 allow ip from any to any via gif0</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Make similar changes to
|
||
<filename>/etc/rc.conf</filename> on gateway host #2,
|
||
reversing the order of IP addresses.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Step 2: Securing the link</title>
|
||
|
||
<para>To secure the link we will be using IPsec. IPsec provides
|
||
a mechanism for two hosts to agree on an encryption key, and to
|
||
then use this key in order to encrypt data between the two
|
||
hosts.</para>
|
||
|
||
<para>The are two areas of configuration to be considered here.</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>There must be a mechanism for two hosts to agree on the
|
||
encryption mechanism to use. Once two hosts have agreed on
|
||
this mechanism there is said to be a <quote>security association</quote>
|
||
between them.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>There must be a mechanism for specifying which traffic
|
||
should be encrypted. Obviously, you do not want to encrypt
|
||
all your outgoing traffic -- you only want to encrypt the
|
||
traffic that is part of the VPN. The rules that you put in
|
||
place to determine what traffic will be encrypted are called
|
||
<quote>security policies</quote>.</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>Security associations and security policies are both
|
||
maintained by the kernel, and can be modified by userland
|
||
programs. However, before you can do this you must configure the
|
||
kernel to support IPsec and the Encapsulated Security Payload
|
||
(ESP) protocol. This is done by configuring a kernel with:</para>
|
||
|
||
<indexterm>
|
||
<primary>kernel options</primary>
|
||
<secondary>IPSEC</secondary>
|
||
</indexterm>
|
||
|
||
<programlisting>options IPSEC
|
||
options IPSEC_ESP
|
||
</programlisting>
|
||
|
||
<para>and recompiling, reinstalling, and rebooting. As before
|
||
you will need to do this to the kernels on both of the gateway
|
||
hosts.</para>
|
||
|
||
<indexterm>
|
||
<primary>IKE</primary>
|
||
</indexterm>
|
||
|
||
<para>You have two choices when it comes to setting up security
|
||
associations. You can configure them by hand between two hosts,
|
||
which entails choosing the encryption algorithm, encryption keys,
|
||
and so forth, or you can use daemons that implement the Internet
|
||
Key Exchange protocol (IKE) to do this for you.</para>
|
||
|
||
<para>I recommend the latter. Apart from anything else, it is
|
||
easier to set up.</para>
|
||
|
||
<indexterm>
|
||
<primary>IPsec</primary>
|
||
<secondary>security policies</secondary>
|
||
</indexterm>
|
||
|
||
<indexterm>
|
||
<primary><command>setkey</command></primary>
|
||
</indexterm>
|
||
|
||
<para>Editing and displaying security policies is carried out
|
||
using &man.setkey.8;. By analogy, <command>setkey</command> is
|
||
to the kernel's security policy tables as &man.route.8; is to
|
||
the kernel's routing tables. <command>setkey</command> can
|
||
also display the current security associations, and to continue
|
||
the analogy further, is akin to <command>netstat -r</command>
|
||
in that respect.</para>
|
||
|
||
<para>There are a number of choices for daemons to manage
|
||
security associations with FreeBSD. This article will describe
|
||
how to use one of these, racoon — which is available from
|
||
<filename role="package">security/ipsec-tools</filename> in the &os; Ports
|
||
collection.</para>
|
||
|
||
<indexterm>
|
||
<primary>racoon</primary>
|
||
</indexterm>
|
||
|
||
<para>The <application>racoon</application> software must be run on both gateway hosts. On each host it
|
||
is configured with the IP address of the other end of the VPN,
|
||
and a secret key (which you choose, and must be the same on both
|
||
gateways).</para>
|
||
|
||
<para>The two daemons then contact one another, confirm that they
|
||
are who they say they are (by using the secret key that you
|
||
configured). The daemons then generate a new secret key, and use
|
||
this to encrypt the traffic over the VPN. They periodically
|
||
change this secret, so that even if an attacker were to crack one
|
||
of the keys (which is as theoretically close to unfeasible as it
|
||
gets) it will not do them much good -- by the time they have cracked
|
||
the key the two daemons have chosen another one.</para>
|
||
|
||
<para>The configuration file for racoon is stored in
|
||
<filename>${PREFIX}/etc/racoon</filename>. You should find a
|
||
configuration file there, which should not need to be changed
|
||
too much. The other component of racoon's configuration,
|
||
which you will need to change, is the <quote>pre-shared
|
||
key</quote>.</para>
|
||
|
||
<para>The default racoon configuration expects to find this in
|
||
the file <filename>${PREFIX}/etc/racoon/psk.txt</filename>. It is important to note
|
||
that the pre-shared key is <emphasis>not</emphasis> the key that will be used to
|
||
encrypt your traffic across the VPN link, it is simply a token
|
||
that allows the key management daemons to trust one another.</para>
|
||
|
||
<para><filename>psk.txt</filename> contains a line for each
|
||
remote site you are dealing with. In this example, where there
|
||
are two sites, each <filename>psk.txt</filename> file will contain one line (because
|
||
each end of the VPN is only dealing with one other end).</para>
|
||
|
||
<para>On gateway host #1 this line should look like this:</para>
|
||
|
||
<programlisting>W.X.Y.Z secret</programlisting>
|
||
|
||
<para>That is, the <emphasis>public</emphasis> IP address of the remote end,
|
||
whitespace, and a text string that provides the secret.
|
||
Obviously, you should not use <quote>secret</quote> as your key -- the normal
|
||
rules for choosing a password apply.</para>
|
||
|
||
<para>On gateway host #2 the line would look like this</para>
|
||
|
||
<programlisting>A.B.C.D secret</programlisting>
|
||
|
||
<para>That is, the public IP address of the remote end, and the
|
||
same secret key. <filename>psk.txt</filename> must be mode
|
||
<literal>0600</literal> (i.e., only read/write to
|
||
<username>root</username>) before racoon will run.</para>
|
||
|
||
<para>You must run racoon on both gateway machines. You will
|
||
also need to add some firewall rules to allow the IKE traffic,
|
||
which is carried over UDP to the ISAKMP (Internet Security Association
|
||
Key Management Protocol) port. Again, this should be fairly early in
|
||
your firewall ruleset.</para>
|
||
|
||
<programlisting>ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp
|
||
ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp
|
||
</programlisting>
|
||
|
||
<para>Once racoon is running you can try pinging one gateway host
|
||
from the other. The connection is still not encrypted, but
|
||
racoon will then set up the security associations between the two
|
||
hosts -- this might take a moment, and you may see this as a
|
||
short delay before the ping commands start responding.</para>
|
||
|
||
<para>Once the security association has been set up you can
|
||
view it using &man.setkey.8;. Run</para>
|
||
|
||
<programlisting>setkey -D</programlisting>
|
||
|
||
<para>on either host to view the security association information.</para>
|
||
|
||
<para>That's one half of the problem. The other half is setting
|
||
your security policies.</para>
|
||
|
||
<para>To create a sensible security policy, let's review what's
|
||
been set up so far. This discussions hold for both ends of the
|
||
link.</para>
|
||
|
||
<para>Each IP packet that you send out has a header that contains
|
||
data about the packet. The header includes the IP addresses of
|
||
both the source and destination. As we already know, private IP
|
||
addresses, such as the <hostid role="ipaddr">192.168.x.y</hostid>
|
||
range are not supposed to appear on the public Internet.
|
||
Instead, they must first be encapsulated inside another packet.
|
||
This packet must have the public source and destination IP
|
||
addresses substituted for the private addresses.</para>
|
||
|
||
<para>So if your outgoing packet started looking like this:</para>
|
||
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="security/ipsec-out-pkt" align="center">
|
||
</imageobject>
|
||
|
||
<textobject>
|
||
<literallayout class="monospaced">
|
||
.----------------------.
|
||
| Src: 192.168.1.1 |
|
||
| Dst: 192.168.2.1 |
|
||
| <other header info> |
|
||
+----------------------+
|
||
| <packet data> |
|
||
`----------------------'</literallayout>
|
||
</textobject>
|
||
</mediaobject>
|
||
|
||
<para>Then it will be encapsulated inside another packet, looking
|
||
something like this:</para>
|
||
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="security/ipsec-encap-pkt" align="center">
|
||
</imageobject>
|
||
|
||
<textobject>
|
||
<literallayout class="monospaced">
|
||
.--------------------------.
|
||
| Src: A.B.C.D |
|
||
| Dst: W.X.Y.Z |
|
||
| <other header info> |
|
||
+--------------------------+
|
||
| .----------------------. |
|
||
| | Src: 192.168.1.1 | |
|
||
| | Dst: 192.168.2.1 | |
|
||
| | <other header info> | |
|
||
| +----------------------+ |
|
||
| | <packet data> | |
|
||
| `----------------------' |
|
||
`--------------------------'</literallayout>
|
||
</textobject>
|
||
</mediaobject>
|
||
|
||
<para>This encapsulation is carried out by the
|
||
<devicename>gif</devicename> device. As
|
||
you can see, the packet now has real IP addresses on the outside,
|
||
and our original packet has been wrapped up as data inside the
|
||
packet that will be put out on the Internet.</para>
|
||
|
||
<para>Obviously, we want all traffic between the VPNs to be
|
||
encrypted. You might try putting this in to words, as:</para>
|
||
|
||
<para><quote>If a packet leaves from <hostid
|
||
role="ipaddr">A.B.C.D</hostid>, and it is destined for <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid>, then encrypt it, using the
|
||
necessary security associations.</quote></para>
|
||
|
||
<para><quote>If a packet arrives from <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid>, and it is destined for <hostid
|
||
role="ipaddr">A.B.C.D</hostid>, then decrypt it, using the
|
||
necessary security associations.</quote></para>
|
||
|
||
<para>That's close, but not quite right. If you did this, all
|
||
traffic to and from <hostid role="ipaddr">W.X.Y.Z</hostid>, even
|
||
traffic that was not part of the VPN, would be encrypted. That's
|
||
not quite what you want. The correct policy is as follows</para>
|
||
|
||
<para><quote>If a packet leaves from <hostid
|
||
role="ipaddr">A.B.C.D</hostid>, and that packet is encapsulating
|
||
another packet, and it is destined for <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid>, then encrypt it, using the
|
||
necessary security associations.</quote></para>
|
||
|
||
<para><quote>If a packet arrives from <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid>, and that packet is encapsulating
|
||
another packet, and it is destined for <hostid
|
||
role="ipaddr">A.B.C.D</hostid>, then decrypt it, using the
|
||
necessary security associations.</quote></para>
|
||
|
||
<para>A subtle change, but a necessary one.</para>
|
||
|
||
<para>Security policies are also set using &man.setkey.8;.
|
||
&man.setkey.8; features a configuration language for defining the
|
||
policy. You can either enter configuration instructions via
|
||
stdin, or you can use the <option>-f</option> option to specify a
|
||
filename that contains configuration instructions.</para>
|
||
|
||
<para>The configuration on gateway host #1 (which has the public
|
||
IP address <hostid role="ipaddr">A.B.C.D</hostid>) to force all
|
||
outbound traffic to <hostid role="ipaddr">W.X.Y.Z</hostid> to be
|
||
encrypted is:</para>
|
||
|
||
<programlisting>
|
||
spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;
|
||
</programlisting>
|
||
|
||
<para>Put these commands in a file (e.g.
|
||
<filename>/etc/ipsec.conf</filename>) and then run</para>
|
||
|
||
<screen>&prompt.root; <userinput>setkey -f /etc/ipsec.conf</userinput></screen>
|
||
|
||
<para><option>spdadd</option> tells &man.setkey.8; that we want
|
||
to add a rule to the secure policy database. The rest of this
|
||
line specifies which packets will match this policy. <hostid
|
||
role="ipaddr">A.B.C.D/32</hostid> and <hostid
|
||
role="ipaddr">W.X.Y.Z/32</hostid> are the IP addresses and
|
||
netmasks that identify the network or hosts that this policy will
|
||
apply to. In this case, we want it to apply to traffic between
|
||
these two hosts. <option>ipencap</option> tells the kernel that
|
||
this policy should only apply to packets that encapsulate other
|
||
packets. <option>-P out</option> says that this policy applies
|
||
to outgoing packets, and <option>ipsec</option> says that the
|
||
packet will be secured.</para>
|
||
|
||
<para>The second line specifies how this packet will be
|
||
encrypted. <option>esp</option> is the protocol that will be
|
||
used, while <option>tunnel</option> indicates that the packet
|
||
will be further encapsulated in an IPsec packet. The repeated
|
||
use of <hostid role="ipaddr">A.B.C.D</hostid> and <hostid
|
||
role="ipaddr">W.X.Y.Z</hostid> is used to select the security
|
||
association to use, and the final <option>require</option>
|
||
mandates that packets must be encrypted if they match this
|
||
rule.</para>
|
||
|
||
<para>This rule only matches outgoing packets. You will need a
|
||
similar rule to match incoming packets.</para>
|
||
|
||
<programlisting>spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;</programlisting>
|
||
|
||
<para>Note the <option>in</option> instead of
|
||
<option>out</option> in this case, and the necessary reversal of
|
||
the IP addresses.</para>
|
||
|
||
<para>The other gateway host (which has the public IP address
|
||
<hostid role="ipaddr">W.X.Y.Z</hostid>) will need similar rules.</para>
|
||
|
||
<programlisting>spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;
|
||
spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;</programlisting>
|
||
|
||
<para>Finally, you need to add firewall rules to allow ESP and
|
||
IPENCAP packets back and forth. These rules will need to be
|
||
added to both hosts.</para>
|
||
|
||
<programlisting>ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z
|
||
ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D
|
||
ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z
|
||
ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D
|
||
</programlisting>
|
||
|
||
<para>Because the rules are symmetric you can use the same rules
|
||
on each gateway host.</para>
|
||
|
||
<para>Outgoing packets will now look something like this:</para>
|
||
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="security/ipsec-crypt-pkt" align="center">
|
||
</imageobject>
|
||
|
||
<textobject>
|
||
<literallayout class="monospaced">
|
||
.------------------------------. --------------------------.
|
||
| Src: A.B.C.D | |
|
||
| Dst: W.X.Y.Z | |
|
||
| <other header info> | | Encrypted
|
||
+------------------------------+ | packet.
|
||
| .--------------------------. | -------------. | contents
|
||
| | Src: A.B.C.D | | | | are
|
||
| | Dst: W.X.Y.Z | | | | completely
|
||
| | <other header info> | | | |- secure
|
||
| +--------------------------+ | | Encap'd | from third
|
||
| | .----------------------. | | -. | packet | party
|
||
| | | Src: 192.168.1.1 | | | | Original |- with real | snooping
|
||
| | | Dst: 192.168.2.1 | | | | packet, | IP addr |
|
||
| | | <other header info> | | | |- private | |
|
||
| | +----------------------+ | | | IP addr | |
|
||
| | | <packet data> | | | | | |
|
||
| | `----------------------' | | -' | |
|
||
| `--------------------------' | -------------' |
|
||
`------------------------------' --------------------------'
|
||
</literallayout>
|
||
</textobject>
|
||
</mediaobject>
|
||
|
||
<para>When they are received by the far end of the VPN they will
|
||
first be decrypted (using the security associations that have
|
||
been negotiated by racoon). Then they will enter the
|
||
<devicename>gif</devicename> interface, which will unwrap
|
||
the second layer, until you are left with the innermost
|
||
packet, which can then travel in to the inner network.</para>
|
||
|
||
<para>You can check the security using the same &man.ping.8; test from
|
||
earlier. First, log in to the
|
||
<hostid role="ipaddr">A.B.C.D</hostid> gateway machine, and
|
||
run:</para>
|
||
|
||
<programlisting>tcpdump dst host 192.168.2.1</programlisting>
|
||
|
||
<para>In another log in session on the same host run</para>
|
||
|
||
<programlisting>ping 192.168.2.1</programlisting>
|
||
|
||
<para>This time you should see output like the following:</para>
|
||
|
||
<programlisting>XXX tcpdump output</programlisting>
|
||
|
||
<para>Now, as you can see, &man.tcpdump.1; shows the ESP packets. If
|
||
you try to examine them with the <option>-s</option> option you will see
|
||
(apparently) gibberish, because of the encryption.</para>
|
||
|
||
<para>Congratulations. You have just set up a VPN between two
|
||
remote sites.</para>
|
||
|
||
<itemizedlist>
|
||
<title>Summary</title>
|
||
<listitem>
|
||
<para>Configure both kernels with:</para>
|
||
|
||
<programlisting>options IPSEC
|
||
options IPSEC_ESP
|
||
</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Install <filename
|
||
role="package">security/ipsec-tools</filename>. Edit
|
||
<filename>${PREFIX}/etc/racoon/psk.txt</filename> on both
|
||
gateway hosts, adding an entry for the remote host's IP
|
||
address and a secret key that they both know. Make sure
|
||
this file is mode 0600.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Add the following lines to
|
||
<filename>/etc/rc.conf</filename> on each host:</para>
|
||
|
||
<programlisting>ipsec_enable="YES"
|
||
ipsec_file="/etc/ipsec.conf"
|
||
</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Create an <filename>/etc/ipsec.conf</filename> on each
|
||
host that contains the necessary spdadd lines. On gateway
|
||
host #1 this would be:</para>
|
||
|
||
<programlisting>
|
||
spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec
|
||
esp/tunnel/A.B.C.D-W.X.Y.Z/require;
|
||
spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec
|
||
esp/tunnel/W.X.Y.Z-A.B.C.D/require;
|
||
</programlisting>
|
||
|
||
<para>On gateway host #2 this would be:</para>
|
||
|
||
<programlisting>
|
||
spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec
|
||
esp/tunnel/W.X.Y.Z-A.B.C.D/require;
|
||
spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec
|
||
esp/tunnel/A.B.C.D-W.X.Y.Z/require;
|
||
</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Add firewall rules to allow IKE, ESP, and IPENCAP
|
||
traffic to both hosts:</para>
|
||
|
||
<programlisting>
|
||
ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp
|
||
ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp
|
||
ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z
|
||
ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D
|
||
ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z
|
||
ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D
|
||
</programlisting>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>The previous two steps should suffice to get the VPN up and
|
||
running. Machines on each network will be able to refer to one
|
||
another using IP addresses, and all traffic across the link will
|
||
be automatically and securely encrypted.</para>
|
||
</sect3>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="openssh">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Chern</firstname>
|
||
<surname>Lee</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
<!-- 21 April 2001 -->
|
||
</authorgroup>
|
||
</sect1info>
|
||
|
||
<title>OpenSSH</title>
|
||
<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
|
||
access remote machines securely. It can be used as a direct
|
||
replacement for <command>rlogin</command>,
|
||
<command>rsh</command>, <command>rcp</command>, and
|
||
<command>telnet</command>. Additionally, TCP/IP
|
||
connections can be tunneled/forwarded securely through SSH.
|
||
<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 based
|
||
upon SSH v1.2.12 with all the recent bug fixes and updates. It
|
||
is compatible with both SSH protocols 1 and 2.</para>
|
||
|
||
<sect2>
|
||
<title>Advantages of Using OpenSSH</title>
|
||
|
||
<para>Normally, when using &man.telnet.1; or &man.rlogin.1;,
|
||
data is sent over the network in an clear, un-encrypted form.
|
||
Network sniffers anywhere in between the client and server can
|
||
steal your user/password information or data transferred in
|
||
your session. <application>OpenSSH</application> offers a variety of authentication and
|
||
encryption methods to prevent this from happening.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Enabling sshd</title>
|
||
<indexterm>
|
||
<primary>OpenSSH</primary>
|
||
<secondary>enabling</secondary>
|
||
</indexterm>
|
||
|
||
<para>The
|
||
<application>sshd</application> is an option presented during
|
||
a <literal>Standard</literal> install of &os;. To see if
|
||
<application>sshd</application> is enabled, check the
|
||
<filename>rc.conf</filename> file for:</para>
|
||
<screen>sshd_enable="YES"</screen>
|
||
<para>This will load &man.sshd.8;, the daemon program for <application>OpenSSH</application>,
|
||
the next time your system initializes. Alternatively, it is
|
||
possible to use <filename>/etc/rc.d/sshd</filename> &man.rc.8;
|
||
script to start <application>OpenSSH</application>:</para>
|
||
|
||
<programlisting>/etc/rc.d/sshd start</programlisting>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>SSH Client</title>
|
||
<indexterm>
|
||
<primary>OpenSSH</primary>
|
||
<secondary>client</secondary>
|
||
</indexterm>
|
||
|
||
<para>The &man.ssh.1; utility works similarly to
|
||
&man.rlogin.1;.</para>
|
||
|
||
<screen>&prompt.root; <userinput>ssh <replaceable>user@example.com</replaceable></userinput>
|
||
Host key not found from the list of known hosts.
|
||
Are you sure you want to continue connecting (yes/no)? <userinput>yes</userinput>
|
||
Host 'example.com' added to the list of known hosts.
|
||
user@example.com's password: <userinput>*******</userinput></screen>
|
||
|
||
<para>The login will continue just as it would have if a session was
|
||
created using <command>rlogin</command> or
|
||
<command>telnet</command>. SSH utilizes a key fingerprint
|
||
system for verifying the authenticity of the server when the
|
||
client connects. The user is prompted to enter
|
||
<literal>yes</literal> only when
|
||
connecting for the first time. Future attempts to login are all
|
||
verified against the saved fingerprint key. The SSH client
|
||
will alert you if the saved fingerprint differs from the
|
||
received fingerprint on future login attempts. The fingerprints
|
||
are saved in <filename>~/.ssh/known_hosts</filename>, or
|
||
<filename>~/.ssh/known_hosts2</filename> for SSH v2
|
||
fingerprints.</para>
|
||
|
||
<para>By default, recent versions of the
|
||
<application>OpenSSH</application> servers only accept SSH v2
|
||
connections. The client will use version 2 if possible and
|
||
will fall back to version 1. The client can also be forced to
|
||
use one or the other by passing it the <option>-1</option> or
|
||
<option>-2</option> for version 1 or version 2, respectively.
|
||
The version 1 compatibility is maintained in the client for
|
||
backwards compatibility with older versions.</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Secure Copy</title>
|
||
<indexterm>
|
||
<primary>OpenSSH</primary>
|
||
<secondary>secure copy</secondary>
|
||
</indexterm>
|
||
<indexterm><primary><command>scp</command></primary></indexterm>
|
||
|
||
<para>The &man.scp.1; command works similarly to
|
||
&man.rcp.1;; it copies a file to or from a remote machine,
|
||
except in a secure fashion.</para>
|
||
|
||
<screen>&prompt.root; <userinput> scp <replaceable>user@example.com:/COPYRIGHT COPYRIGHT</replaceable></userinput>
|
||
user@example.com's password: <userinput>*******</userinput>
|
||
COPYRIGHT 100% |*****************************| 4735
|
||
00:00
|
||
&prompt.root;</screen>
|
||
<para>Since the fingerprint was already saved for this host in the
|
||
previous example, it is verified when using &man.scp.1;
|
||
here.</para>
|
||
|
||
<para>The arguments passed to &man.scp.1; are similar
|
||
to &man.cp.1;, with the file or files in the first
|
||
argument, and the destination in the second. Since the file is
|
||
fetched over the network, through SSH, one or more of the file
|
||
arguments takes on the form
|
||
<option>user@host:<path_to_remote_file></option>.</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Configuration</title>
|
||
<indexterm>
|
||
<primary>OpenSSH</primary>
|
||
<secondary>configuration</secondary>
|
||
</indexterm>
|
||
|
||
<para>The system-wide configuration files for both the
|
||
<application>OpenSSH</application> daemon and client reside
|
||
within the <filename>/etc/ssh</filename> directory.</para>
|
||
|
||
<para><filename>ssh_config</filename> configures the client
|
||
settings, while <filename>sshd_config</filename> configures the
|
||
daemon.</para>
|
||
|
||
<para>Additionally, the <option>sshd_program</option>
|
||
(<filename>/usr/sbin/sshd</filename> by default), and
|
||
<option>sshd_flags</option> <filename>rc.conf</filename>
|
||
options can provide more levels of configuration.</para>
|
||
</sect2>
|
||
|
||
<sect2 id="security-ssh-keygen">
|
||
<title>ssh-keygen</title>
|
||
|
||
<para>Instead of using passwords, &man.ssh-keygen.1; can
|
||
be used to generate DSA or RSA keys to authenticate a user:</para>
|
||
|
||
<screen>&prompt.user; <userinput>ssh-keygen -t <replaceable>dsa</replaceable></userinput>
|
||
Generating public/private dsa key pair.
|
||
Enter file in which to save the key (/home/user/.ssh/id_dsa):
|
||
Created directory '/home/user/.ssh'.
|
||
Enter passphrase (empty for no passphrase):
|
||
Enter same passphrase again:
|
||
Your identification has been saved in /home/user/.ssh/id_dsa.
|
||
Your public key has been saved in /home/user/.ssh/id_dsa.pub.
|
||
The key fingerprint is:
|
||
bb:48:db:f2:93:57:80:b6:aa:bc:f5:d5:ba:8f:79:17 user@host.example.com
|
||
</screen>
|
||
|
||
<para>&man.ssh-keygen.1; will create a public and private
|
||
key pair for use in authentication. The private key is stored in
|
||
<filename>~/.ssh/id_dsa</filename> or
|
||
<filename>~/.ssh/id_rsa</filename>, whereas the public key is
|
||
stored in <filename>~/.ssh/id_dsa.pub</filename> or
|
||
<filename>~/.ssh/id_rsa.pub</filename>, respectively for DSA and
|
||
RSA key types. The public key must be placed in
|
||
<filename>~/.ssh/authorized_keys</filename> of the remote
|
||
machine in order for the setup to work. Similarly, RSA version
|
||
1 public keys should be placed in
|
||
<filename>~/.ssh/authorized_keys</filename>.</para>
|
||
|
||
<para>This will allow connection to the remote machine based upon
|
||
SSH keys instead of passwords.</para>
|
||
|
||
<para>If a passphrase is used in &man.ssh-keygen.1;, the user
|
||
will be prompted for a password each time in order to use the
|
||
private key. &man.ssh-agent.1; can alleviate the strain of
|
||
repeatedly entering long passphrases, and is explored in the
|
||
<xref linkend="security-ssh-agent"> section below.</para>
|
||
|
||
<warning><para>The various options and files can be different
|
||
according to the <application>OpenSSH</application> version
|
||
you have on your system; to avoid problems you should consult
|
||
the &man.ssh-keygen.1; manual page.</para></warning>
|
||
</sect2>
|
||
|
||
<sect2 id="security-ssh-agent">
|
||
<title>ssh-agent and ssh-add</title>
|
||
|
||
<para>The &man.ssh-agent.1; and &man.ssh-add.1; utilities provide
|
||
methods for <application>SSH</application> keys to be loaded
|
||
into memory for use, without needing to type the passphrase
|
||
each time.</para>
|
||
|
||
<para>The &man.ssh-agent.1; utility will handle the authentication
|
||
using the private key(s) that are loaded into it.
|
||
&man.ssh-agent.1; should be used to launch another application.
|
||
At the most basic level, it could spawn a shell or at a more
|
||
advanced level, a window manager.</para>
|
||
|
||
<para>To use &man.ssh-agent.1; in a shell, first it will need to
|
||
be spawned with a shell as an argument. Secondly, the
|
||
identity needs to be added by running &man.ssh-add.1; and
|
||
providing it the passphrase for the private key. Once these
|
||
steps have been completed the user will be able to &man.ssh.1;
|
||
to any host that has the corresponding public key installed.
|
||
For example:</para>
|
||
|
||
<screen>&prompt.user; ssh-agent <replaceable>csh</replaceable>
|
||
&prompt.user; ssh-add
|
||
Enter passphrase for /home/user/.ssh/id_dsa:
|
||
Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa)
|
||
&prompt.user;</screen>
|
||
|
||
<para>To use &man.ssh-agent.1; in X11, a call to
|
||
&man.ssh-agent.1; will need to be placed in
|
||
<filename>~/.xinitrc</filename>. This will provide the
|
||
&man.ssh-agent.1; services to all programs launched in X11.
|
||
An example <filename>~/.xinitrc</filename> file might look
|
||
like this:</para>
|
||
|
||
<programlisting>exec ssh-agent <replaceable>startxfce4</replaceable></programlisting>
|
||
|
||
<para>This would launch &man.ssh-agent.1;, which would in turn
|
||
launch <application>XFCE</application>, every time X11 starts.
|
||
Then once that is done and X11 has been restarted so that the
|
||
changes can take effect, simply run &man.ssh-add.1; to load
|
||
all of your SSH keys.</para>
|
||
</sect2>
|
||
|
||
<sect2 id="security-ssh-tunneling">
|
||
<title>SSH 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 &man.ssh.1; 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>The <command>ssh</command> command is used with the
|
||
following options:</para>
|
||
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><option>-2</option></term>
|
||
|
||
<listitem>
|
||
<para>Forces <command>ssh</command> to use version 2 of
|
||
the protocol. (Do not use if you are working with older
|
||
SSH servers)</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term><option>-N</option></term>
|
||
|
||
<listitem>
|
||
<para>Indicates no command, or tunnel only. If omitted,
|
||
<command>ssh</command> would initiate 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>
|
||
fashion.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term><option>user@foo.example.com</option></term>
|
||
|
||
<listitem>
|
||
<para>The remote SSH server.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
|
||
|
||
<para>An SSH tunnel works by creating a listen socket on
|
||
<hostid>localhost</hostid> on the specified port.
|
||
It then forwards any connection received
|
||
on the local host/port via the SSH connection to the specified
|
||
remote host and port.</para>
|
||
|
||
<para>In the example, port <replaceable>5023</replaceable> on
|
||
<hostid>localhost</hostid> is being forwarded to port
|
||
<replaceable>23</replaceable> on <hostid>localhost</hostid>
|
||
of the remote machine. Since <replaceable>23</replaceable> is <application>telnet</application>,
|
||
this would create a secure <application>telnet</application> session through an SSH tunnel.</para>
|
||
|
||
<para>This can be used to wrap any number of insecure TCP
|
||
protocols such as SMTP, POP3, FTP, etc.</para>
|
||
|
||
<example>
|
||
<title>Using SSH to Create a Secure Tunnel for SMTP</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 an
|
||
&man.ssh-keygen.1; and additional user accounts to create a
|
||
more seamless/hassle-free SSH tunneling environment. Keys
|
||
can be used in place of typing a password, and the tunnels
|
||
can be run as a separate user.</para>
|
||
</example>
|
||
|
||
<sect3>
|
||
<title>Practical SSH Tunneling Examples</title>
|
||
|
||
<sect4>
|
||
<title>Secure Access of a POP3 Server</title>
|
||
|
||
<para>At work, there is an SSH server that accepts
|
||
connections from the outside. On the same office network
|
||
resides a mail server running a POP3 server. The network,
|
||
or network path between your home and office may or may not
|
||
be completely trustable. Because of this, you need to check
|
||
your e-mail in a secure manner. The solution is to create
|
||
an SSH connection to your office's SSH 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>When the tunnel is up and running, you can point your
|
||
mail client to send POP3 requests to <hostid>localhost</hostid>
|
||
port 2110. A connection here will be forwarded securely across
|
||
the tunnel to <hostid>mail.example.com</hostid>.</para>
|
||
</sect4>
|
||
|
||
<sect4>
|
||
<title>Bypassing a Draconian Firewall</title>
|
||
|
||
<para>Some network administrators impose extremely draconian
|
||
firewall rules, filtering not only incoming connections,
|
||
but outgoing connections. You may be only given access
|
||
to contact remote machines on ports 22 and 80 for SSH
|
||
and web surfing.</para>
|
||
|
||
<para>You may wish to access another (perhaps non-work
|
||
related) service, such as an Ogg Vorbis server to stream
|
||
music. If this Ogg Vorbis server is streaming on some other
|
||
port than 22 or 80, you will not be able to access it.</para>
|
||
|
||
<para>The solution is to create an SSH connection to a machine
|
||
outside of your network's firewall, and use it to tunnel to
|
||
the Ogg Vorbis server.</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>Your streaming client can now be pointed to
|
||
<hostid>localhost</hostid> port 8888, which will be
|
||
forwarded over to <hostid>music.example.com</hostid> port
|
||
8000, successfully evading the firewall.</para>
|
||
</sect4>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>The <varname>AllowUsers</varname> Users Option</title>
|
||
|
||
<para>It is often a good idea to limit which users can log in and
|
||
from where. The <literal>AllowUsers</literal> option is a good
|
||
way to accomplish this. For example, to only allow the
|
||
<username>root</username> user to log in from
|
||
<hostid role="ipaddr">192.168.1.32</hostid>, something like this
|
||
would be appropriate in the
|
||
<filename>/etc/ssh/sshd_config</filename> file:</para>
|
||
|
||
<programlisting>AllowUsers root@192.168.1.32</programlisting>
|
||
|
||
<para>To allow the user <username>admin</username> to log in from
|
||
anywhere, just list the username by itself:</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>
|
||
|
||
<note>
|
||
<para>It is important that you list each user that needs to
|
||
log in to this machine; otherwise they will be locked out.</para>
|
||
</note>
|
||
|
||
<para>After making changes to
|
||
<filename>/etc/ssh/sshd_config</filename> you must tell
|
||
&man.sshd.8; to reload its config files, by running:</para>
|
||
|
||
<screen>&prompt.root; <userinput>/etc/rc.d/sshd reload</userinput></screen>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Further Reading</title>
|
||
<para><ulink url="http://www.openssh.com/">OpenSSH</ulink></para>
|
||
<para>&man.ssh.1; &man.scp.1; &man.ssh-keygen.1;
|
||
&man.ssh-agent.1; &man.ssh-add.1; &man.ssh.config.5;</para>
|
||
<para>&man.sshd.8; &man.sftp-server.8; &man.sshd.config.5;</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="fs-acl">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
<surname>Rhodes</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
<indexterm>
|
||
<primary>ACL</primary>
|
||
</indexterm>
|
||
<title>File System Access Control Lists</title>
|
||
|
||
<para>In conjunction with file system enhancements like snapshots, FreeBSD 5.0
|
||
and later offers the security of File System Access Control Lists
|
||
(<acronym>ACL</acronym>s).</para>
|
||
|
||
<para>Access Control Lists extend the standard &unix;
|
||
permission model in a highly compatible (&posix;.1e) way. This feature
|
||
permits an administrator to make use of and take advantage of a
|
||
more sophisticated security model.</para>
|
||
|
||
<para>To enable <acronym>ACL</acronym> support for <acronym>UFS</acronym>
|
||
file systems, the following:</para>
|
||
|
||
<programlisting>options UFS_ACL</programlisting>
|
||
|
||
<para>must be compiled into the kernel. If this option has
|
||
not been compiled in, a warning message will be displayed
|
||
when attempting to mount a file system supporting <acronym>ACL</acronym>s.
|
||
This option is included in the <filename>GENERIC</filename> kernel.
|
||
<acronym>ACL</acronym>s rely on extended attributes being enabled on
|
||
the file system. Extended attributes are natively supported in the next generation
|
||
&unix; file system, <acronym>UFS2</acronym>.</para>
|
||
|
||
<note><para>A higher level of administrative overhead is required to
|
||
configure extended attributes on <acronym>UFS1</acronym> than on
|
||
<acronym>UFS2</acronym>. The performance of extended attributes
|
||
on <acronym>UFS2</acronym> is also substantially higher. As a
|
||
result, <acronym>UFS2</acronym> is generally recommended in preference
|
||
to <acronym>UFS1</acronym> for use with access control lists.</para></note>
|
||
|
||
<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 mount-time <acronym>ACL</acronym>s flag cannot be changed by a
|
||
remount (&man.mount.8; <option>-u</option>), only by means of a complete
|
||
&man.umount.8; and fresh &man.mount.8;. This means that
|
||
<acronym>ACL</acronym>s cannot be enabled on the root file system after boot.
|
||
It also means that you cannot change the disposition of a file system once
|
||
it is in use.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Setting the superblock flag will cause 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>s
|
||
enabled, which can result in <acronym>ACL</acronym>s being improperly enforced,
|
||
and hence security problems.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<note><para>We may change the <acronym>ACL</acronym>s behavior to allow the flag to
|
||
be enabled without a complete fresh &man.mount.8;, but we consider it desirable to
|
||
discourage accidental mounting without <acronym>ACL</acronym>s enabled, because you
|
||
can shoot your feet quite nastily if you enable <acronym>ACL</acronym>s, then disable
|
||
them, then re-enable them without flushing the extended attributes. In general, once
|
||
you have enabled <acronym>ACL</acronym>s 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 other unpredictable behavior.</para></note>
|
||
|
||
<para>File systems with <acronym>ACL</acronym>s enabled will show a <literal>+</literal>
|
||
(plus) sign in their permission settings when viewed. For example:</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>Here we see that the <filename>directory1</filename>,
|
||
<filename>directory2</filename>, and <filename>directory3</filename>
|
||
directories are all taking advantage of <acronym>ACL</acronym>s. The
|
||
<filename>public_html</filename> directory is not.</para>
|
||
|
||
<sect2>
|
||
<title>Making Use of <acronym>ACL</acronym>s</title>
|
||
|
||
<para>The file system <acronym>ACL</acronym>s can be viewed by the
|
||
&man.getfacl.1; utility. For instance, to view the
|
||
<acronym>ACL</acronym> settings on the <filename>test</filename>
|
||
file, one would use the command:</para>
|
||
|
||
<screen>&prompt.user; <userinput>getfacl <filename>test</filename></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,
|
||
invoke the &man.setfacl.1; utility. Observe:</para>
|
||
|
||
<screen>&prompt.user; <userinput>setfacl -k <filename>test</filename></userinput></screen>
|
||
|
||
<para>The <option>-k</option> flag will remove all of the
|
||
currently defined <acronym>ACL</acronym>s from a file or file
|
||
system. The more preferable method would be 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 -m u:trhodes:rwx,group:web:r--,o::--- <filename>test</filename></userinput></screen>
|
||
|
||
<para>In the aforementioned command, the <option>-m</option>
|
||
option was used to modify the default <acronym>ACL</acronym>
|
||
entries. Since there were no pre-defined entries, as they were
|
||
removed by the previous command, this will restore the default
|
||
options and assign the options listed. Take care to notice that
|
||
if you add a user or group which does not exist on the system,
|
||
an <errorname>Invalid argument</errorname> error will be printed
|
||
to <devicename>stdout</devicename>.</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="security-portaudit">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
<surname>Rhodes</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
|
||
<indexterm>
|
||
<primary>Portaudit</primary>
|
||
</indexterm>
|
||
<title>Monitoring Third Party Security Issues</title>
|
||
|
||
<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, and
|
||
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>Portaudit</application> exists solely for this
|
||
purpose.</para>
|
||
|
||
<para>The <filename role="port">ports-mgmt/portaudit</filename> port
|
||
polls a database, updated and maintained by the &os; Security
|
||
Team and ports developers, for known security issues.</para>
|
||
|
||
<para>To begin using <application>Portaudit</application>, one
|
||
must install it from the Ports Collection:</para>
|
||
|
||
<screen>&prompt.root; <userinput>cd /usr/ports/ports-mgmt/portaudit && make install clean</userinput></screen>
|
||
|
||
<para>During the install process, the configuration files for
|
||
&man.periodic.8; will be updated, permitting
|
||
<application>Portaudit</application> output in the daily security
|
||
runs. Ensure the daily security run emails, which are sent to
|
||
<username>root</username>'s email account, are being read. No
|
||
more configuration will be required here.</para>
|
||
|
||
<para>After installation, an administrator can update the database
|
||
and view known vulnerabilities in installed packages by invoking
|
||
the following command:</para>
|
||
|
||
<screen>&prompt.root; <userinput>portaudit -Fda</userinput></screen>
|
||
|
||
<note>
|
||
<para>The database will automatically be updated during the
|
||
&man.periodic.8; run; thus, the previous command is completely
|
||
optional. It is only required for the following
|
||
examples.</para>
|
||
</note>
|
||
|
||
<para>To audit the third party utilities installed as part of
|
||
the Ports Collection at anytime, an administrator need only run
|
||
the following command:</para>
|
||
|
||
<screen>&prompt.root; <userinput>portaudit -a</userinput></screen>
|
||
|
||
<para><application>Portaudit</application> will produce something
|
||
like this for vulnerable packages:</para>
|
||
|
||
<programlisting>Affected package: cups-base-1.1.22.0_1
|
||
Type of problem: cups-base -- HPGL buffer overflow vulnerability.
|
||
Reference: <http://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html>
|
||
|
||
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 <acronym>URL</acronym> shown,
|
||
an administrator may obtain more information about the
|
||
vulnerability in question. This will include versions affected,
|
||
by &os; Port version, along with other web sites which may contain
|
||
security advisories.</para>
|
||
|
||
<para>In short, <application>Portaudit</application> is a powerful
|
||
utility and extremely useful when coupled with the
|
||
<application>Portupgrade</application> port.</para>
|
||
</sect1>
|
||
|
||
<sect1 id="security-advisories">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
<surname>Rhodes</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
<indexterm>
|
||
<primary>FreeBSD Security Advisories</primary>
|
||
</indexterm>
|
||
<title>&os; Security Advisories</title>
|
||
|
||
<para>Like many production quality operating systems, &os; publishes
|
||
<quote>Security Advisories</quote>. These advisories are usually
|
||
mailed to the security lists and noted in the Errata only
|
||
after the appropriate releases have been patched. This section
|
||
will work to explain what an advisory is, how to understand it,
|
||
and what measures to take in order to patch a system.</para>
|
||
|
||
<sect2>
|
||
<title>What does an advisory look like?</title>
|
||
|
||
<para>The &os; security advisories look similar to the one below,
|
||
taken from the &a.security-notifications.name; mailing list.</para>
|
||
|
||
<programlisting>=============================================================================
|
||
&os;-SA-XX:XX.UTIL Security Advisory
|
||
The &os; Project
|
||
|
||
Topic: denial of service due to some problem<co id="co-topic">
|
||
|
||
Category: core<co id="co-category">
|
||
Module: sys<co id="co-module">
|
||
Announced: 2003-09-23<co id="co-announce">
|
||
Credits: Person@EMAIL-ADDRESS<co id="co-credit">
|
||
Affects: All releases of &os;<co id="co-affects">
|
||
&os; 4-STABLE prior to the correction date
|
||
Corrected: 2003-09-23 16:42:59 UTC (RELENG_4, 4.9-PRERELEASE)
|
||
2003-09-23 20:08:42 UTC (RELENG_5_1, 5.1-RELEASE-p6)
|
||
2003-09-23 20:07:06 UTC (RELENG_5_0, 5.0-RELEASE-p15)
|
||
2003-09-23 16:44:58 UTC (RELENG_4_8, 4.8-RELEASE-p8)
|
||
2003-09-23 16:47:34 UTC (RELENG_4_7, 4.7-RELEASE-p18)
|
||
2003-09-23 16:49:46 UTC (RELENG_4_6, 4.6-RELEASE-p21)
|
||
2003-09-23 16:51:24 UTC (RELENG_4_5, 4.5-RELEASE-p33)
|
||
2003-09-23 16:52:45 UTC (RELENG_4_4, 4.4-RELEASE-p43)
|
||
2003-09-23 16:54:39 UTC (RELENG_4_3, 4.3-RELEASE-p39)<co id="co-corrected">
|
||
<acronym>CVE</acronym> Name: CVE-XXXX-XXXX<co id="co-cve">
|
||
|
||
For general information regarding FreeBSD Security Advisories,
|
||
including descriptions of the fields above, security branches, and the
|
||
following sections, please visit
|
||
http://www.FreeBSD.org/security/.
|
||
|
||
I. Background<co id="co-backround">
|
||
|
||
|
||
II. Problem Description<co id="co-descript">
|
||
|
||
|
||
III. Impact<co id="co-impact">
|
||
|
||
|
||
IV. Workaround<co id="co-workaround">
|
||
|
||
|
||
V. Solution<co id="co-solution">
|
||
|
||
|
||
VI. Correction details<co id="co-details">
|
||
|
||
|
||
VII. References<co id="co-ref"></programlisting>
|
||
|
||
|
||
<calloutlist>
|
||
<callout arearefs="co-topic">
|
||
<para>The <literal>Topic</literal> field indicates exactly what the problem is.
|
||
It is basically an introduction to the current security
|
||
advisory and notes the utility with the
|
||
vulnerability.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-category">
|
||
<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
|
||
contributed to the &os; Project, such as
|
||
<application>sendmail</application>. Finally the <literal>ports</literal>
|
||
category indicates that the vulnerability affects add on
|
||
software available as part of the Ports Collection.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-module">
|
||
<para>The <literal>Module</literal> field refers to the component location, for
|
||
instance <literal>sys</literal>. In this example, we see that the module,
|
||
<literal>sys</literal>, is affected; therefore, this vulnerability
|
||
affects a component used within the kernel.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-announce">
|
||
<para>The <literal>Announced</literal> field reflects the date said security
|
||
advisory was published, or announced to the world. This
|
||
means that the security team has verified that the problem
|
||
does exist and that a patch has been committed to the &os;
|
||
source code repository.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-credit">
|
||
<para>The <literal>Credits</literal> field gives credit to the individual or
|
||
organization who noticed the vulnerability and reported
|
||
it.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-affects">
|
||
<para>The <literal>Affects</literal> field explains which releases of &os; are
|
||
affected by this vulnerability. For the kernel, a quick
|
||
look over the output from <command>ident</command> on the
|
||
affected files will help in determining the revision.
|
||
For ports, the version number is listed after the port name
|
||
in <filename>/var/db/pkg</filename>. If the system does not
|
||
sync with the &os; <acronym>CVS</acronym> repository and rebuild
|
||
daily, chances are that it is affected.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-corrected">
|
||
<para>The <literal>Corrected</literal> field indicates the date, time, time
|
||
offset, and release that was corrected.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-cve">
|
||
<para>Reserved for the identification information used to look up
|
||
vulnerabilities in the Common Vulnerabilities Database system.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-backround">
|
||
<para>The <literal>Background</literal> field gives information on exactly what
|
||
the affected utility is. Most of the time this is why
|
||
the utility exists in &os;, what it is used for, and a bit
|
||
of information on how the utility came to be.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-descript">
|
||
<para>The <literal>Problem Description</literal> field explains the security hole
|
||
in depth. This can include information on flawed code, or
|
||
even how the utility could be maliciously used to open
|
||
a security hole.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-impact">
|
||
<para>The <literal>Impact</literal> field describes what type of impact the
|
||
problem could have on a system. For example, this could
|
||
be anything from a denial of service attack, to extra
|
||
privileges available to users, or even giving the attacker
|
||
superuser access.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-workaround">
|
||
<para>The <literal>Workaround</literal> field offers a feasible workaround to
|
||
system administrators who may be incapable of upgrading
|
||
the system. This may be due to time constraints, network
|
||
availability, or a slew of other reasons. Regardless,
|
||
security should not be taken lightly, and an affected system
|
||
should either be patched or the security hole workaround
|
||
should be implemented.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-solution">
|
||
<para>The <literal>Solution</literal> field offers instructions on patching the
|
||
affected system. This is a step by step tested and verified
|
||
method for getting a system patched and working
|
||
securely.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-details">
|
||
<para>The <literal>Correction Details</literal> field displays the
|
||
<acronym>CVS</acronym> branch or release name with the
|
||
periods changed to underscore characters. It also shows
|
||
the revision number of the affected files within each
|
||
branch.</para>
|
||
</callout>
|
||
|
||
<callout arearefs="co-ref">
|
||
<para>The <literal>References</literal> field usually offers sources of other
|
||
information. This can include web <acronym>URL</acronym>s,
|
||
books, mailing lists, and newsgroups.</para>
|
||
</callout>
|
||
</calloutlist>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="security-accounting">
|
||
<sect1info>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
<surname>Rhodes</surname>
|
||
<contrib>Contributed by </contrib>
|
||
</author>
|
||
</authorgroup>
|
||
</sect1info>
|
||
<indexterm>
|
||
<primary>Process Accounting</primary>
|
||
</indexterm>
|
||
<title>Process Accounting</title>
|
||
|
||
<para>Process accounting is a security method in which an
|
||
administrator may keep track of system resources used,
|
||
their allocation among users, provide for system monitoring,
|
||
and minimally track a user's commands.</para>
|
||
|
||
<para>This indeed has its own 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 will walk an administrator through
|
||
the basics of process accounting.</para>
|
||
|
||
<sect2>
|
||
<title>Enable and Utilizing Process Accounting</title>
|
||
<para>Before making use of process accounting, it
|
||
must be enabled. To do this, execute the following
|
||
commands:</para>
|
||
|
||
<screen>&prompt.root; <userinput>touch <filename>/var/account/acct</filename></userinput>
|
||
|
||
&prompt.root; <userinput>accton <filename>/var/account/acct</filename></userinput>
|
||
|
||
&prompt.root; <userinput>echo 'accounting_enable="YES"' >> <filename>/etc/rc.conf</filename></userinput></screen>
|
||
|
||
<para>Once enabled, accounting will begin to track
|
||
<acronym>CPU</acronym> stats, commands, etc. All accounting
|
||
logs are in a non-human readable format and may be viewed
|
||
using the &man.sa.8; utility. If issued without any options,
|
||
<command>sa</command> will print information relating to the
|
||
number of per user calls, the total elapsed time in minutes,
|
||
total <acronym>CPU</acronym> and user time in minutes, average
|
||
number of I/O operations, etc.</para>
|
||
|
||
<para>To view information about commands being issued, one
|
||
would use the &man.lastcomm.1; utility. The
|
||
<command>lastcomm</command> may be used to print out commands
|
||
issued by users on specific &man.ttys.5;, for example:</para>
|
||
|
||
<screen>&prompt.root; <userinput>lastcomm ls
|
||
<username>trhodes</username> ttyp1</userinput></screen>
|
||
|
||
<para>Would print out all known usage of the <command>ls</command>
|
||
by <username>trhodes</username> on the ttyp1 terminal.</para>
|
||
|
||
<para>Many other useful options exist and are explained in the
|
||
&man.lastcomm.1;, &man.acct.5; and &man.sa.8; manual
|
||
pages.</para>
|
||
</sect2>
|
||
</sect1>
|
||
</chapter>
|
||
|
||
<!--
|
||
Local Variables:
|
||
coding: iso-8859-7
|
||
mode: sgml
|
||
sgml-declaration: "../chapter.decl"
|
||
sgml-indent-data: t
|
||
sgml-omittag: nil
|
||
sgml-always-quote-attributes: t
|
||
sgml-parent-document: ("../book.sgml" "part" "chapter")
|
||
End:
|
||
-->
|