252 lines
8.4 KiB
Text
252 lines
8.4 KiB
Text
|
Desc: Configuring SSL
|
||
|
File: ssl.txt
|
||
|
Date: 19 February 2004
|
||
|
Auth: Russell Kroll <rkroll@exploits.org>
|
||
|
|
||
|
SSL is now available as a development option. It encrypts sessions with
|
||
|
upsd and can also be used to authenticate servers. This means that
|
||
|
stealing port 3493 from upsd will no longer net you interesting
|
||
|
passwords.
|
||
|
|
||
|
Several things must happen before this will work, however:
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
1. Install OpenSSL.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
2. Recompile NUT from source, starting with 'configure --with-ssl'.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
3. Install everything as usual.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
4. Create a certificate and key for upsd.
|
||
|
|
||
|
openssl (the program) should be in your PATH, unless you installed
|
||
|
it from source yourself, in which case it may be in
|
||
|
/usr/local/ssl/bin.
|
||
|
|
||
|
openssl req -new -x509 -nodes -out upsd.crt -keyout upsd.key
|
||
|
|
||
|
You can also put a "-days nnn" in there to set the expiration. If
|
||
|
you skip this, it may default to 30 days. This is probably not what
|
||
|
you want.
|
||
|
|
||
|
It will ask several questions. What you put in there doesn't matter
|
||
|
a whole lot, since nobody is going to see it for now. Future
|
||
|
versions of the clients may present data from it, so you might use
|
||
|
this opportunity to identify each server somehow.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
5. Figure out the hash for the key.
|
||
|
|
||
|
openssl x509 -hash -noout -in upsd.crt
|
||
|
|
||
|
You'll get back a single line with 8 hex characters. This is the
|
||
|
hash of the certificate, which is used for naming the client-side
|
||
|
certificate. For the purposes of this example the hash is
|
||
|
0123abcd.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
6. Install the client-side certificate.
|
||
|
|
||
|
mkdir <certpath>
|
||
|
chmod 0755 <certpath>
|
||
|
cp upsd.crt <certpath>/<hash>.0
|
||
|
|
||
|
Example:
|
||
|
|
||
|
mkdir /usr/local/ups/etc/certs
|
||
|
chmod 0755 /usr/local/ups/etc/certs
|
||
|
cp upsd.crt /usr/local/ups/etc/certs/0123abcd.0
|
||
|
|
||
|
If you already have a file with that name in there, increment the
|
||
|
0 until you get a unique filename that works.
|
||
|
|
||
|
If you have multiple client systems (like upsmon slaves), be sure
|
||
|
to install this file on them as well.
|
||
|
|
||
|
I recommend making a directory under your existing confpath to
|
||
|
keep everything in the same place. Remember the path you created,
|
||
|
since you will need to put it in upsmon.conf later.
|
||
|
|
||
|
It must not be writable by unprivileged users, since someone could
|
||
|
insert a new client certificate and fool upsmon into trusting a
|
||
|
fake upsd.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
7. Create the combined file for upsd.
|
||
|
|
||
|
cat upsd.crt upsd.key > upsd.pem
|
||
|
|
||
|
chown root:nut upsd.pem
|
||
|
chmod 0640 upsd.pem
|
||
|
|
||
|
This file must be kept secure, since anyone possessing it could
|
||
|
pretend to be upsd and harvest authentication data if they get a
|
||
|
hold of port 3493.
|
||
|
|
||
|
Having it be owned by root and readable by group nut allows upsd
|
||
|
to read the file without being able to change the contents. This
|
||
|
is done to minimize the impact if someone should break into upsd.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
8. Install the server-side certificate.
|
||
|
|
||
|
mv upsd.pem <upsd certfile path>
|
||
|
|
||
|
Example:
|
||
|
|
||
|
mv upsd.pem /usr/local/ups/etc/upsd.pem
|
||
|
|
||
|
After that, edit your upsd.conf and tell it where to find it:
|
||
|
|
||
|
CERTFILE /usr/local/ups/etc/upsd.pem
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
9. Clean up the temporary files.
|
||
|
|
||
|
rm -f upsd.crt upsd.key
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
10. Restart upsd.
|
||
|
|
||
|
It should come back up without any complaints. If it says something
|
||
|
about keys or certificates, then you probably missed a step.
|
||
|
|
||
|
If you run upsd as a separate user id (like nutsrv), make sure that
|
||
|
user can read the upsd.pem file.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
11. Point upsmon at the certificates.
|
||
|
|
||
|
Edit your upsmon.conf, and tell it where the CERTPATH is:
|
||
|
|
||
|
CERTPATH <path>
|
||
|
|
||
|
CERTPATH /usr/local/ups/etc/certs
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
12. Recommended: make upsmon verify all connections with certificates.
|
||
|
|
||
|
Put this in upsmon.conf:
|
||
|
|
||
|
CERTVERIFY 1
|
||
|
|
||
|
Without this, there is no guarantee that the upsd is the right host.
|
||
|
Enabling this greatly reduces the risk of man in the middle attacks.
|
||
|
|
||
|
This effectively forces the use of SSL, so don't use this unless
|
||
|
all of your upsd hosts are ready for SSL and have their certificates
|
||
|
in order.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
13. Recommended: force upsmon to use SSL.
|
||
|
|
||
|
Again in upsmon.conf:
|
||
|
|
||
|
FORCESSL 1
|
||
|
|
||
|
If you don't use CERTVERIFY 1, then this will at least make sure
|
||
|
that nobody can sniff your sessions without a large effort. Setting
|
||
|
this will make upsmon drop connections if the remote upsd doesn't
|
||
|
support SSL, so don't use it unless all of them have it running.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
14. Restart upsmon.
|
||
|
|
||
|
You should see something like this in the syslog from upsd:
|
||
|
|
||
|
foo upsd[1234]: Client mon@localhost logged in to UPS [myups] (SSL)
|
||
|
|
||
|
If upsd or upsmon give any error messages, or the (SSL) is missing,
|
||
|
then something isn't right.
|
||
|
|
||
|
If in doubt about upsmon, start it with -D so it will stay in
|
||
|
the foreground and print debug messages. It should print something
|
||
|
like this every couple of seconds:
|
||
|
|
||
|
polling ups: myups@localhost [SSL]
|
||
|
|
||
|
Obviously, if the [SSL] isn't there, something's broken.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
15. Recommended: sniff the connection to see it for yourself.
|
||
|
|
||
|
Using tcpdump, Ethereal, or another network sniffer tool, tell it
|
||
|
to monitor port 3493/tcp and see what happens. You should only see
|
||
|
"STARTTLS" go out, "OK STARTTLS" come back, and the rest will be
|
||
|
certificate data and then seemingly random characters.
|
||
|
|
||
|
If you see any plaintext besides that (USERNAME, PASSWORD, etc.)
|
||
|
then something is not working.
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
SSL support should be considered stable but purposely underdocumented
|
||
|
since various bits of the implementation or configuration may change in
|
||
|
the future. In other words, if you use this and it stops working after
|
||
|
an upgrade, come back to this file to find out what changed.
|
||
|
|
||
|
This is why the other documentation doesn't mention any of these
|
||
|
directives yet. SSL support is a treat for those of you that RTFM.
|
||
|
|
||
|
There are also potential licensing issues for people who ship binary
|
||
|
packages since NUT is GPL and OpenSSL is not compatible with it. You
|
||
|
can still build and use it yourself, but you can't distribute the
|
||
|
results of it. Or maybe you can. It depends on what you consider
|
||
|
"essential system software", and some other legal junk that I'm not
|
||
|
going to touch.
|
||
|
|
||
|
Other packages have solved this by explicitly stating that an exception
|
||
|
has been granted. That is (purposely) impossible here, since NUT is the
|
||
|
combined effort of many people, and all of them would have to agree to a
|
||
|
license change. This is actually a feature, since it means nobody can
|
||
|
unilaterally run off with the source - not even me.
|
||
|
|
||
|
It would be nice if we could also link against gnutls to avoid the
|
||
|
licensing issues.
|
||
|
|
||
|
Potential problems
|
||
|
==================
|
||
|
|
||
|
If you specify a certificate expiration date, you will eventually
|
||
|
see things like this in your syslog:
|
||
|
|
||
|
Oct 29 07:27:25 rktoy upsmon[3789]: Poll UPS [for750@rktoy] failed -
|
||
|
SSL error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:
|
||
|
certificate verify failed
|
||
|
|
||
|
You can verify that it is expired by using openssl to display the date:
|
||
|
|
||
|
openssl x509 -enddate -noout -in <certfile>
|
||
|
|
||
|
It'll display a date like this:
|
||
|
|
||
|
notAfter=Oct 28 20:05:32 2002 GMT
|
||
|
|
||
|
If that's after the current date, you need to generate another cert/key
|
||
|
pair using the procedure above.
|
||
|
|
||
|
CAs / signed keys
|
||
|
=================
|
||
|
|
||
|
There are probably other ways to handle this, involving keys which have
|
||
|
been signed by a CA you recognize. Contact your local SSL guru.
|
||
|
|