Linux Server Security (2nd Edition( [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Linux Server Security (2nd Edition( [Electronic resources] - نسخه متنی

Michael D. Bauer

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







7.2. Setting Up the Server


If you're like me,
you're a lot less interested in LDAP theory than you
are in LDAP practice, so let's go ahead and install
OpenLDAPwe'll
go further with LDAP database design in a minute. (And if you
aren't like me, then good for you! But
you'll still have to skip ahead a few pages if you
want more LDAP theory right this instant.)

7.2.1. Getting and Installing OpenLDAP


Being such a useful and important thing,
OpenLDAP is included in most major
Linux distributions. Generally, it's split across
multiple packages: server daemons in one package, client
commands/programs in another, development libraries in still another,
etc. You're building an LDAP server, so naturally
you'll want to install your
distribution's OpenLDAP server package, plus
OpenLDAP runtime libraries if they aren't included
in the server package.

You might be tempted to forego installing the OpenLDAP client
commands on your server if there will be no local user accounts on it
(i.e., if you expect all LDAP transactions to occur over the network,
not locally). However, these client commands are useful for testing
and troubleshooting, so I strongly recommend you install them.

The specific packages that make up
OpenLDAP in Fedora and Red Hat are
openldap (OpenLDAP libraries, configuration
files, and documentation);
openldap-clients (OpenLDAP client software/commands);
openldap-servers (OpenLDAP server programs); and
openldap-devel (headers and libraries for developers).
Although these packages have a number of fairly mundane dependencies
(e.g., glibc), there are two required packages
in particular that you may not already have installed:
cyrus-sasl and
cyrus-sasl-md5, which help broker authentication
transactions with OpenLDAP.

In SUSE, OpenLDAP is provided via the RPMs
openldap2-client;
openldap2 (which includes both the OpenLDAP libraries
and server daemons); and
openldap2-devel. As with Red Hat, you'll
need to be sure to also install the package
cyrus-sasl, located in SUSE's
sec1 directory.

Note that earlier SUSE distributions (e.g., SUSE 8.0) provided
packages for OpenLDAP Versions 1.2 and 2.0. If your version gives you
the choice, be sure to install the newer 2.0 packages listed in the
previous paragraph (e.g., openldap2 rather than
openldap), unless you have a specific reason to
run OpenLDAP 1.2.

For Debian 3.0 ("Woody"), the
equivalent deb packages are
libldap2 (OpenLDAP libraries, in
Debian's libs directory);
slapd
(the OpenLDAP server package, found in the net
directory); and
ldap-utils (OpenLDAP client commands, also found
in the net directory). You'll
also need libsasl7, from the Debian
libs directory.

If your distribution of choice doesn't have binary
packages for OpenLDAP, if there's a specific feature
of the very latest version of OpenLDAP that is lacking in your
distribution's OpenLDAP packages, or if you need to
customize OpenLDAP at the binary level, you can always compile it
yourself from source you've downloaded from the
official OpenLDAP web site at http://www.openldap.org.


7.2.2. Configuring and Starting slapd


The main server daemon in
OpenLDAP
is called slapd, and configuring this program is
the first step in getting OpenLDAP working once it's
been installed. Its configuration is determined primarily by the file
/etc/openldap/slapd.conf.

The
"OpenLDAP 2.0
Administrator's Guide" at
http://www.openldap.org/doc/admin20/guidel
has an excellent "Quick-Start"
procedure for getting slapd up and running:
it's in Section 2, starting at Step 8. (That
document also explains directory services and LDAP concepts in more
depth than I do in this chapter.) Let's step through this procedure to make sure you
get off to a good start. The first thing to do is to edit
slapd.conf, an example of which is shown in Example 7-1. As you can see,
slapd.conf is a
typical Linux configuration file: each line in it consists of a
parameter name followed by a value.

Example 7-1. Customized part of /etc/openldap/slapd.conf


database ldbm
suffix "dc=wiremonkeys,dc=org"
rootdn "cn=ldapguy,dc=wiremonkeys,dc=org"
rootpw {SSHA}zRsCkoVvVDXObE3ewn19/Imf3yDoH9XC
directory /var/lib/ldap The first parameter shown in Example 7-1,
database, specifies what type of database backend
to use; usually the best choice here is ldbm,
which uses the fast dbm database format, but shell
(for custom shell-script backends) and passwd (to
use /etc/passwd as the backend) are also valid
choices. There may be multiple database definitions, each with its
own set of applicable parameters; all the lines in Example 7-1 comprise a single database definition.

The next parameter in Example 7-1 is
suffix, which determines what queries will match
this database definition. Here, the specified suffix is
"wiremonkeys.org," expressed in
LDAP-speak as a series of domain component
(dc) statements, which are parsed from left to
right. In other words, if an LDAP client queries our example server
in order to obtain information about the distinguished
name (dn)
cn=bubba,dc=wiremonkeys,dc=org, our server will
match that query against this database definition since the
dn ends with
dc=wiremonkeys,dc=org.

The next two entries in Example 7-1 have to do with
LDAP database administration:
rootdn and rootpw specify the
username and password (respectively) that must be supplied by remote
(or local) commands that perform administrative actions on the LDAP
database. Interestingly, these entries are used only for this
purpose: they won't show up in regular LDAP database
queries.

This addresses the paradox of how to authenticate the actions that
are required to populate the authentication (LDAP) database. Later,
after you've populated your LDAP database with
"real" entity records, you should
designate one of them as the administrative account, via
slapd.conf access-control lists (ACLs), and
delete the rootdn and rootpw
entries. During initial setup, however, rootdn and
rootpw will suffice.

Note that it's a very, very bad idea to store the
value of rootpw as cleartext. Instead, you should
use the slappasswd command to generate a password hash,
like in Example 7-2.

Example 7-2. The slappasswd command


[root@mydirserver openldap]# slappasswd -h {SSHA}
New password: *********
Re-enter new password: *********
{SSHA}16JhhIDajRc1cDwwa1t6o0ske8goj8Od As you can see, slappasswd prompts you for a
password and prints that password hashed with the algorithm you
specify with the -h flag. Be sure to enclose this
value in curly bracketssee the
slappasswd(8C) manpage for a list of valid
choices. You can copy and paste
slappasswd's output directly
into slapd.conf, which is precisely what I did
to create the rootpw value in Example 7-1.

Getting back to Example 7-1, the next parameter in
this directory definition is directory. Obviously
enough, this specifies which directory on the local filesystem your
LDAP directory should be created in. Since /var
is the customary place for
"growing" files like logs and
databases, Example 7-1 shows a value of
/var/lib/ldap. This directory must already exist,
and you should make sure it's owned by
OpenLDAP's user and group (usually
ldap and ldap). Its permissions
should be set to 0700
(-rwx------).

Technically, that's enough to get started: you can
try starting slapd via your
ldap startup script, most likely
/etc/init.d/ldap, though this may vary between
distributions. I encourage you to start adding practice entries to
your LDAP database using the ldapadd command;
the Quick Start procedure I mentioned earlier shows how.

Before you begin managing and querying your LDAP database from over
the network, however, you'll want to configure and
enable TLS encryption.

7.2.3. TLS for Secure LDAP Transactions


By default,
OpenLDAP transactions over networks are
conducted in clear text. If you're using OpenLDAP,
for example, as a centralized address-book server on a trusted
network, that's probably fine. But if
you're using it to authenticate users, regardless of
whether the networks involved are trusted or not, you really ought to
encrypt your
LDAP
communications so as to protect your users'
passwords from eavesdroppers.

The LDAP v3 protocol, support for which was introduced in OpenLDAP
2.0, provides encryption in the form of Transport Layer
Security (TLS), the same mechanism used by web browsers and Mail
Transport Agents (TLS is the successor to SSL, the Secure Sockets
Layer protocol). All you'll need to do to take
advantage of this is:

Create a server certificate on your LDAP server Add a couple more lines to
/etc/openldap/slapd.conf.

Optionally, tweak slapd's
startup flags.

To generate a server certificate, you'll need
OpenSSL. This should already be present on your system, since binary
OpenLDAP packages depend on OpenSSL.

What sort of certificate you should use on your LDAP server is
actually a fairly subtle question: will the server need a certificate
that has been signed by some other Certificate Authority such as
Thawte or Verisign (i.e., will your LDAP clients need to see an
externally verifiable certificate when connecting to your server)? Or
will your organization be its own Certificate Authority? If so, will
the LDAP server also act as your local CA, issuing and signing both
its own and other hosts' and users'
certificates?

If your needs match any of those scenarios, you'll
need to do a bit more work than I'm going to
describe here. Suffice it to say that the certificate
slapd uses can't have a
password associated with it (i.e., its key can't be
DES-encrypted), so a self-signed certificate, while technically a CA
certificate, shouldn't be used as an actual CA
certificate (i.e., for signing other certificates). If you want to
use your LDAP server as a
"real" CA, you'll
need to create two keys, a password-protected CA key and a
password-free slapd key. Vincent
Danen's article "Using
OpenLDAP for
Authentication" (http://www.mandrakesecure.net/en/docs/ldap-auth.php)
discusses this.

For many if not most readers, it will be enough to create a
self-generated TLS-only certificate to be used by
slapd and slapd alone. If
you don't care about being a Certificate Authority
and you don't need your LDAP clients to be able to
verify the server certificate's authenticity via
some third party, you can create your certificate like this (Example 7-3).

Example 7-3. Generating a self-signed X.509 certificate and key


bash-$> openssl req -new -x509 -nodes -out slapdcert.pem -keyout
slapdkey.pem -days 365

Using configuration from /usr/share/ssl/openssl.cnf
Generating a 1024 bit RSA private key
....++++++
.........++++++
writing new private key to 'slapdkey.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) [GB]:US
State or Province Name (full name) [Berkshire]:Minnesota
Locality Name (eg, city) [Newbury]:St. Paul
Organization Name (eg, company) [My Company Ltd]:wiremonkeys
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:cornelius.wiremonkeys.org
Email Address []:ldapguy@wiremonkeys.org Example 7-3 is deceptively long, but it involved
only one command: the openssl command at the
beginning. In this command line, I told OpenSSL to generate a new
X.509 certificate, without password protection, with the certificate
(public key) stored in the current working directory in the file
slapdcert.pem and with the private key stored in
the file slapdkey.pem, with a lifetime of 365
days.

After issuing this command, I was prompted for
"Distinguished Name" information
for the new certificate and key. For OpenLDAP's
purposes, the most important field here was the
"Common Name": this must be set to
your LDAP server's DNS namei.e., the name
your LDAP clients will see associated with this certificate. If your
LDAP server's IP address, for example,
reverse-resolves to
bonzo.lamemoviesfromthepast.com but its
server certificate shows a CN of
bonzo.lm.com, LDAP clients will reject the
certificate and will therefore be unable to negotiate TLS connections
(with very unpredictable results, depending on your client software).

Once you've got certificate and key files, copy them
into /etc/openldap (if you
weren't in that directory already when you created
them). Make sure that both of these are owned by
ldap (or whatever user your Linux distribution
runs slapd as; Red Hat and SUSE use
ldap) and that your key file has very strict
permissions, e.g., -r-------- (your certificate
file may, however, be world-readable, since this contains a public
key).


It is possible for you to specify the same filename after both the
-out and -keyout flags,
resulting in both certificate and private key being stored in a
single file. This is fine if you don't intend to
share the certificate. Keeping the two separate, however, allows you
to distribute the server certificate while still keeping the server
(private) key secret.

If your LDAP server uses a self-signed certificate
key, then on every client system that makes LDAPS queries
(LDAPS means LDAP secure)
against your server, you'll need to add this line to
/etc/openldap/ldap.conf:

TLS_REQCERT a llow You'll also need this line in your
server's
/etc/openldap/ldap.conf file if other processes
on the LDAP server make LDAPS queries (i.e., to ldaps://localhost).

If instead of using a self-signed certificate, you used a CA to sign
your LDAP server certificate, then you'll need to
copy your CA certificate to each client
system and specify the CA certificate's location in
the client's ldap.conf file,
via either the TLS_CACERT or TLS_CACERTDIR variable. See the
ldap.conf(5) manpage for more details.

Naturally, it isn't enough to have certificate/key
files in place; you need to tell slapd to use
them. As with most other slapd configurations,
this happens in /etc/openldap/slapd.conf.

Example 7-4 shows the sample
slapd.conf entries from Example 7-1, plus three additional ones:
TLSCipherSuite,
TLSCertificateFile, and
TLSCertificateKeyFile.

Example 7-4. Customized Part of /etc/openldap/slapd.conf


database ldbm
suffix "dc=wiremonkeys,dc=org"
rootdn "cn=ldapguy,dc=wiremonkeys,dc=org"
rootpw {SSHA}zRsCkoVvVDXObE3ewn19/Imf3yDoH9XC
directory /var/lib/ldap
TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCertificateFile /etc/openldap/slapdcert.pem
TLSCertificateKeyFile /etc/openldap/slapdkey.pem TLSCipherSuite specifies a list of
OpenSSL
ciphers from which slapd will choose when
negotiating TLS connections, in decreasing order of preference. To
see which ciphers are supported by your local OpenSSL installation,
issue this command:

openssl ciphers -v ALL In addition to those specific ciphers, you can use any of the
wildcards supported by OpenSSL, which allow you to specify multiple
ciphers with a single word. For example, in Example 7-4, TLSCipherSuite is set to
HIGH:MEDIUM:+SSLv2; as it happens,
HIGH, MEDIUM, and
+SSLv2 are all wildcards.

HIGH means "all ciphers using key
lengths greater than 128 bits";
MEDIUM is short for "all ciphers
using key lengths equal to 128
bits"' and
+SSLv2 means "all ciphers
specified in the SSL protocol, Version 2, regardless of key
strength." For a complete explanation of OpenSSL
ciphers, including all supported wildcards, see the
ciphers(1) manpage.

TLSCertificateFile and
TLSCertificateKeyFile are more obvious: they
specify the paths to your certificate file and private-key file,
respectively. If both certificate and key are combined in a single
file, you can specify the same path for both parameters (but see my
note on the previous page).

7.2.4. slapd Startup Options for TLS


Okay, we've done
everything we need (on the server end) for TLS encryption to work.
There's only one remaining detail to consider:
should we force the use of TLS for all LDAP requests from the
network, or keep it optional?

By default, slapd will listen for LDAP
connections on TCP port 389 and will accept either cleartext or
TLS-encrypted connections on that port. However, if
you're using LDAP for authentication, you probably
don't want to make TLS optional. A better approach
in that case is to have slapd listen for
cleartext-only LDAP connections on TCP 389 on the loopback interface
only, and have slapd listen for TLS-enabled
(ldaps) connections on TCP 636 (the standard
port for ldaps) for all other local addresses.

This behavior is controlled by
slapd's startup option
-h, which you can use to specify the various LDAP
URLs slapd will respond to. For example:

slapd -h ldap://127.0.0.1/ ldaps:/// tells slapd to listen on the loopback address
(127.0.0.1) for ldap connections to the default
ldap port (TCP 389), and to listen on all local
addresses for ldaps connections to the default
ldaps port (TCP 636).

If you run Red Hat 7.3 or later, this is actually the default
behavior: /etc/init.d/ldap checks
/etc/openldap/slapd.conf for TLS configuration
information, and if it finds it, sets the -h
option exactly like the one in the previous
paragraph's example. If you run SUSE 8.1 or later,
you can achieve the same thing by editing
/etc/sysconfig/openldap such that the value for
OPENLDAP_START_LDAPS is yes,
and then editing /etc/init.d/openldap to set the
value for SLAPD_URLS to
ldap://127.0.0.1 (this variable is defined early
in the script, with a default value of ldap:///).

Other Linux distributions may have different ways of passing startup
options like -h to slapd, but
hopefully by now you get the idea and can figure out how to make
slapd's listening-ports work
the way you want them to.


7.2.5. Testing


So, does our TLS-enabled LDAP server actually work?
A quick local test will tell us. First, start LDAP:

/etc/init.d/ldap start Next, use the ldapsearch command to do a simple
query via loopback:

ldapsearch -x -H ldaps://localhost/ -b 'dc=wiremonkeys,dc=org' '(objectclass=*)' (Naturally, your own LDAP server will have a different base DN from
dc=wiremonkeys,dc=org.) If you prefer, you can run
that last command from a remote host, specifying the LDAP
server's name or IP address in place of
localhost in the -h option.

If the LDAP server returns a dump of the LDAP database (which is
actually empty at this point), followed by the string
result: 0 Success, then your test has succeeded!
Depending on which version of OpenLDAP your server is running, a
nonzero result may also mean success, if you haven't
yet added your organization entry (see "Creating
Your First LDAP Record" later in this chapter).


7.2.6. LDAP Schema


You're almost ready to start populating the LDAP
database. On the one hand, tools such as
gq and
ldapbrowser can greatly reduce the ugliness and toil
of LDAP data entry and administration. But to get to the point where
these tools can be used, you first have to settle on a combination of
LDAP
schemas, and this is where things can get unpleasant.

For purposes of this discussion, there are two types of
LDAP
data that matter: attributes and
object classes. Attributes are the things that
make up a record: a user's phone number, email
address, nicknames, etc. are all attributes. You can use as many or
as few attributes in your LDAP database as you like; you can even
invent your own. But for a record to contain a given attribute, that
record must be associated with the proper object class.

An object class describes the type of record you're
trying to build: it defines which attributes are mandatory for each
record and which attributes are optional.
"Oh," you might think,
"that's easy, then: I just need to
choose an object class that provides the group of attributes I want
to store for my users and associate each user record with that object
class!" If you thought that, you'd only be partly right. In
practice, you'll probably want to use attributes
from a variety of object classes. "Well,
fine," you think,
"I'll just specify multiple object
classes in each user record, and get my full complement of attributes
à la carte. Whatever." Right again, but again there's more to it than that:
chances are, the object classes that provide the attributes you need
are spread across a number of schema files
(these are text files, each containing a list of attributes and the
object classes that reference them). So even before you can begin
composing your user records, each containing a stack of object class
statements and a bigger stack of attribute settings,
you'll need to first make sure
/etc/openldap/slapd.conf contains
include statements for all the schema files you
need (usually present in /etc/openldap/schema).

For example, suppose that since we're going to use
our sample LDAP server for authentication, we want to make sure that
no matter what, we're able to specify the attributes
userid and userPassword. Doing
a quick grep of the files in
/etc/openldap/schema shows that
uid appears in the file
inetorgperson.schema in the MAY list (of allowed
attributes) for the object class inetOrgPerson.

This has two ramifications. First,
/etc/openldap/slapd.conf will need to contain
this line:

include /etc/openldap/schema/inetorgperson.schema Second, whenever I create a user record, I'll need
to make sure that there is an objectclass:
inetOrgPerson
statement present.


7.2.7. Creating Your First LDAP Record


So, how do you create LDAP records? Ideally, via the GUI of
your choice. (I've mentioned
gq, which is a standard package in many distros;
another excellent tool is ldapbrowser, available
at http://www.iit.edu/~gawojar/ldap/) Initially, however, you'll probably want to add at
least your organizational entry manually, by creating an
LDIF file and writing it to the database
via the ldapadd command.

An LDIF file is a text file containing a list of
attribute/object-class declarations, one per line: Example 7-5 shows a simple one.

Example 7-5. A simple LDIF file


dn: dc=wiremonkeys,dc=org
objectclass: top
objectclass: dcObject
objectclass: organization
dc: wiremonkeys
o: Wiremonkeys of St. Paul In Example 7-5, we're defining the
organization wiremonkeys.org: we specify its
Distinguished Name, we associate it with the object classes
top, dcObject, and
organization, and finally we specify the
organization's unique domain component
(wiremonkeys) and name (Wiremonkeys of
St. Paul
).

To write this record to the database, we issue this command:

ldapadd -x -H ldaps://localhost/ -D "cn=ldapguy,dc=wiremonkeys,dc=org" -W \
-f wiremonkeys_init.ldif
As with most openldap commands,
-x specifies simple password authentication,
-H specifies the LDAP server's
URL, -D specifies the DN of the administrator
account, and -W causes the
administrator's password to be prompted for. The
-f option specifies the path to our LDIF file.

Confused yet? I've packed a lot of information into
this section, but our LDAP server is very nearly done.


/ 94