Version 1 vs 2
Version 1 vs 2
Content Changes
Content Changes
Pacemaker optionally supports encrypting communications with TLS certificates for two things:
# Pacemaker Remote node connections
# Remote CIB operations (`CIB_user=... CIB_encrypted=... CIB_port=... cibadmin -Q`)
This is especially important for remote CIB operations which have no encryption at all otherwise.
Testing this requires a fair bit of setup. We assume that users will use TLS certificates as follows:
- They will set up their own Certificate Authority (CA). In the real world, you pay a real CA a lot of money to sign your credentials. This is because web browsers have lists of CAs they trust, and so if you use one of those then your credentials will be trusted. Otherwise the user will get a scary error about self-signed certificates and things like that. However, we expect that people will keep their clusters on private networks and connect via our own command line tools, so there's no real need for a trusted, real CA.
- They will generate one set of credentials for each server. If they have ten Pacemaker Remote nodes (remember - remote nodes are the server, the cluster is the client) then each would have its own server cert and key.
- They will generate one set of credentials for each client. If they have ten admin machines that need to run `cibadmin` to do remote CIB operations, then each would have its own client cert and key. This makes it possible to revoke a single client's credentials if necessary without a lot of annoying work.
In addition, this document will assume there is not an intermediate CA involved. In the real world, you would create a root CA and only use that to sign credentials for intermediate CAs. The intermediate CA would then sign the client/server credentials. The reason for this is that if your CA gets compromised, everything it has ever signed is now compromised as well. The root CA credentials would be locked away and only taken out on the rare time when you need a new intermediate. Pacemaker should support this just fine as long as the root CA and intermediate CA credentials get bundled together. I'm not going to cover how to do that here.
Pacemaker optionally supports encrypting communications with TLS certificates for two things:
# Pacemaker Remote node connections
# Remote CIB operations (`CIB_user=... CIB_encrypted=... CIB_port=... cibadmin -Q`)
This is especially important for remote CIB operations which have no encryption at all otherwise.
Testing this requires a fair bit of setup. We assume that users will use TLS certificates as follows:
- They will set up their own Certificate Authority (CA). In the real world, you pay a real CA a lot of money to sign your credentials. This is because web browsers have lists of CAs they trust, and so if you use one of those then your credentials will be trusted. Otherwise the user will get a scary error about self-signed certificates and things like that. However, we expect that people will keep their clusters on private networks and connect via our own command line tools, so there's no real need for a trusted, real CA.
- They will generate one set of credentials for each server. If they have ten Pacemaker Remote nodes (remember - remote nodes are the server, the cluster is the client) then each would have its own server cert and key.
- They will generate one set of credentials for each client. If they have ten admin machines that need to run `cibadmin` to do remote CIB operations, then each would have its own client cert and key. This makes it possible to revoke a single client's credentials if necessary without a lot of annoying work.
In addition, this document will assume there is not an intermediate CA involved. In the real world, you would create a root CA and only use that to sign credentials for intermediate CAs. The intermediate CA would then sign the client/server credentials. The reason for this is that if your CA gets compromised, everything it has ever signed is now compromised as well. The root CA credentials would be locked away and only taken out on the rare time when you need a new intermediate. Pacemaker should support this just fine as long as the root CA and intermediate CA credentials get bundled together. I'm not going to cover how to do that here.
If you look around, you'll find tons of explanations for how to set this stuff up. These instructions worked for me. There very well may be much simpler ways to do all of this.
To generate TLS credentials, you need to do all of the following...
= Create your own CA =
== Set up the directory structure ==
```
$ mkdir -p ~/cert-stuff/ca/{certs,newcerts,private,csr}
$ mkdir -p ~/cert-stuff/{clients,servers}
$ cd ~/cert-stuff/ca
$ echo 01 > serial
$ echo 01 > crlnumber
$ touch index.txt
```
== Create `openssl.cnf` ==
I'm not sure how much of this is necessary at all. I haven't experimented with simplification. At the least, check `dir`, `countryName`, `stateOrProvinceName`, `localityName`, and `organizationName` and set them to something that makes sense for you.
```
[ ca ] # The default CA section
default_ca = CA_default # The default CA name
[ CA_default ] # Default settings for the CA
dir = /root/cert-stuff/ca # CA directory
certs = $dir/certs # Certificates directory
crl_dir = $dir/crl # CRL directory
new_certs_dir = $dir/newcerts # New certificates directory
database = $dir/index.txt # Certificate index file
serial = $dir/serial # Serial number file
RANDFILE = $dir/private/.rand # Random number file
private_key = $dir/private/ca.key.pem # Root CA private key
certificate = $dir/certs/ca.cert.pem # Root CA certificate
crl = $dir/crl/ca.crl.pem # Root CA CRL
crlnumber = $dir/crlnumber # Root CA CRL number
crl_extensions = crl_ext # CRL extensions
default_crl_days = 30 # Default CRL validity days
default_md = sha256 # Default message digest
preserve = no # Preserve existing extensions
email_in_dn = no # Exclude email from the DN
name_opt = ca_default # Formatting options for names
cert_opt = ca_default # Certificate output options
policy = policy_strict # Certificate policy
unique_subject = no # Allow multiple certs with the same DN
[ policy_strict ] # Policy for stricter validation
countryName = match # Must match the issuer's country
stateOrProvinceName = match # Must match the issuer's state
organizationName = match # Must match the issuer's organization
organizationalUnitName = optional # Organizational unit is optional
commonName = optional # Must provide a common name
emailAddress = optional # Email address is optional
[ req ] # Request settings
default_bits = 2048 # Default key size
distinguished_name = req_distinguished_name # Default DN template
string_mask = utf8only # UTF-8 encoding
default_md = sha256 # Default message digest
prompt = no # Non-interactive mode
[ req_distinguished_name ] # Template for the DN in the CSR
countryName = US
stateOrProvinceName = NH
localityName = Merrimack
organizationName = Cluster
[ v3_ca ] # Root CA certificate extensions
subjectKeyIdentifier = hash # Subject key identifier
authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
basicConstraints = critical, CA:true # Basic constraints for a CA
keyUsage = critical, keyCertSign, cRLSign # Key usage for a CA
[ crl_ext ] # CRL extensions
authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
```
== Generate the root CA certificate ==
Set `days` to something appropriate - this is how many days until the root CA expires. For testing, shorter is fine. For real world use, make it very long. When the root CA expires, everything it signed expires too. Years would be appropriate.
Also set `subj` appropriately too. I'm not actually sure if this needs to be set at all given that it's already in the config file.
```
$ openssl genrsa -out private/ca.key.pem 4096
$ openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 100 -sha256 -extensions v3_ca -out certs/ca.cert.pem -subj "/C=US/ST=NH/L=Merrimack/O=Cluster/CN=Root CA"
```
For real world use, keep the private `ca.key.pem` file private. Set ownership and permissions restrictively. Maybe store it on a USB key instead of permanently on the system. The `ca.cert.pem` file should be installed to every client and server system and readable by the cluster user (`hacluster:haclient` most likely). This file should also be referenced in `/etc/sysconfig/pacemaker` as `PCMK_ca_file`.
Pacemaker optionally supports encrypting communications with TLS certificates for two things:
# Pacemaker Remote node connections
# Remote CIB operations (`CIB_user=... CIB_encrypted=... CIB_port=... cibadmin -Q`)
This is especially important for remote CIB operations which have no encryption at all otherwise.
Testing this requires a fair bit of setup. We assume that users will use TLS certificates as follows:
- They will set up their own Certificate Authority (CA). In the real world, you pay a real CA a lot of money to sign your credentials. This is because web browsers have lists of CAs they trust, and so if you use one of those then your credentials will be trusted. Otherwise the user will get a scary error about self-signed certificates and things like that. However, we expect that people will keep their clusters on private networks and connect via our own command line tools, so there's no real need for a trusted, real CA.
- They will generate one set of credentials for each server. If they have ten Pacemaker Remote nodes (remember - remote nodes are the server, the cluster is the client) then each would have its own server cert and key.
- They will generate one set of credentials for each client. If they have ten admin machines that need to run `cibadmin` to do remote CIB operations, then each would have its own client cert and key. This makes it possible to revoke a single client's credentials if necessary without a lot of annoying work.
In addition, this document will assume there is not an intermediate CA involved. In the real world, you would create a root CA and only use that to sign credentials for intermediate CAs. The intermediate CA would then sign the client/server credentials. The reason for this is that if your CA gets compromised, everything it has ever signed is now compromised as well. The root CA credentials would be locked away and only taken out on the rare time when you need a new intermediate. Pacemaker should support this just fine as long as the root CA and intermediate CA credentials get bundled together. I'm not going to cover how to do that here.
If you look around, you'll find tons of explanations for how to set this stuff up. These instructions worked for me. There very well may be much simpler ways to do all of this.
To generate TLS credentials, you need to do all of the following...
= Create your own CA =
== Set up the directory structure ==
```
$ mkdir -p ~/cert-stuff/ca/{certs,newcerts,private,csr}
$ mkdir -p ~/cert-stuff/{clients,servers}
$ cd ~/cert-stuff/ca
$ echo 01 > serial
$ echo 01 > crlnumber
$ touch index.txt
```
== Create `openssl.cnf` ==
I'm not sure how much of this is necessary at all. I haven't experimented with simplification. At the least, check `dir`, `countryName`, `stateOrProvinceName`, `localityName`, and `organizationName` and set them to something that makes sense for you.
```
[ ca ] # The default CA section
default_ca = CA_default # The default CA name
[ CA_default ] # Default settings for the CA
dir = /root/cert-stuff/ca # CA directory
certs = $dir/certs # Certificates directory
crl_dir = $dir/crl # CRL directory
new_certs_dir = $dir/newcerts # New certificates directory
database = $dir/index.txt # Certificate index file
serial = $dir/serial # Serial number file
RANDFILE = $dir/private/.rand # Random number file
private_key = $dir/private/ca.key.pem # Root CA private key
certificate = $dir/certs/ca.cert.pem # Root CA certificate
crl = $dir/crl/ca.crl.pem # Root CA CRL
crlnumber = $dir/crlnumber # Root CA CRL number
crl_extensions = crl_ext # CRL extensions
default_crl_days = 30 # Default CRL validity days
default_md = sha256 # Default message digest
preserve = no # Preserve existing extensions
email_in_dn = no # Exclude email from the DN
name_opt = ca_default # Formatting options for names
cert_opt = ca_default # Certificate output options
policy = policy_strict # Certificate policy
unique_subject = no # Allow multiple certs with the same DN
[ policy_strict ] # Policy for stricter validation
countryName = match # Must match the issuer's country
stateOrProvinceName = match # Must match the issuer's state
organizationName = match # Must match the issuer's organization
organizationalUnitName = optional # Organizational unit is optional
commonName = optional # Must provide a common name
emailAddress = optional # Email address is optional
[ req ] # Request settings
default_bits = 2048 # Default key size
distinguished_name = req_distinguished_name # Default DN template
string_mask = utf8only # UTF-8 encoding
default_md = sha256 # Default message digest
prompt = no # Non-interactive mode
[ req_distinguished_name ] # Template for the DN in the CSR
countryName = US
stateOrProvinceName = NH
localityName = Merrimack
organizationName = Cluster
[ v3_ca ] # Root CA certificate extensions
subjectKeyIdentifier = hash # Subject key identifier
authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
basicConstraints = critical, CA:true # Basic constraints for a CA
keyUsage = critical, keyCertSign, cRLSign # Key usage for a CA
[ crl_ext ] # CRL extensions
authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
```
== Generate the root CA certificate ==
Set `days` to something appropriate - this is how many days until the root CA expires. For testing, shorter is fine. For real world use, make it very long. When the root CA expires, everything it signed expires too. Years would be appropriate.
Also set `subj` appropriately too. I'm not actually sure if this needs to be set at all given that it's already in the config file.
```
$ openssl genrsa -out private/ca.key.pem 4096
$ openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 100 -sha256 -extensions v3_ca -out certs/ca.cert.pem -subj "/C=US/ST=NH/L=Merrimack/O=Cluster/CN=Root CA"
```
For real world use, keep the private `ca.key.pem` file private. Set ownership and permissions restrictively. Maybe store it on a USB key instead of permanently on the system. The `ca.cert.pem` file should be installed to every client and server system and readable by the cluster user (`hacluster:haclient` most likely). This file should also be referenced in `/etc/sysconfig/pacemaker` as `PCMK_ca_file`.