From 72437bd031ba57ec6581bd7bfc86f10f21a08324 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 18 Jan 2024 11:26:06 +0100 Subject: [PATCH 1/4] docs/man/upsd.conf.txt: fix multi-paragraph attachments in sections Signed-off-by: Jim Klimov --- docs/man/upsd.conf.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/man/upsd.conf.txt b/docs/man/upsd.conf.txt index bf269673a0..90e83e1c81 100644 --- a/docs/man/upsd.conf.txt +++ b/docs/man/upsd.conf.txt @@ -124,6 +124,7 @@ connections. Only set this if you know exactly what you're doing. When compiled with SSL support with OpenSSL backend, you can enter the certificate file here. ++ The certificates must be in PEM format and must be sorted starting with the subject's certificate (server certificate), followed by intermediate CA certificates (if applicable_ and the highest level (root) CA. It should @@ -134,6 +135,7 @@ NUT user manual for more information on the SSL support in NUT. When compiled with SSL support with NSS backend, you can enter the certificate path here. ++ Certificates are stored in a dedicated database (data split in 3 files). Specify the path of the database directory. @@ -148,6 +150,7 @@ the password required to access certificate related private key. When compiled with SSL support with NSS backend and client certificate validation (disabled by default, see 'docs/security.txt'), you can specify if upsd requests or requires client's' certificates. ++ Possible values are : - '0' to not request to clients to provide any certificate - '1' to require to all clients a certificate @@ -158,6 +161,7 @@ Possible values are : Tell upsd to disable older/weak SSL/TLS protocols and ciphers. With relatively recent versions of OpenSSL or NSS it will be restricted to TLSv1.2 or better. ++ Unless you have really ancient clients, you probably want to enable this. Currently disabled by default to ensure compatibility with existing setups. From 5bc19f7532354193cfb5a648e9f986fa4e2f43cd Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 18 Jan 2024 11:26:35 +0100 Subject: [PATCH 2/4] docs/man/upsmon.conf.txt: fix multi-paragraph attachments in the very nested MONITOR section Blanks and pluses are the trick: https://stackoverflow.com/a/52164722/4715872 Signed-off-by: Jim Klimov --- docs/man/upsmon.conf.txt | 62 +++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/docs/man/upsmon.conf.txt b/docs/man/upsmon.conf.txt index 0a1a49b660..e4be457b3b 100644 --- a/docs/man/upsmon.conf.txt +++ b/docs/man/upsmon.conf.txt @@ -103,55 +103,63 @@ Each UPS that you need to be monitor should have a MONITOR line. Not all of these need supply power to the system that is running upsmon. You may monitor other systems if you want to be able to send notifications about status changes on them. - ++ You must have at least one MONITOR directive in `upsmon.conf`. - -'system' is a UPS identifier. It is in this form: - ++ +* 'system' is a UPS identifier. It is in this form: ++ +[@[:]]+ - ++ The default hostname is "localhost". Some examples: - - - "su700@mybox" means a UPS called "su700" on a system called "mybox". ++ + - "su700@mybox" means a UPS called "su700" on a system called "mybox". This is the normal form. - - "fenton@bigbox:5678" is a UPS called "fenton" on a system called + - "fenton@bigbox:5678" is a UPS called "fenton" on a system called "bigbox" which runs linkman:upsd[8] on port "5678". -'powervalue' is an integer representing the number of power supplies ++ +* 'powervalue' is an integer representing the number of power supplies that the UPS feeds on this system. Most normal computers have one power supply, and the UPS feeds it, so this value will be 1. You need a very large or special system to have anything higher here. - ++ You can set the 'powervalue' to 0 if you want to monitor a UPS that doesn't actually supply power to this system. This is useful when you want to have upsmon do notifications about status changes on a UPS without shutting down when it goes critical. -The 'username' and 'password' on this line must match an entry in ++ +* The 'username' and 'password' on this line must match an entry in the `upsd` server system's linkman:upsd.users[5] file. - ++ If your username is "observer" and your password is "abcd", the MONITOR line might look like this (likely on a remote secondary system): - -+MONITOR myups@bigserver 1 observer abcd secondary+ - ++ +---- +MONITOR myups@bigserver 1 observer abcd secondary +---- ++ Meanwhile, the `upsd.users` on `bigserver` would look like this: ++ +---- +[observer] + password = abcd + upsmon secondary - [observer] - password = abcd - upsmon secondary - - [upswired] - password = blah - upsmon primary - +[upswired] + password = blah + upsmon primary +---- ++ And the copy of upsmon on that bigserver would run with the primary configuration: ++ +---- +MONITOR myups@bigserver 1 upswired blah primary +---- -+MONITOR myups@bigserver 1 upswired blah primary+ - - -The 'type' refers to the relationship with linkman:upsd[8]. It can ++ +* The 'type' refers to the relationship with linkman:upsd[8]. It can be either "primary" or "secondary". See linkman:upsmon[8] for more information on the meaning of these modes. The mode you pick here also goes in the `upsd.users` file, as seen in the example above. From 438ee6bff6c1bb109bcda5b8ad02e49c42492932 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 18 Jan 2024 11:30:58 +0100 Subject: [PATCH 3/4] docs/security.txt, docs/man/upsd.conf.txt, docs/man/upsmon.conf.txt: stress that multi-word "Certificate Name" values should be double-quoted; fix examples [#2265] Signed-off-by: Jim Klimov --- docs/man/upsd.conf.txt | 3 +++ docs/man/upsmon.conf.txt | 6 ++++++ docs/security.txt | 8 ++++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/man/upsd.conf.txt b/docs/man/upsd.conf.txt index 90e83e1c81..5597f483c5 100644 --- a/docs/man/upsd.conf.txt +++ b/docs/man/upsd.conf.txt @@ -144,6 +144,9 @@ Specify the path of the database directory. When compiled with SSL support with NSS backend, you can specify the certificate name to retrieve from database to authenticate itself and the password required to access certificate related private key. ++ +NOTE: Be sure to enclose "certificate name" in double-quotes if you +are using a value with spaces in it. "CERTREQUEST 'certificate request level'":: diff --git a/docs/man/upsmon.conf.txt b/docs/man/upsmon.conf.txt index e4be457b3b..a50edb86f7 100644 --- a/docs/man/upsmon.conf.txt +++ b/docs/man/upsmon.conf.txt @@ -446,6 +446,9 @@ When compiled with SSL support, you can enter the certificate path here. When compiled with SSL support with NSS, you can specify the certificate name to retrieve from database to authenticate itself and the password required to access certificate related private key. ++ +NOTE: Be sure to enclose "certificate name" in double-quotes if you +are using a value with spaces in it. *CERTHOST* 'hostname' 'certificate name' 'certverify' 'forcessl':: @@ -455,6 +458,9 @@ for each server you can contact. Each entry maps server name with the expected certificate name and flags indicating if the server certificate is verified and if the connection must be secure. ++ +NOTE: Be sure to enclose "certificate name" in double-quotes if you +are using a value with spaces in it. *CERTVERIFY* '0 | 1':: diff --git a/docs/security.txt b/docs/security.txt index 92673eb86e..5f873c1589 100644 --- a/docs/security.txt +++ b/docs/security.txt @@ -569,7 +569,7 @@ Edit the upsd.conf to tell where find the certificate database: Also tell which is the certificate to send to clients to authenticate itself and the password to decrypt private key associated to certificate: - CERTIDENT 'certificate name' 'database password' + CERTIDENT "certificate name" "database password" NOTE: Generally, the certificate name is the server domain name, but is not a hard rule. The certificate can be named as useful. @@ -608,13 +608,13 @@ with the directive 'CERTHOST'. whether a SSL connection is mandatory, and if the server certificate must be validated. - CERTHOST 'hostname' 'certificate name' 'certverify' 'forcessl' + CERTHOST "hostname" "certificate name" "certverify" "forcessl" If the flag `forcessl` is set to `1`, and upsd answers that it can not connect with SSL, the connection closes. If the flag `certverify` is set to `1` and the connection is done in SSL, upsd's certificate is verified and its name must be the specified -'certificate name'. +`"certificate name"`. To prevent security leaks, you should set all `certverify` and `forcessl` flags to `1` (force SSL connection and validate all certificates for all @@ -638,7 +638,7 @@ database configuring `CERTPATH` and `CERTIDENT` in upsmon.conf in the same way as upsd. CERTPATH /usr/local/ups/etc/cert_db - CERTIDENT 'certificate name' 'database password' + CERTIDENT "certificate name" "database password" Restart upsd From 9441ed230627d53e09b2d8f1401e874aa3bfd3da Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 18 Jan 2024 11:31:57 +0100 Subject: [PATCH 4/4] docs/security.txt: typography: fix quoting style Signed-off-by: Jim Klimov --- docs/security.txt | 92 ++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/docs/security.txt b/docs/security.txt index 5f873c1589..99e85b7ee7 100644 --- a/docs/security.txt +++ b/docs/security.txt @@ -187,7 +187,7 @@ During the initial <>, we have created a monitoring user for `upsmon`. -You can also create an 'administrator' user with full power using: +You can also create an `administrator` user in NUT with full power using: [administrator] password = mypass @@ -295,10 +295,10 @@ Configuring SSL SSL is available as a build option (`--with-ssl`). -It encrypts sessions between upsd and clients, and can also be used to +It encrypts sessions between `upsd` and clients, and can also be used to authenticate servers. -This means that stealing port 3493 from upsd will no longer net you interesting +This means that stealing port 3493 from `upsd` will no longer net you interesting passwords. Several things must happen before this will work, however. This chapter will @@ -375,18 +375,18 @@ Example: 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. +`0` part until you get a unique filename that works. -If you have multiple client systems (like upsmon instances in +If you have multiple client systems (like `upsmon` instances in secondary mode), be sure to install this file on them as well. We 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. +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. +insert a new client certificate and fool `upsmon` into trusting a +fake `upsd`. Create the combined file for upsd ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -398,12 +398,12 @@ To do so, use the below commands: 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 +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 +Having it 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. +is done to minimize the impact if someone should break into `upsd`. NUT reads the key and certificate files after dropping privileges and forking. @@ -439,13 +439,13 @@ 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. +If you run `upsd` as a separate user id (like `nutsrv`), make sure that +user can read the `upsd.pem` file. Point upsmon at the certificates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Edit your upsmon.conf, and tell it where the CERTPATH is: +Edit your `upsmon.conf`, and tell it where the `CERTPATH` is: CERTPATH @@ -456,27 +456,27 @@ Example: Recommended: make upsmon verify all connections with certificates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Put this in upsmon.conf: +Put this in `upsmon.conf`: CERTVERIFY 1 -Without this, there is no guarantee that the upsd is the right host. +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 +all of your `upsd` hosts are ready for SSL and have their certificates in order. Recommended: force upsmon to use SSL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Again in upsmon.conf: +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 +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. NSS backend usage @@ -510,12 +510,12 @@ Certificates should be signed by a certification authorities (CAs). Following commands are typical samples, contact your SSL guru or security officer to follow your company procedures. -.Generate a server certificate for upsd: +.Generate a server certificate for `upsd`: - Create a directory where store the certificate database: `mkdir cert_db` - Create the certificate database : `certutil -N -d cert_db` - Import the CA certificate: `certutil -A -d cert_db -n "My Root CA" -t "TC,," -a -i rootca.crt` -- Create a server certificate request (here called 'My nut server'): +- Create a server certificate request (here called "My nut server"): `certutil -R -d cert_db -s "CN=My nut server,O=MyCompany,ST=MyState,C=US" -a -o server.req` - Make your CA sign the certificate (produces server.crt) - Import the signed certificate into server database: @@ -542,8 +542,8 @@ an "official" certificate authority. `certutil -N -d CA_db` - Generate a certificate for CA: `certutil -S -d CA_db -n "My Root CA" -s "CN=My CA,O=MyCompany,ST=MyState,C=US" -t "CT,," -x -2` -(Do not forget to answer 'Yes' to the question 'Is this a CA certificate [y/N]?') -- Extract the CA certificate to be able to import it in upsd (or upsmon) +(Do not forget to answer `Yes` to the question "Is this a CA certificate [y/N]?") +- Extract the CA certificate to be able to import it in `upsd` (or `upsmon`) certificate database: `certutil -L -d CA_db -n "My Root CA" -a -o rootca.crt` - Sign a certificate request with the CA certificate (simulate a real CA @@ -562,7 +562,7 @@ database .db files) to the right place, such as `/usr/local/ups/etc/`: upsd (required): certificate database and self certificate ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Edit the upsd.conf to tell where find the certificate database: +Edit the `upsd.conf` to tell where find the certificate database: CERTPATH /usr/local/ups/etc/cert_db @@ -583,7 +583,7 @@ NUT with `WITH_CLIENT_CERTIFICATE_VALIDATION` defined: make CFLAGS="-DWITH_CLIENT_CERTIFICATE_VALIDATION" UPSD can accept three levels of client authentication. Just specify it with -the directive `CERTREQUEST` with the corresponding value in the upsd.conf +the directive `CERTREQUEST` with the corresponding value in the `upsd.conf` file: - NO: no client authentication. @@ -593,27 +593,28 @@ If the client does not send any certificate, the connection is closed. - REQUIRE: a certificate is requested to the client and if it is not valid (no validation chain) the connection is closed. -Like CA certificates, you can add many 'trusted' client and CA certificates +Like CA certificates, you can add many "trusted" client and CA certificates in server's certificate databases. upsmon (required): upsd authentication ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In order for upsmon to securely connect to upsd, it must authenticate it. -You must associate an upsd host name to security rules in upsmon.conf -with the directive 'CERTHOST'. +In order for `upsmon` to securely connect to `upsd`, it must authenticate it. +You must associate an `upsd` host name to security rules in `upsmon.conf` +with the directive `CERTHOST`. -'CERTHOST' associates a hostname to a certificate name. It also determines +`CERTHOST` associates a hostname to a certificate name. It also determines whether a SSL connection is mandatory, and if the server certificate must be validated. CERTHOST "hostname" "certificate name" "certverify" "forcessl" -If the flag `forcessl` is set to `1`, and upsd answers that it can not +If the flag `forcessl` is set to `1`, and `upsd` answers that it can not connect with SSL, the connection closes. + If the flag `certverify` is set to `1` and the connection is done in SSL, -upsd's certificate is verified and its name must be the specified +`upsd`'s certificate is verified and its name must be the specified `"certificate name"`. To prevent security leaks, you should set all `certverify` and `forcessl` @@ -631,11 +632,12 @@ name is its hostname. upsmon (optional): certificate database and self certificate ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Like upsd, upsmon may need to authenticate itself (upsd's `CERTREQUEST` +Like `upsd`, `upsmon` may need to authenticate itself (`upsd`'s `CERTREQUEST` directive set to `REQUEST` or `REQUIRE`). + It must access to a certificate (and its private key) in a certificate -database configuring `CERTPATH` and `CERTIDENT` in upsmon.conf in the -same way as upsd. +database configuring `CERTPATH` and `CERTIDENT` in `upsmon.conf` in the +same way as `upsd`. CERTPATH /usr/local/ups/etc/cert_db CERTIDENT "certificate name" "database password" @@ -647,21 +649,21 @@ 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 +If you run `upsd` as a separate user ID (like `nutsrv`), make sure that user can read files in the certificate directory. NUT reads the keys and certificates after forking and dropping privileges. Restart upsmon ~~~~~~~~~~~~~~ -You should see something like this in the syslog from upsd: +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, +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 +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: @@ -731,7 +733,7 @@ Note that the replacement of OpenSSL by Mozilla Network Security Services chrooting and other forms of paranoia ------------------------------------- -It has been possible to run the drivers and upsd in a chrooted jail for +It has been possible to run the drivers and `upsd` in a chrooted jail for some time, but it involved a number of evil hacks. From the 1.3 series, a much saner chroot behavior exists, using BIND 9 as an inspiration. @@ -763,7 +765,7 @@ programs have been built with the default prefix, so they are using cp -a /usr/local/ups/etc/upsd.conf . cp -a /usr/local/ups/etc/ups.conf . -We're using 'cp -a' to maintain the permissions on those files. +We're using `cp -a` to maintain the permissions on those files. Now bring over your state path, maintaining the same permissions as before. @@ -803,7 +805,7 @@ symlinks ~~~~~~~~ After you do this, you will have two copies of many things, like the -confpath and the state path. I recommend deleting the 'real' +confpath and the state path. I recommend deleting the "real" `/var/state/ups`, replacing it with a symlink to `/chroot/nut/var/state/ups`. That will let other programs reference the `.pid` files without a lot of hassle. @@ -811,7 +813,7 @@ confpath and the state path. I recommend deleting the 'real' You can also do this with your confpath and point `/usr/local/ups/etc` (or equivalent on your system) at `/chroot/nut/usr/local/ups/etc` unless you're worried about something hurting the files inside that directory. In that -case, you should maintain a 'golden' copy and push it into the chroot path +case, you should maintain a "golden" copy and push it into the chroot path after making changes. The `upsdrvctl` itself does not chroot, so the `ups.conf` still needs to be @@ -820,9 +822,9 @@ in the usual confpath. upsmon ~~~~~~ -This has not yet been applied to upsmon, since it can be quite +This has not yet been applied to `upsmon`, since it can be quite complicated when there are notifiers that need to be run. One -possibility would be for upsmon to have three instances: +possibility would be for `upsmon` to have three instances: - privileged root parent that listens for a shutdown command