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

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

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

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

Michael D. Bauer

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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






5.1. Stunnel and OpenSSL: Concepts










At its
simplest,
tunneling
is wrapping data or
packets of one protocol inside packets of a different protocol. When
used in security contexts, the term usually specifies the practice of
wrapping data or packets from an insecure protocol inside
encrypted
packets.[1] In this
section, we'll see how Stunnel,
an SSL-wrapper utility, can be used to wrap
transactions from various applications with
encrypted SSL tunnels.





[1] Even having said that, some network geeks
may find this use of the word tunneling
something of a stretch. An encrypted data stream is different from a
network protocol, and some people insist that tunneling is about
protocols, not cleartext versus ciphertext. I justify my usage based
on the end result, which is that one type of transaction gets
encapsulated into a different type.






Many network applications have the virtues of simplicity (with regard
to their use of network resources) and usefulness but lack security
features such as encryption and strong or even adequately protected
authentication. Web services were previously in this category, until
Netscape Communications invented the Secure Sockets Layer (SSL) in 1994.





SSL successfully grafted transparent but well-implemented encryption
functionality onto the HTTP experience without adding significant
complexity for end users. SSL also added the capability to
authenticate clients and servers alike with X.509 digital
certificates (though in the case of client authentication, this
feature is underutilized). Since Netscape wanted SSL to become an
Internet standard, they released enough of its details so that free
SSL libraries could be created, and indeed they were:
Eric A.
Young's
SSLeay was one of the
most successful, and its direct descendant OpenSSL is still being
maintained and developed today.





Note that the SSL protocol itself, while still widely used, is in
fact obsolete; its successor is the Transport Layer
Security protocol (TLS). Among other things, TLS allows you to
initiate secure (authenticated and/or encrypted) communications over
an existing application session, unlike with SSL, in which
authentication and encryption must be initiated at the outset of each
session. (This is why SSL-enabled services such as HTTPS
traditionally use a different port than their cleartext
counterpartse.g., TCP 443 for HTTPS and TCP 80 for
HTTPwhile TLS-enabled applications can use the same port for
all transactions regardless of whether encryption might be
initiated.) Besides its obvious relevance to web security, OpenSSL has led to the
creation of Stunnel, one of the most versatile and useful security
tools in the open source repertoire. Stunnel makes it possible to
encrypt connections involving virtually any
single-port TCP service via SSL, without
any modifications to the service itself. By
"single-port TCP service," I mean a
service that listens for connections on a single TCP port without
subsequently using additional ports for other functions.





HTTP, which listens and
conducts all of its business on a single port (usually TCP 80), is
such a service.
rsync,
Syslog-ng,
MySQL, and, yes, even
Telnet are, too: all
of these can be run in encrypted Stunnel SSL wrappers.





FTP,
which listens on TCP 21 for data connections but uses connections to
additional random ports for data transfers, is
not such a service. Anything that uses
Remote Procedure Call
(RPC) is also disqualified, because RPC uses the
Portmapper service to assign random
ports dynamically for RPC connections.
NFS and
NIS/NIS+ are common
RPC services; accordingly, neither will work with Stunnel.





Sun's newer
WebNFS service
doesn't require the Portmapper: it can use a single
TCP port (TCP 2049), making it a viable candidate for Stunnel use,
though I've never done this myself. See the
nfsd(8) and exports(5)
manpages for more information on using WebNFS with Linux.





Microsoft's SMB (CIFS) file- and
print-sharing protocol can function similarly when limited to TCP
port 139, albeit to varying degrees depending on your client OS, and
can thus be tunneled as well. See David Lechnyr's excellent
Samba Tutorial at http://hr.uoregon.edu/davidrl/sambal.
Section 4 of this tutorial, "Tunneling SMB over
SSH," explains how
Samba behaves the same
in either casealthough written with SSH in mind rather than
Stunnel.






5.1.1. OpenSSL










Stunnel relies on
OpenSSL
for all its cryptographic functions. Therefore, to use Stunnel, you
must first obtain and install OpenSSL on each host on which you
intend to use Stunnel. The current versions of most Linux
distributions now include binary packages for OpenSSL v0.9.7 or
later. Your distribution's base OpenSSL package will
probably suffice, but if you have trouble building Stunnel, try
installing the openssl-devel package (or your
distribution's equivalent).






OpenSSL has had a number of security vulnerabilities over the years,
including buffer overflows, timing attacks, ASN.1 parse errors, and
arcane but dangerous cryptographic flaws. As with OpenSSH, this is
much more a function of how hard it is to build a secure cryptosystem
implementation than of sloppiness on the part of the OpenSSL team.





You must be especially diligent in applying
security patches for OpenSSL whenever they're
released for your distribution. Any vulnerability in OpenSSL directly
affects everything on your system that uses ite.g., Apache,
OpenSSH, etc.













If you plan to use Stunnel with client-side certificates (i.e.,
certificate-based
authentication), you should obtain and install the latest OpenSSL
source code (available at http://www.openssl.org) rather than rely on
binary packages. To compile OpenSSL, uncompress and untar the source
tarball, change your working directory to the
source's root directory, and
run the config script. I recommend passing four
arguments to this script:





--prefix=






To specify the base installation directory (I use
/usr/local).






--openssldir=






To specify OpenSSL's home directory
(/usr/local/ssl is a popular choice).






shared






To tell OpenSSL to build and install its shared libraries, which are
used by both Stunnel and OpenSSH.






zlib-dynamic






To tell OpenSSL to use external libraries for the
zlib compression suite rather than redundantly
compile those functions into OpenSSL; zlib has
had major security vulnerabilities of its own over the years, so
you're well advised to maintain
zlib separately from OpenSSL (otherwise,
you'll need to recompile OpenSSL any time
there's a problem with zlib).
Alternatively, you can use the no-zlib flag to
forego zlib support altogether.







For example, using my recommended paths, the configuration command
would be as follows:





[root openssl-0.9.7d# ./config --prefix=/usr/local \
--openssldir=/usr/local/ssl shared zlib-dynamic For the remainder of this section, I'll refer to
OpenSSL's home as
/usr/local/ssl, though you may use whatever you
like.





The binary distributions of
OpenSSL in Red Hat and SUSE use
/usr/share/ssl/ for OpenSSL's
home directory, and Debian uses /usr/local/ssl/.
Since I use all three distributions and often confuse their OpenSSL
paths, I find it useful to create symbolic links on my non-Debian
systems from /usr/local/ssl to the actual
OpenSSL home. (That's one reason all OpenSSL
examples in this chapter use that path.) If config runs without returning errors, run
make, followed optionally
by make test and then make
install. You are now ready to create a local Certificate
Authority and start generating certificates.





5.1.1.1 What a Certificate Authority does and why you might need one






Stunnel uses two types of certificates:
server
certificates and
client
certificates. Any time Stunnel runs in
daemon mode (i.e.,
without the -c
flag), it must use a server certificate. Binary
distributions of Stunnel often include a pregenerated
stunnel.pem file, but this is for
testing purposes only!





You'll therefore need to generate at least one
server certificate, and if you wish to use client certificates,
you'll need to generate them, too. Either way,
you'll need a Certificate Authority (CA).





Perhaps you think of CAs strictly as commercial entities like
VeriSign and
Thawte, who create
and sign web-server certificates for a fee; indeed,
X.509 certificates from such
companies will work with OpenSSL and Stunnel. When users (or their
web browsers) need to verify the authenticity of a web
server's certificate, a "neutral
third party" such as a commercial CA is often
necessary.





However, it's far more likely that any certificate
verification you do with Stunnel will involve the
server-authenticating clients, not the other way around. This threat
model doesn't really need a third-party CA: in the
scenarios in which you'd most likely deploy Stunnel,
the server is at greater risk from unauthorized users than users are
from a phony server. To the extent that users do need to be concerned
with server authentication, a signature from your
organization's CA rather than from a neutral third
party is probably sufficient. These are some of the situations in
which it makes sense to run your own Certificate Authority.





If all this seems a bit confusing, Figure 5-1 shows
how clients, servers, and CAs in SSL relationships use
certificates.






Figure 5-1. How SSL clients, servers, and CAs use certificates






Figure 5-1 illustrates several important aspects of
the SSL (and of
public-key infrastructures in
general). First, you can see the distinction between
public
certificates and
private keys. In
public-key cryptography, each party has two keys: one public and one
private. SSL is based on public-key cryptography; in SSL
parlance, a signed public key is called a certificate, and a private
key is simply called a key. (If you're completely
new to public-key cryptography, see the "Public-Key
Cryptography" section in Chapter 4.) As Figure 5-1 shows, certificates are freely
sharedeven CA certificates. Keys, on the other hand, are not:
each key is held only by its owner and must be carefully protected
for its corresponding certificate to have meaning as a unique and
verifiable credential.





Another important point shown in Figure 5-1 is that
Certificate
Authorities do not directly participate in SSL
transactions. In day-to-day SSL activities, CAs do little
more than sign new certificates. So important is the trustworthiness
of these signatures, that the less contact your
CA has with other networked systems, the better.





It's not only possible but desirable for a CA to be
disconnected from the network altogether, accepting new signing
requests and exporting new signatures
manuallye.g., via floppy disks or
CD-ROMs. This minimizes the chance of your CA's
signing key being copied and misused: the moment a
CA's signing key is compromised, all certificates
signed by it become untrustworthy. For this reason, your main
Intranet file server is a terrible place to host a CA; any publicly
accessible server is absolutely out of the question.





When a host "verifies a
certificate," it does so using a locally stored copy
of the CA's "CA
certificate," which, like any certificate, is not
sensitive in and of itself. It is important, however, that any
certificate copied from one host to another is done over a secure
channel to prevent tampering. While certificate confidentiality
isn't important, certificate authenticity is of the
utmost importance, especially CA-certificate authenticity (since
it's used to determine the authenticity/validity of
other certificates).

5.1.1.2 How to become a small-time CA


Anybody can create their own Certificate Authority using OpenSSL on
their platform of choice: it compiles and runs not only on Linux and
other Unices, but also on Windows, VMS, and other operating systems.
All examples in this chapter will, of course, show OpenSSL running on
Linux. Also, given the importance and sensitivity of CA activities,
you should be logged in as root when performing
CA functions, and all CA files and directories should be owned by
root and set to mode 0600 or 0700.





First, install OpenSSL as described earlier under
"OpenSSL." In
OpenSSL's home directory (e.g.,
/usr/local/ssl), you'll find a
directory named misc/ that contains several
scripts. One of them, CA, can be used to
automatically set up a CA directory hierarchy complete with index
files and a CA certificate (and key). Depending on which version of
OpenSSL you have, CA may be provided as a shell
script (CA.sh), a Perl script
(CA.pl), or both.





Before you use it, however, you should tweak both it and the file
openssl.cnf (located
at the root of your OpenSSL home directory) to reflect your needs and
environment. First, in CA.sh, edit the variables
at the beginning of the script as you see fit. One noteworthy
variable is DAYS, which sets the default lifetime
of new certificates. I usually leave this to its default value of
-days 365, but your needs may differ.





One variable that I always change, however, is
CA_TOP, which sets the name of new CA directory
trees. By default, this is set to ./demoCA, but I
prefer to name mine ./localCA or simply
./CA. The leading ./ is handy:
it causes the script to create the new CA with your working directory
as its root. There's nothing to stop you from making
this an absolute path, though: you'll just need to
change the script if you want to run it again to create another CA;
otherwise, you'll copy over older CAs. (Multiple CAs
can be created on the same host, each with its own directory tree.)


On some systems (e.g., Fedora), the CA script is
hardcoded to ignore
openssl.cnf's value for
CA_TOP (forcing all new CA directories to be named
demoCA). To customize this setting, you may need
to manually edit your CA (or
CA.sh or CA.pl) script.













In openssl.cnf, there are still more variables
to set, which determine default settings for your certificates (Example 5-1). These are less importantsince most of
them may be changed when you actually create certificatesbut
one in particular, default_bits, is most easily
changed in openssl.cnf. This setting determines
the strength of your certificate's key, which is
used to sign other certificates, and in the case of SSL clients and
servers (but not of CAs), to negotiate SSL session
keys and
authenticate
SSL sessions.





By default, default_bits is set to
1024. Recent advances in the factoring of large
numbers have made 2048 a safer choice, though
computationally expensive (but only during certificate actions such
as generating, signing, and verifying signatures, and during SSL
session startup; it has no effect on the speed of actual data
transfers). The CA script reads
openssl.cnf, so if you want your CA certificate
to be stronger or weaker than 1024 bits, change
openssl.cnf before running CA.pl
or CA.sh (see Example 5-1).





Example 5-1. Changed lines from a sample openssl.cnf file






# these are the only important lines in this sample...
dir = ./CA
default_bits = 2048
# ...changing these saves typing when generating new certificates
countryName_default = ES
stateOrProvinceName_default = Andalucia
localityName_default = Sevilla
0.organizationName_default = Mesòn Milwaukee
organizationalUnitName_default =
commonName_default =
emailAddress_default =
# I don't use unstructuredName, so I comment it out:
# unstructuredName = An optional company name Now, change your working directory to the one in which you wish to
locate your CA hierarchy. Popular choices are
/root and the OpenSSL home directory itself,
which, again, is often /usr/local/ssl. From this
directory, run one of the following commands:





[root ssl]# /usr/local/ssl/misc/CA.pl -newca or:





[root ssl]# /usr/local/ssl/misc/CA.sh -newca In either case, replace /usr/local/ssl with your
OpenSSL home directory, if different.





The script will prompt you for an existing CA certificate to use
(Example 5-2); simply press Return to generate a new
one. You'll next be prompted for a passphrase for
your new CA key. This passphrase is extremely important: anyone who
knows this and has access to your CA key can sign certificates that
are verifiably valid for your domain. Choose as long and complex a
passphrase as is feasible for you.
Whitespace and punctuation marks are allowed.





Example 5-2. A CA.pl session






[root@tamarin ssl]# /usr/local/ssl/misc/CA.pl -newca
CA certificate filename (or enter to create)
Making CA certificate ...
Using configuration from /usr/local/ssl/openssl.cnf
Generating a 2048 bit RSA private key
........++++++
....++++++
writing new private key to './CA/private/cakey.pem'
Enter PEM pass phrase: *************
Verifying password - Enter PEM pass phrase: *************
-----
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) [ES]:
State or Province Name (full name) [Andalucia]:
Locality Name (eg, city) [Sevilla]:
Organization Name (eg, company) [Mesòn Milwaukee]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:ca.mesonmilwaukee.com
Email Address []:certmaestro@mesonmilwaukee.com By default, the CA.pl and
CA.sh scripts create a CA certificate called
cacert.pem in the root of the CA filesystem
hierarchy (e.g., /usr/local/ssl/CA/cacert.pem)
and a CA key called cakey.pem in the CA
filesystem's private/ directory
(e.g., /usr/local/ssl/CA/ private/cakey.pem).
The CA certificate must be copied to any host that will verify
certificates signed by your CA, but make sure the CA
key is never copied out of
private/ and is owned and readable only by
root.





Now you're ready to create and sign your own
certificates. Technically, any host running OpenSSL may generate
certificates, regardless of whether it's a CA. In
practice, however, the CA is the logical place to do this, since you
won't have to worry about the integrity of
certificates created elsewhere and transmitted over potentially
untrustworthy bandwidth. In other words, it's a lot
easier to feel good about signing a locally generated certificate
than about signing one that was emailed to the CA over the Internet.





For Stunnel use, you'll need certificates for each
host that will act as a server. If you plan to use
SSL client-certificate
authentication, you'll also need a certificate for
each client system. Stunnel supports two types of
client-certificate
authentication: you can restrict connections to clients
with certificates signed by a trusted CA, or you can allow only
certificates of which the server has a local copy. Either type of
authentication uses the same type of client certificate.





There's usually no difference between
server certificates and client
certificates. The exception is that server certificates sometimes may
need unencrypted (i.e., non-password-protected) keys because
they're used by automated processes, whereas
it's usually desirable to encrypt (password-protect)
client certificates. If a client certificate's key
is encrypted with a strong passphrase, the risk of that key being
copied or stolen is mitigated to a modest degree.





On the other hand, if you think the application
you'll be tunneling through Stunnel has adequate
authentication controls of its own, or if the client Stunnel process
will be used by an automated process, unencrypted client keys may be
justified. Just remember that any time you create client certificates
without passphrases, their usefulness in authenticating users is
practically nil. See the sidebar "The Danger of
Passphrase-Free Certificates" for some more thoughts
on this matter.





Before you start generating host certificates, copy the
openssl.cnf file from the OpenSSL home directory
to your CA directory and optionally edit it to reflect any
differences between your CA certificate and subsequent certificates
(e.g., you may have set default_bits to
2048 for your CA certificate but wish to use
1024-bit certificates for server or client certificates). At the very
least, I recommend you set the variable dir in
this copy of openssl.cnf to the absolute path of
the CA (e.g., /usr/local/ssl/ CA).

5.1.1.3 Creating CA-signed certificates


Now let's create a CA-signed certificate.
We'll start with a server certificate for an Stunnel
server named elfiero:





Change your working directory to the CA directory you created
earlier: e.g., /usr/ local/ssl/CA.





Create a new signing request (which is actually a certificate) and
key with this command:





bash-# openssl req -nodes -new -keyout elfiero_key.pem \
-out elfiero_req.pem -days 365 -config ./openssl.cnf You can include the flag -nodes if you want the
new certificate's key to be passphrase-free
(unencrypted). This will save you the trouble of having to type your
passphrase each time you start a program that uses the certificate,
but please see the sidebar, "The Danger of
Passphrase-Free Certificates" before using the
-nodes flag.





-keyout specifies what name you want the new key
to be, and -out specifies a name for the new
request/certificate. (The filenames passed to both
-keyout and
-out are both arbitrary: you can name them
whatever you like.) -days specifies how many days
the certificate will be valid, and it's optional
since it's also set in
openssl.cnf.





Another flag you can include is -newkey
rsa
:[bits], where
[bits] is the size of the new
certificate's RSA keye.g.,
1024 or 2048. As with the other
flags, this overrides the equivalent setting in
openssl.cnf.





After you enter this command, you will be prompted to enter new
values or accept default values for the
certificate's "Distinguished
Name" parameters (Country
Name, Locality
Name, Common Name, etc.), as in
Example 5-2. Note that each
certificate's Distinguished Name must be unique: if
you try to create a certificate with all the same DN parameters as
those of a previous certificate created by your CA, the action will
fail with an error. Only one DN field must differ from certificate to
certificate, however; the fields I tend to change are
Email Address and
Common Name.





Now, sign the certificate with this command:





bash-# openssl ca -config ./openssl.cnf -policy policy_anything \
-out elfiero_pubcert.pem -infiles elfiero_req.pem Again, you can call the output file specified by
-out anything you want. After entering this
command, you'll be prompted for the CA
key's passphrase, and after you enter this,
you'll be presented with the new
certificate's details and asked to verify your
intention to sign it.


If you skipped to this procedure from the
"START-TLS" section of Chapter 9 (i.e., you're creating
this certificate for an SMTP server, not an Stunnel server),
you're done: copy your new CA certificate, server
key, and signed server certificate over to your SMTP server, and
return to where you left off in Chapter 9.
Otherwise, proceed to Step 4.














The Danger of Passphrase-Free Certificates






To many security experts, using a
passphrase-free
key for practically any purpose is heresy: they argue that if a
process is sensitive enough to require public-key encryption, then
starting that process manually (i.e., in order to enter a passphrase
for that process's server certificate) is a
reasonable requirement.





For example, if you configure an Apache web server to use a
password-protected server certificate, you'll be
prompted for the key's passphrase when you start
Apache but won't have to enter it again until the
next time Apache restarts. Stunnel has no problem using
password-protected server certificates in this fashion.





I'm bowing to popular practice in describing use of
the -nodes flag here. However,
it's up to you to decide whether doing so yourself
in a given situation is worth the risk of someone compromising your
system and using that key for nefarious purposes.





One hint: the more things you use a given certificate for, the more
important that its key be encrypted/password-protected. If a
certificate is to be used only by a single application, containing
the risk associated with that certificate's having
no passphrase is much more manageable than if the risk were to impact
other processes that share the certificate.









Open the new key (e.g., elfiero_key.pem) in a
text editor, add a blank line to the bottom of the file, and save it.





This step isn't strictly necessary for recent
versions of Stunnel, which aren't as fussy about
certificate file formatting as older versions, but I still add the
blank line, since it's one less thing that can cause
problems (e.g., in case the local Stunnel build is older than I
thought).





Open the new signed certificate (e.g.,
elfiero_pubcert.pem) and
delete everything above but not including the
line -----BEGIN CERTIFICATE-----. Add a blank line
to the bottom of the file and save it. Again, the blank line may not
be necessary, but it doesn't hurt.





Concatenate the key and the signed certificate into a single file,
like this:





bash-# cat ./elfiero_key.pem ./elfiero_pubcert.pem > ./elfiero_cert.pem That's it! You now have a signed public certificate
you can share, named elfiero_pubcert.pem, and a
combined certificate and key named elfiero_cert.pem
that you can use as
elfiero's Stunnel server
certificate.





Note that the previous procedure assumes that your CA administrator
and your server administrator are one and the same person (which is
part of what I mean when I use the term "small-time
CA"). However, if one person is in charge of your
organization's CA and other people are in charge of
servers requiring CA-signed server certificates,
you'll want to have your server administrators
follow this procedure instead:





Create a new signing request and key (as I just described), but on
the server on which the certificate will be used rather than on the
CA itself.





Give a copy of the signing request, but not the
key, to your CA administrator; have her sign the request.





Format the key and signed certificate for Stunnel use and concatenate
them into a single file (as described in the previous
procedure).

5.1.1.4 Creating self-signed certificates






If you
have
no pressing or anticipated need for client-certificate
authentication, you may have opted to skip the whole Certificate
Authority experience. If so, there's nothing
stopping you from creating a self-signed
(non-CA-signed) certificate directly on your server system, using its
own local openssl command. This is quite simple:





Change your working directory to wherever you intend to install the
certificate, e.g., /etc/stunnel.





Create a single, combined key+certificate file with this command:





openssl req -x509 -newkey rsa:1024 -days 365 -keyout stunnel.pem -out stunnel.pem The only new flag, here, is -x509, which specifies
that the new certificate should be in X.509 format.
(It's required for self-signed certificates to work
with Stunnel, but not for CA-signed certificates.) Other than now
checking to ensure that your new certificate has appropriate
filesystem permissions (0600, or -rw-------),
you're done!





5.1.1.5 Client certificates






Creating certificates for Stunnel client
systems, which again is necessary only if you wish to use
client-certificate authentication on your Stunnel server, is no
different from creating server certificates. Note that unless you use
openssl's
-nodes flag when you create your client
certificate, you'll need to enter the correct
passphrase to start an Stunnel client daemon. But after the daemon
starts, any local user on your client machine can use the resulting
tunnel.[2] (Authentication required by the application being
tunneled, however, will still apply.) [2] iptables has a new match-module,
owner, that can help restrict local
users' access to local network daemons. If your
Stunnel client machine's kernel has iptables
support, you can add rules to its INPUT and OUTPUT chains that
restrict access to Stunnel's local listening port
(e.g., localhost:ssync) to a specific group ID
or user ID via the iptables options
--gid-owner and
--uid-owner, respectively. However, the
owner module, which provides these options, is
still experimental and must be enabled in a custom kernel build. This
module's name is ipt_owner.o,
"Owner Match Support
(EXPERIMENTAL)," in the kernel-configuration script.
Linux in a Nutshell (O'Reilly)
includes documentation on iptables in general and the
owner match module specifically.







From an Stunnel server's perspective, the client
certificate effectively authenticates the Stunnel client system and
not the tunneled application's users per se. This is
true of any server application that accepts connections involving
either certificates with unprotected keys or shared client
daemons.










5.1.2. Using Stunnel










Once you've created at least one server certificate,
you're ready to set up your Stunnel client(s) and
server. Chances are, your Linux distribution of choice includes a
binary package for Stunnel: recent releases of SUSE, Fedora, and Red
Hat Enterprise all include Stunnel Version 4. Debian 3.0 (Woody)
includes Stunnel Version 3.22.





Stunnel 3.22 is a stable version that's well
documented and well understood. On the other hand, Stunnel Version 4
is a major rewrite that, among other things, allows for easier
management of multiple tunnels, and it's the version
I'm covering here. If you run Debian, I think
it's worthwhile to download the latest Stunnel
source from http://www.stunnel.org and compile it
yourself.





Compiling Stunnel on any Linux distribution is quick and easy. First,
make sure you've already got your
distribution's packages for OpenSSL (probably called
openssl), OpenSSL development libraries
(openssl-devel or
libssl096-dev), and TCPwrapper development
libraries (the package libwrap0-dev on Debian;
the library is included as part of SUSE's and
Fedora's base installations).





Then, unpack Stunnel's source-code tarball and do a
quick ./configure && make &&
make install. If for some reason that
doesn't work, entering ./configure
--help
lists advanced precompile configuration options you
can pass to the configure scriptfor example,
--without-tcp-wrappers.





Once you've installed Stunnel, it's
time to create some certificates and start tunneling!






To see a list of the
configuration defaults with which your
Stunnel binary was built, run the command stunnel
-version
. This is particularly useful if you installed
Stunnel from a binary package and don't know how it
was built. Troubleshooting is easier when you know where Stunnel
expects things to be, etc.













5.1.2.1 A quick Stunnel example






And
now, at long last, we come to the heart of the matter: actually
running Stunnel and
tunneling things
over it. In pre-Version 4 releases, Stunnel accepted all its
configuration from the command linee.g., stunnel -c
-d rsync -r ssyncd -N ssync
.





In current versions (v4.0 and later), however, Stunnel uses a
configuration file, stunnel.conf. In fact, the
location of this configuration file is now the
only thing you can specify with
stunnel command flags. Its default path is
/usr/local/etc/stunnel/stunnel.conf if you built
Stunnel from source code with default build options, but if you
installed Stunnel from a binary package, the default path is more
likely to be /etc/stunnel/stunnel.conf.





Before I give a detailed explanation of
stunnel.conf parameters, I'm
going to walk through a brief sample scenario that demonstrates how
to build a quick and simple tunnel.





Suppose you have two servers, skillet and
elfiero. elfiero is an
rsync server, and you'd like to
tunnel rsync sessions
from skillet to elfiero.
The simplest usage of rsync, as shown in Chapter 11, is rsync hostname::,
which asks the host named hostname for a list of
its anonymous modules (shares). Your goal in this example will be to
run this command successfully over an Stunnel session.





First, you'll need to have
rsync installed, configured, and running in
daemon mode on elfiero. (Let's
assume you've followed my advice in Chapter 11 on how to do this, and that the
rsync daemon elfiero has
subsequently become so stable and secure as to be the envy of your
local rsync users' group.) Next, you'll need to make sure some things are in
place on elfiero for Stunnel to run as a
daemon. The most important of these is a
server certificate formatted as described earlier in
"Creating CA-signed certificates"
and "Creating self-signed
certificates." In this example, your certificate is
named elfiero_cert.pem and has been copied into
in the directory /etc/stunnel, and has
permissions 0600 (-rw-------).





You also need to make some minor changes to existing files on the
server: in /etc/services, you want an entry for
the port on which Stunnel will listen for remote connections, so that
log entries and command lines will be more human-readable. For our
example, this is the line to add to
/etc/services:





ssyncd 273/tcp # Secure Rsync daemon (The "real" rsync
daemon is listening on TCP 873, of course, so I like to
use an Stunnel port that's similar.) In addition, for purposes of our example, let's
assume that Stunnel on the server was compiled with
libwrap support; so add this line to
/etc/hosts.allow:





ssync: ALL On a Red Hat system, the hosts.allow entry would
instead look like this:





ssync: ALL: ALLOW Next, you need to tweak
elfiero's
/etc/stunnel/stunnel.conf file
(/usr/local/etc/stunnel/stunnel.conf if you
installed from source). Example 5-3 shows the
nondefault settings that tell Stunnel to use the server certificate
/etc/stunnel/elfiero_cert.pem, run in server
mode, use ssync as the TCPwrappers service name,
listen for encrypted packets on the ssyncd port
(TCP 273), and forward decrypted packets to the local
rsync port.





Example 5-3. stunnel.conf file on the Stunnel server






cert = /etc/stunnel/elfiero_cert.pem
client = no
[ssync]
accept = ssyncd
connect = rsync All that remains on elfiero is to start Stunnel
by simply typing the command stunnel. You
don't need to worry about starting it on the server
before starting it on the client or vice versa; the client
won't initiate a tunnel until you try to use it. If
elfiero's server certificate is
password-protected, you'll be prompted for it now
(keep this in mind if you set up an Stunnel startup script); once
you've entered that successfully, you should be up
and running!






What Are "TCPwrappers-Style Access Controls,"and How Do You Use Them?










I haven't yet covered
TCPwrappers, a
popular tool for adding logging and access controls to services run
from
inetd,
mainly because inetd is of limited usefulness on
a bastion host (see why I think so in the section
"Inetd/Xinetd Versus standalone
mode" in Chapter 11).





But TCPwrappers has an access-control
mechanism that restricts incoming connections based on remote
clients' IP addresses, which is a handy way to
augment application security. This mechanism, which I refer to in the
book as "TCPwrappers-style Access
Controls," is supported by Stunnel and many other
standalone services, via TCPwrappers'
libwrap.a library.





This mechanism uses two files, /etc/hosts.allow
and /etc/hosts.deny. Whenever a client host
attempts to connect to some service that is protected by this
mechanism, the remote host's IP address is first
compared to the contents of /etc/hosts.allow. If
it matches any line in hosts.allow, the
connection is passed. If the IP matches no line in
hosts.allow,
/etc/hosts.deny is then parsed, and if the IP
matches any line in it, the connection is dropped. If the client IP
matches neither file, the connection is passed.





Because this default allow behavior
isn't a very secure approach, most people implement
a default deny policy by keeping only one line
in /etc/hosts.deny:





ALL: ALL In this way, access is controlled by
/etc/hosts.allow: any combination of service and
IP address not listed in hosts.allow will be
denied.





In the simplest usage, each line in hosts.allow
(and hosts.deny) consists of two fields:





daemon1 [daemon2 etc.] : host1 [host2 etc.] where the first field is a space- or comma-delimited list of daemon
names to match and the second field (preceded by a colon) is a space-
or comma-delimited list of host IP addresses.





A daemon's name is usually determined from the value
of argv[0] passed from the daemon to the shell in
which it's invoked. In the case of Stunnel,
it's determined either from a
-N option passed to Stunnel
at startup or from a combination of the daemon being tunneled and the
name of the host to which Stunnel is connecting. The wildcard
ALL may also be used.





The host IP(s) may be expressed as an IP address or part of an IP
address: for example, 10.200. will match all IP
addresses in the range 10.200.0.1 through 10.200.254.254. The
wildcard ALL may also be used.





On Red Hat (and on any other system on which
tcpd has been compiled with PROCESS_
OPTIONS), a third field is also used, preceded by another
colon, whose most popular settings are ALLOW and
DENY. This obviates the need for a
/etc/hosts.deny file: a single
/etc/hosts.allow file may be used to include
both ALLOW and DENY rules.





See the manpages hosts_access(5) and
hosts_options(5) for more information.









You can now check for successful startup by issuing a quick
ps auxw and looking for an
stunnel process: stunnel
returns no output to the console whether it starts cleanly or not. It
will, however, send messages to your system's syslog
facility (by default, to the daemon facility),
including startup messages.





And now for the client system, skillet. For now,
you're not planning on using client certificates or
having the client verify server certificates, so
there's less to do here. Add one line to
/etc/services, and add one entry to
/etc/hosts.allow. (Even that last step is
necessary only if the Stunnel build on skillet
was compiled with libwrap support.) For consistency's sake, the line you add to
/etc/services should be identical to the one you
added to elfiero:





ssyncd 273/tcp # Secure rsync daemon Optimally, the Stunnel listener on skillet
should listen on TCP 873, the rsync
port, so that local rsync clients can use the
default port when connecting through the tunnel. If the client system
is already running an rsync daemon of its own on
TCP 873, however, you can add another line to
/etc/services to define an Stunnel forwarding
port:





zsync 272/tcp # Secure rsync forwarder


When choosing new port assignments for services such as
Stunnel, be sure not to choose any port already in use by another
active process. (This will save you the trouble of later trying to
figure out why your new service won't start!) The command to display all active TCP/IP listening sockets
is netstat --inet -aln. (Active local port numbers
are displayed after the colon in the "Local
Address" column.) This command is the same on all
flavors of Linux.













Assuming the Stunnel package on skillet was
compiled with libwrap, you also need to add this
line to /etc/hosts.allow:





ssync: ALL Or, for the Red Hat/PROCESS_OPTIONS version of
libwrap:





ssync: ALL: ALLOW Your stunnel.conf file on
skillet will need to look very similar to the
one on elfiero, except that client will need to
be set to yes, and the accept and connect values will be reversed. In
Example 5-4, we see the nondefault settings in
stunnel.conf necessary to tell Stunnel to start
in client mode, use the TCPwrappers service name
ssync, listen for local connections on the
rsync port (TCP 873), and forward them to the
ssyncd port (TCP 273) on
elfiero.





Example 5-4. stunnel.conf file on the Stunnel client


client = yes
[ssync]
accept = rsync
connect = elfiero.mesonmilwaukee.com:ssyncd (If all the unexplained stunnel.conf parameters
in Examples Example 5-3 and Example 5-4 are making you nervous, don't
worry: I'll cover them in my usual verbosity in the
next section.) The only other thing to do on skillet is to
start Stunnel, again by simply typing the command
stunnel.





Finally, you've arrived at the payoff:
it's time to invoke rsync.
Normally, the rsync command to poll
elfiero directly for its module list would look
like this:





[schmoe@skillet ~]$ rsync elfiero:: In fact, nothing you've done so far would prevent
this from working. (Preventing nontunneled access to the server is
beyond the scope of this quick example.) But you're cooler than that: you're
going to connect instead to a local process that
will transparently forward your command over an encrypted session to
elfiero, and
elfiero's reply will come back
over the same encrypted channel. Example 5-5 shows
what that exchange looks like (note that you don't
need to be root to run the client application).





Example 5-5. Running rsync over Stunnel






[schmoe@skillet ~]$ rsync localhost::
toolz Free software for organizing your skillet recipes
recipes Donuts, hush-puppies, tempura, corn dogs, pork rinds, etc.
images Pictures of Great American Fry-Cooks in frisky poses
medical Addresses of angioplasty providers It worked! Now your friends with accounts on
skillet can download
elfiero's unhealthy recipes
with cryptographic impunity, safe from the prying eyes of the
American Medical Association.





By the way, if you had to use a nonstandard
rsync port for the client's
Stunnel listener (e.g., by setting the connect
parameter in Example 5-5 to zsync
rather than to
rsync), Example 5-5
would instead look like Example 5-6.





Example 5-6. Running rsync over Stunnel (nonstandard rsync port)


[schmoe@skillet ~]$ rsync --port=272 localhost::
toolz Free software for organizing your skillet recipes
recipes Donuts, hush-puppies, tempura, corn dogs, pork rinds, etc.
images Pictures of Great American Fry-Cooks in frisky poses In other words, the rsync command can connect to
any port, but if it isn't 873, you must specify it
with the --port= option. Note that since
rsync doesn't parse
/etc/services, you must express it as a number,
not as a service name.





That's the quick start. Now, let's
roll up our sleeves, analyze what we just did, and discuss some
additional things you can do with Stunnel.





5.1.2.2 Explanation of the example stunnel.conf settings






As we just saw, Stunnel uses a single binary,
stunnel,
that can run in two different modes:
client mode
and server mode. They work similarly, except for one main difference:
in client mode, Stunnel listens for unencrypted connections (e.g.,
from the local machine) and forwards them through an encrypted SSL
connection to a remote machine running Stunnel; in server mode,
Stunnel listens for encrypted SSL connections (e.g., from remote
Stunnel processes) and then decrypts and forwards those sessions to a
local process. The stunnel.conf parameters used
in Examples Example 5-3 and Example 5-4 are therefore very similar;
it's mainly how
they're used that differs.





Here's a breakdown of the parameters specified in
the stunnel.conf files listed in Examples Example 5-3 and Example 5-4:





client = yes | no






The -c flag tells stunnel to
run in client mode and to interpret all other flags and options
(e.g., -d and
-r) accordingly. Without this flag, daemon mode is
assumed.






cert = /path/to/certificate.pem


This option specifies the full path to the host's
certificate. It's necessary in client mode only when
you need to present a client certificate to the servers you connect
to, but a certificate is always needed in server mode.






[servicename]


This label, contained in square brackets, signifies the beginning of
a service definition and is also used to specify a service name for
stunnel to pass in calls to
libwrap (i.e., to match against the entries in
/etc/hosts.allow). All parameters
above the first service definition are applied
globally. The service definition is assumed to end either with the
next service name or the end of the file (whichever comes first).






accept [hostIP:]daemonport


The
accept parameter specifies on which IP and
port stunnel should listen for connections.
hostIP, a local IP address or resolvable
hostname, specifies which local IP address (or resolvable hostname)
you want Stunnel to listen on (e.g., specify 127.0.0.1 to restrict
use of the tunnel to local users).
daemonport can be either a TCP port number
or a service name listed in /etc/services. In
server mode, this option is usually used to specify the port on which
to listen for encrypted (tunneled) packets. In client mode,
it's the port on which to listen for cleartext
(pretunneled) packets.






connect [remoteIP:]remoteport


The
connect parameter
specifies to which port Stunnel should forward packets. In server
mode, this means the local TCP port to which it should forward
packets received on the accept port (after
decryption). In client mode, this means the port on which the remote
system (specified by remoteIP, which may be either
an IP address or a hostname) is listening for tunnel connections.
Since remoteIP defaults to
localhost, you can omit that part on Stunnel
servers.







Note that you can use the accept parameter to
limit which interface Stunnel accepts connections on. What about the
"destination" service itself? If
you want some rsync connections to be encrypted,
you probably want all rsync
connections to be encrypted. Different network applications handle
this differently, but to tell rsync to only
accept connections from local processes (i.e.,
stunnel), invoke it like this:





rsync --daemon --address=127.0.0.1.





Not all services, of course, allow you to specify or restrict which
local IPs/interfaces they listen on. In cases where they
don't, you can use some combination of
hosts.allow, iptables, and certificate-based
authentication (see "Using Certificate
Authentication" later in this chapter).

5.1.2.3 Some security-enhancing global settings


The quick example shows enough to get a quick-and-dirty tunnel
running. But Stunnel v4 supports
additional global parameters in stunnel.conf
that significantly enhance its security, by allowing you to run
Stunnel in a chroot jail and by letting you run it with nonprivileged
user and group IDs. These parameters, which being global should
precede any service definitions, are as follows:





chroot = /path/to/chrootjail


Tells Stunnel to chroot itself to the specified path, after reading
its configuration file and host certificate (if applicable), but
before writing its PID, parsing hosts.allow and
hosts.deny, or acting on any
exec parameters (see Example 5-7). You must create/copy
etc/hosts.allow,
etc/hosts.deny, and any processes you wish to
have Stunnel execute into the chroot jail.






setuid = username or UID


Provides the name or numeric UID of a nonprivileged user account for
Stunnel to run as. Note that this may affect certain things Stunnel
needs to doe.g., writing its PID file or starting a daemon per
an exec parameter.






setgid = group name or GID


Provides the name or numeric GID of a nonprivileged group for Stunnel
to run as.







For other global and service-specific
stunnel.conf settings, see the
stunnel(8) manpage.





5.1.2.4 Another method for using Stunnel on the server


The skillet-elfiero example
showed Stunnel running in server mode on the server system. In
addition to client and daemon mode, Stunnel can run in
Inetd mode. In this mode, the
server's inetd process starts
the Stunnel daemon (and the service Stunnel is brokering) each time
it receives a connection on the specified port. Details on how to do
this are given by the Stunnel FAQ (http://www.stunnel.org/faq/)
and in the stunnel(8) manpage.





I'm not going to go into further depth on running
Stunnel in Inetd mode here: I've already stated my
bias against using Inetd on bastion hosts. Lest you think
it's just me, here's a quote from
the Stunnel FAQ:






Running in daemon (server) mode is much preferred to running in inetd
mode. Why?





SSL needs to be initialized for every connection.





No session cache is possible inetd mode requires forking, which causes additional overhead.
Daemon mode will not fork if you have stunnel compiled with threads.






Rather than starting Stunnel from inetd.conf, a
much better way to serve Inetd-style daemons, such as
in.telnetd and
in.talkd, over
Stunnel is to have the Stunnel daemon start them itself, using an
exec definition instead of
connect in your service definition (in
stunnel.conf).





For example, if you want to create your own
secure
Telnet service on elfiero, you can use the
method described in the previous section. However,
Linux's in.telnetd daemon
really isn't designed to run as a standalone daemon
except for debugging purposes. It would make better sense to use a
service definition like Example 5-7 on your Stunnel
server. (Suppose, for the purposes of this example, that on each host
you've already added an entry for the
telnets service to
/etc/hosts.allow.)

Example 5-7. Server-side service definition for telnets


[telnets]
accept = telnets
exec = /usr/sbin/in.telnetd
execargs = /usr/sbin/in.telnetd The exec parameter tells which local process to
invoke and forward decrypted packets to. Note that if
you're also using the chroot
global parameter to run Stunnel in a chroot jail, all paths specified
in exec statements will be interpreted relative to
the chroot path. The execargs
parameter specifies a space-delimited list of arguments to pass to
the exec process, starting with
$0 (the name of the process). Even if the process
doesn't need any other arguments, you must still use
execargs to tell Stunnel which process name to
provide as argument $0; exec
and execargs go together.






You may think that I skipped a step by not adding a line to
/etc/services for the service
telnets. But as it happens, the Internet
Assigned Names Authority (IANA) has already designated a number of
ports for SSL-wrapped services, with TCP 992 being assigned to
Telnets (Telnet secure). So this service
name/number combination is already in the
/etc/services file included on most Linux
systems.





A fast and easy way to see a list of IANA's
preassigned ports for SSL-enabled services is to run this command:





bash-# grep SSL /etc/services You can view the complete, current IANA port-number list online at
http://www.iana.org/assignments/port-numbers.













On the client system, you could simply run a
telnets-capable Telnet client (they do exist),
or you could run Stunnel in client mode, using a service definition
like that in Example 5-8.





Example 5-8. Client-side service definition for telnets






client = yes
[telnets]
accept = 127.0.0.1:telnets
connect = elfiero:telnets You could then use the stock Linux telnet
command to connect to the client host's local
Stunnel forwarder:





[schmoe@skillet ~]$ telnet localhost telnets Sparing you the familiar Telnet session that ensues, what happens in
this example is the following:





Your telnet process connects to the local
client-mode Stunnel process listening on port TCP 992.





This client-mode Stunnel process opens an encrypted SSL tunnel to the
server-mode Stunnel process listening on port TCP 992 on the remote
system.





Once the tunnel is established, the remote (server-mode) Stunnel
process starts its local in.telnetd daemon.





The client-mode Stunnel process then forwards your Telnet session
through the tunnel, and the remote Stunnel daemon hands the Telnet
packets to the in.telnetd service it started.





By the way, if I haven't made this clear yet, the
client and server
Stunnel processes may use
different listening ports. Again, just make sure that on
each host:





You choose a port not already being listened on by some other process.





The client daemon sends to the same port on
which the server daemon is listening (i.e., the
port specified in the client's
connect setting matches the
one in the server's
accept setting).






Two important notes particular to
telnets:
first,
in.telnetd
uses a number of different system and special files, so invoking it
with a chrooted stunnel process is a challenge;
you probably won't be able to use the
chroot parameter for tunneled Telnet setups.
Similarly, since in.telnetd must be invoked by
root (or by a process running as
root), you won't be able to use
the setuid or setgid parameters
either.






5.1.3. Using Certificate Authentication










Using Stunnel to forward
otherwise insecure applications
through encrypted SSL tunnels is good. Using Stunnel with some
measure of X.509 digital certificate
authentication is even better.





The bad news is that finding clear and consistent documentation on
this can be difficult. The good news is that
using it actually isn't that
difficult, and the following guidelines and procedures (combined with
the OpenSSL material we've already covered) should
get you started with a minimum of pain.





There are several ways you can use X.509 certificate authentication
with Stunnel, specified by
stunnel.conf's global parameter
verify. The verify parameter
can be set to one of three values:





1






If the remote host presents a certificate, check its signature.






2






Accept connections only from hosts that present certificates signed
by a trusted CA.






3






Accept connections only from hosts that present certificates that are
both cached locally (i.e., known) and signed by
a trusted CA.







There's actually a fourth verification level: none,
which is the default value. For no certificate verification,
uncomment or delete the verify line in
stunnel.conf altogether.





Since SSL uses a
peer-to-peer model for
authentication (i.e., as far as SSL is concerned, there are no
"client certificates" or
"server certificates";
they're all just
"certificates"), an Stunnel process
can require certificate authentication, whether it's
run in daemon mode or client mode. In other
words, not only can Stunnel servers require clients to present valid
certificates; clients can check server certificates, too!





In practical terms, this is probably most useful in HTTPS scenarios
(e.g., e-commerce: if you're about to send your
credit card information to a merchant's web server,
it's good to know they're not an
imposter). I can't think of nearly as many Stunnel
uses for clients authenticating servers. However, I have tested it,
and it works no differently from the other way around. Having said
all that, the following examples will both involve servers
authenticating clients.





5.1.3.1 X.509 authentication example


Let's return to our original
rsync-forwarding scenario with
skillet and elfiero. To
review, skillet is the client, and it has an
/etc/services entry mapping the service name
ssyncd to TCP port 273. So does the server
elfiero. Both hosts also have a line in
/etc/hosts.allow giving all hosts access to the
service ssync. Finally,
rsync is running on
elfiero, invoked by the command rsync
--daemon --address=127.0.0.1
.





In this example, you want elfiero to accept
connections only from clients with certificates signed by your
organization's Certificate Authority.
skillet, therefore, needs its own certificate:
you'll need to create one using the procedure from
"Creating CA-signed
certificates" earlier in this
chapter. We'll call the resulting files
skillet_cert.pem (the combined cert/key for
skillet to use) and
skillet_pubcert.pem
(skillet's signed certificate).
We'll also need a copy of the CA's
certificate, cacert.pem.





elfiero will need the copy of the CA certificate
(cacert.pem). skillet will
need skillet_ cert.pem, but it
won't need the CA certificate unless you later
decide to have skillet verify
elfiero's server certificate.





You can keep certificates wherever you like, remembering that they
should be set to mode 400, UID=root and
GID=root or wheel. So for
simplicity's sake on both systems,
let's keep our certificates in
/etc/stunnel. You can either
cat all your CA and client certificates into one
big file, specified by
stunnel.conf's
CAfile parameter (which is the method
we'll use in this example), or you can maintain
certificates as separate files in the directory specified by the
CApath parameter.





If you opt for the latter, however (using CApath),
note that unlike CAfile, which specifies an
absolute path, CApath will be interpreted relative
to Stunnel's chroot-jail path (unless
chroot isn't defined in your
stunnel.conf file). Also, Stunnel will expect
all certificate files in the CApath directory to
have hash values as their names. Since nobody likes to name files
this way, it's common practice to calculate the
file's hash and then create a symbolic link from
this hash value to the real name of the file.





OpenSSL has a very handy command,
c_rehash,
that does this automatically. Taking a directory as its argument,
c_rehash automatically creates such symbolic
links for all the certificates in the specified directorye.g.,
c_rehash /etc/stunnel.





Once you've got your CA certificates in place on
your server (and client certificates, if you're
using verification level 3) and your client certificate in place on
the client, you can reconfigure and restart the Stunnel daemons.





Example 5-9 shows the global options and service
definition from elfiero's
stunnel.conf file necessary to tell Stunnel to
listen on the ssyncd port (TCP 273), forward to
the local rsync port (TCP 873), require
certificates with trusted signatures, and to use the file
/etc/stunnel/cacert.pem to verify client
certificates.





Example 5-9. stunnel.conf file for a client-certificate-checking server






cert = /etc/stunnel/elfiero_cert
client = no
verify = 2
CAfile = /etc/stunnel/cacert.pem


When using any level of certificate authentication,
always specify where certificates are kept using
either the CApath parameter (to specify a
directory) or the CAfile
option (to specify a single file containing multiple CA
and client certificates). The vast majority of
certificate-authentication problems I've experienced
with Stunnel have been caused by it not knowing where to find host or
CA certificates.













On our Stunnel client system skillet,
we'll only need to add one global option,
cert (Example 5-10).





Example 5-10. Starting Stunnel in client mode, with client certificate






cert = /etc/stunnel/skillet_cert The command on skillet to run the
rsync query command is exactly the same as in
Example 5-5. Although in this case, the transaction
is more secure; the added security is completely
transparent to the end user.





To increase elfiero's level of
certificate verification from 2 to 3 (i.e., checking not only for
valid signatures but also for known certificates), there are only two
additional steps:





Concatenate a copy of skillet's
signed certificate (skillet_pubcert.pem, the
version without skillet's key)
to the end of /etc/stunnel/cacert.pem on
elfiero.





In elfiero's
stunnel.conf file, change the value of
verify from 2 to
3.





Although it may be tempting to copy
skillet_cert.pem (the combined key/certificate
file) over to elfiero in addition to or instead
of skillet_pubcert.pem, please resist this
temptation: unnecessarily copying of private keys is a very bad habit
to get into.

5.1.4. Using Stunnel on the Server and Other SSL Applicationson the Clients










Stunnel isn't the only
SSL
application capable of establishing a connection to an Stunnel
daemon. For example, it's possible to run Stunnel on
a POP3 server listening on the standard pop3s
port TCP 995 and forwarding to a local POP3 mail daemon.
It's then possible to connect to it using popular
SSL-capable POP3 clients, such as Outlook Express and Eudora on
client systems that don't run Stunnel.





This is actually simpler than the examples
I've presented in this chapter: the server side is
the same, and configuring the client side amounts to enabling SSL in
your client application. See the Stunnel FAQ (http://www.stunnel.org/faq/)
for more hints if you need them.






5.1.5. Other Tunneling Tools










In addition to Stunnel, other applications can be used to create
encrypted tunnels. These include Rick Kaseguma's program
SSLwrap, which is
similar to Stunnel (but which hasn't been updated
since 2000), and SSH, the subject of the previous chapter.
SSLwrap's home page is http://www.quiltaholic.com/rickk/sslwrap, and
Chapter 4 addresses tunneling as
well.

5.1.6. Resources










http://www.openssl.org


The official OpenSSL project home page

http://ospkibook.sourceforge.net/


The Open Source PKI Book

http://www.openca.org/openca/


The OpenCA project home page
Viega, John, Matt Messier, and Pravir Chandra. Network Security With OpenSSL. Sebastopol, CA: O'Reilly, 2002.






Comprehensive guide to using
OpenSSL






/ 94