449 lines
15 KiB
Markdown
449 lines
15 KiB
Markdown
# How to configure the server TLS certificates for authentication
|
|
|
|
Author: Zbigniew Kurzynski <zbigniew.kurzynski@intel.com>
|
|
|
|
Created: May 8, 2020
|
|
|
|
Related documents:
|
|
|
|
- [Redfish TLS User Authentication](https://github.com/openbmc/docs/blob/master/designs/redfish-tls-user-authentication.md)
|
|
|
|
## Introduction
|
|
|
|
With help of this guidebook you should be able to create both client and server
|
|
certificates signed by a CA that can be used to authenticate user requests to an
|
|
OpenBMC server. You will also learn how to enable and test the OpenBMC TLS
|
|
authentication.
|
|
|
|
## Certificates
|
|
|
|
For a certificate to be marked as valid, it (and every certificate in the chain)
|
|
has to meet these conditions:
|
|
|
|
- `KeyUsage` contains required purpose `digitalSignature` and `keyAgreement`
|
|
(see rfc 3280 4.2.1.3)
|
|
- `ExtendedKeyUsage` contains required purpose `clientAuth` for client
|
|
certificate and `serverAuth` for server certificate (see rfc 3280 4.2.1.13)
|
|
- public key meets minimal bit length requirement
|
|
- certificate has to be in its validity period
|
|
- `notBefore` and `notAfter` fields have to contain valid time
|
|
- has to be properly signed by certificate authority
|
|
- certificate is well-formed according to X.509
|
|
- issuer name has to match CA's subject name for client certificate
|
|
- issuer name has to match the fully qualified domain name of your OpenBMC host
|
|
|
|
If you already have certificates you can skip to
|
|
[Enable TLS authentication ](#Enable-TLS-authentication) or go to
|
|
[Verify certificates](#Verify-certificates) and check if they meet the above
|
|
requirements.
|
|
|
|
### Prepare configuration files
|
|
|
|
To generate certificates with required parameters some modification must be made
|
|
to the default openssl configuration file.
|
|
|
|
First create a new folder named `ca` and create a configuration file using the
|
|
default configuration as a template (we do not want to change the original one).
|
|
The location of the configuration file may vary depending on the operating
|
|
system. For Ubuntu it is usually `/usr/lib/ssl/openssl.cnf`, but can also can be
|
|
at `/etc/ssl/openssl.cnf`. For Cygwin it might be
|
|
`/etc/defaults/etc/pki/tls/openssl.cnf` or `/etc/pki/tls/openssl.cnf`.
|
|
|
|
```
|
|
mkdir ~/ca
|
|
cd ~/ca
|
|
cp /usr/lib/ssl/openssl.cnf openssl-client.cnf
|
|
```
|
|
|
|
Then open the client `~/ca/openssl-client.cnf` file in your favorite editor, for
|
|
example `vi`.
|
|
|
|
```
|
|
vi ~/ca/openssl-client.cnf
|
|
```
|
|
|
|
Find the sections listed below and add or choose the presented values.
|
|
|
|
```
|
|
[ req ]
|
|
req_extensions = v3_req
|
|
|
|
[ usr_cert ]
|
|
extendedKeyUsage = clientAuth
|
|
|
|
[ v3_req ]
|
|
extendedKeyUsage = clientAuth
|
|
keyUsage = digitalSignature, keyAgreement
|
|
```
|
|
|
|
Now create a server configuration `openssl-server.cnf` by copying the client
|
|
file
|
|
|
|
```
|
|
cp ~/ca/openssl-client.cnf openssl-server.cnf
|
|
```
|
|
|
|
and changing values presented in the sections listed below.
|
|
|
|
```
|
|
[ usr_cert ]
|
|
extendedKeyUsage = serverAuth
|
|
|
|
[ v3_req ]
|
|
extendedKeyUsage = serverAuth
|
|
```
|
|
|
|
Create two additional configuration files `myext-client.cnf` and
|
|
`myext-server.cnf` for the client and server certificates respectively. Without
|
|
these files no extensions are added to the certificate.
|
|
|
|
```
|
|
cat << END > myext-client.cnf
|
|
[ my_ext_section ]
|
|
keyUsage = digitalSignature, keyAgreement
|
|
extendedKeyUsage = clientAuth
|
|
authorityKeyIdentifier = keyid
|
|
END
|
|
```
|
|
|
|
```
|
|
cat << END > myext-server.cnf
|
|
[ my_ext_section ]
|
|
keyUsage = digitalSignature, keyAgreement
|
|
extendedKeyUsage = serverAuth
|
|
authorityKeyIdentifier = keyid
|
|
END
|
|
```
|
|
|
|
### Create a new CA certificate
|
|
|
|
First we need to create a private key to sign the CA certificate.
|
|
|
|
```
|
|
openssl genrsa -out CA-key.pem 2048
|
|
```
|
|
|
|
Now we can create a CA certificate, using the previously generated key. You will
|
|
be prompted for information which will be incorporated into the certificate,
|
|
such as Country, City, Company Name, etc.
|
|
|
|
```
|
|
openssl req -new -config openssl-client.cnf -key CA-key.pem -x509 -days 1000 -out CA-cert.pem
|
|
```
|
|
|
|
### Create client certificate signed by given CA certificate
|
|
|
|
To create a client certificate, a signing request must be created first. For
|
|
this another private key will be needed.
|
|
|
|
Generate a new key that will be used to sign the certificate signing request:
|
|
|
|
```
|
|
openssl genrsa -out client-key.pem 2048
|
|
```
|
|
|
|
Generate a certificate signing request.
|
|
|
|
You will be prompted for the same information as during CA generation, but
|
|
provide **the OpenBMC system user name** for the `CommonName` attribute of this
|
|
certificate. In this example, use **root**.
|
|
|
|
```
|
|
openssl req -new -config openssl-client.cnf -key client-key.pem -out signingReqClient.csr
|
|
```
|
|
|
|
Sign the certificate using your `CA-cert.pem` certificate with following
|
|
command:
|
|
|
|
```
|
|
openssl x509 -req -extensions my_ext_section -extfile myext-client.cnf -days 365 -in signingReqClient.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out client-cert.pem
|
|
```
|
|
|
|
The file `client-cert.pem` now contains a signed client certificate.
|
|
|
|
### Create server certificate signed by given CA certificate
|
|
|
|
For convenience we will use the same CA generated in paragraph
|
|
[Create a new CA certificate](#Create-a-new-CA-certificate), although a
|
|
different one could be used.
|
|
|
|
Generate a new key that will be used to sign the server certificate signing
|
|
request:
|
|
|
|
```
|
|
openssl genrsa -out server-key.pem 2048
|
|
```
|
|
|
|
Generate a certificate signing request. You will be prompted for the same
|
|
information as during CA generation, but provide **the fully qualified domain
|
|
name of your OpenBMC server** for the `CommonName` attribute of this
|
|
certificate. In this example it will be `bmc.example.com`. A wildcard can be
|
|
used to protect multiple host, for example a certificate configured for
|
|
`*.example.com` will secure www.example.com, as well as mail.example.com,
|
|
blog.example.com, and others.
|
|
|
|
```
|
|
openssl req -new -config openssl-server.cnf -key server-key.pem -out signingReqServer.csr
|
|
```
|
|
|
|
Sign the certificate using your `CA-cert.pem` certificate with following
|
|
command:
|
|
|
|
```
|
|
openssl x509 -req -extensions my_ext_section -extfile myext-server.cnf -days 365 -in signingReqServer.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out server-cert.pem
|
|
```
|
|
|
|
The file `server-cert.pem` now contains a signed server certificate.
|
|
|
|
### Verify certificates
|
|
|
|
To verify the signing request and both certificates you can use following
|
|
commands.
|
|
|
|
```
|
|
openssl x509 -in CA-cert.pem -text -noout
|
|
openssl x509 -in client-cert.pem -text -noout
|
|
openssl x509 -in server-cert.pem -text -noout
|
|
openssl req -in signingReqClient.csr -noout -text
|
|
openssl req -in signingReqServer.csr -noout -text
|
|
```
|
|
|
|
Below are example listings that you can compare with your results. Pay special
|
|
attention to attributes like:
|
|
|
|
- Validity in both certificates,
|
|
- `Issuer` in `client-cert.pem`, it must match to `Subject` in `CA-cert.pem`,
|
|
- Section _X509v3 extensions_ in `client-cert.pem` it should contain proper
|
|
values,
|
|
- `Public-Key` length, it cannot be less than 2048 bits.
|
|
- `Subject` CN in `client-cert.pem`, it should match existing OpemBMC user name.
|
|
In this example it is **root**.
|
|
- `Subject` CN in `server-cert.pem`, it should match OpemBMC host name. In this
|
|
example it is **bmc.example.com **. (see rfc 3280 4.2.1.11 for name
|
|
constraints)
|
|
|
|
Below are fragments of generated certificates that you can compare with.
|
|
|
|
```
|
|
CA-cert.pem
|
|
Data:
|
|
Version: 3 (0x2)
|
|
Serial Number: 16242916899984461675 (0xe16a6edca3c34f6b)
|
|
Signature Algorithm: sha256WithRSAEncryption
|
|
Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
|
|
Validity
|
|
Not Before: May 11 11:40:48 2020 GMT
|
|
Not After : Feb 5 11:40:48 2023 GMT
|
|
Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
|
|
Subject Public Key Info:
|
|
Public Key Algorithm: rsaEncryption
|
|
Public-Key: (2048 bit)
|
|
Modulus:
|
|
00:d4:24:c1:1d:ac:85:8c:5b:42:e4:f8:a8:d8:7c:
|
|
...
|
|
55:83:8b:aa:ac:ac:6e:e3:01:2b:ce:f7:ee:87:21:
|
|
f9:2b
|
|
Exponent: 65537 (0x10001)
|
|
X509v3 extensions:
|
|
X509v3 Subject Key Identifier:
|
|
ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
|
|
X509v3 Authority Key Identifier:
|
|
keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
|
|
|
|
X509v3 Basic Constraints:
|
|
CA:TRUE
|
|
Signature Algorithm: sha256WithRSAEncryption
|
|
cc:8b:61:6a:55:60:2b:26:55:9f:a6:0c:42:b0:47:d4:ec:e0:
|
|
...
|
|
45:47:91:62:10:bd:3e:a8:da:98:33:65:cc:11:23:95:06:1b:
|
|
ee:d3:78:84
|
|
```
|
|
|
|
```
|
|
client-cert.pem
|
|
Data:
|
|
Version: 3 (0x2)
|
|
Serial Number: 10150871893861973895 (0x8cdf2434b223bf87)
|
|
Signature Algorithm: sha256WithRSAEncryption
|
|
Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
|
|
Validity
|
|
Not Before: May 11 11:42:58 2020 GMT
|
|
Not After : May 11 11:42:58 2021 GMT
|
|
Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=root
|
|
Subject Public Key Info:
|
|
Public Key Algorithm: rsaEncryption
|
|
Public-Key: (2048 bit)
|
|
Modulus:
|
|
00:cf:d6:d0:a2:09:62:df:e9:a9:b1:e1:3d:7f:2f:
|
|
...
|
|
30:7b:48:dc:c5:2c:3f:a9:c0:d1:b6:04:d4:1a:c8:
|
|
8a:51
|
|
Exponent: 65537 (0x10001)
|
|
X509v3 extensions:
|
|
X509v3 Key Usage:
|
|
Digital Signature, Key Agreement
|
|
X509v3 Extended Key Usage:
|
|
TLS Web Client Authentication
|
|
X509v3 Authority Key Identifier:
|
|
keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
|
|
|
|
Signature Algorithm: sha256WithRSAEncryption
|
|
7f:a4:57:f5:97:48:2a:c4:8e:d3:ef:d8:a1:c9:65:1b:20:fd:
|
|
...
|
|
25:cb:5e:0a:37:fb:a1:ab:b0:c4:62:fe:51:d3:1c:1b:fb:11:
|
|
56:57:4c:6a
|
|
```
|
|
|
|
```
|
|
server-cert.pem
|
|
Data:
|
|
Version: 3 (0x2)
|
|
Serial Number: 10622848005881387807 (0x936beffaa586db1f)
|
|
Signature Algorithm: sha256WithRSAEncryption
|
|
Issuer: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com
|
|
Validity
|
|
Not Before: May 22 13:46:02 2020 GMT
|
|
Not After : May 22 13:46:02 2021 GMT
|
|
Subject: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com
|
|
Subject Public Key Info:
|
|
Public Key Algorithm: rsaEncryption
|
|
Public-Key: (2048 bit)
|
|
Modulus:
|
|
00:d9:34:9c:da:83:c6:eb:af:8f:e8:11:56:2a:59:
|
|
...
|
|
92:60:09:fc:f9:66:82:d0:27:03:44:2f:9d:6d:c0:
|
|
a5:6d
|
|
Exponent: 65537 (0x10001)
|
|
X509v3 extensions:
|
|
X509v3 Key Usage:
|
|
Digital Signature, Key Agreement
|
|
X509v3 Extended Key Usage:
|
|
TLS Web Server Authentication
|
|
X509v3 Authority Key Identifier:
|
|
keyid:5B:1D:0E:76:CC:54:B8:BF:AE:46:10:43:6F:79:0B:CA:14:5C:E0:90
|
|
|
|
Signature Algorithm: sha256WithRSAEncryption
|
|
bf:41:e2:2f:87:44:25:d8:54:9c:4e:dc:cc:b3:f9:af:5a:a3:
|
|
...
|
|
ef:0f:90:a6
|
|
|
|
```
|
|
|
|
## Installing CA certificate on OpenBMC
|
|
|
|
The CA certificate can be installed via Redfish Service. The file `CA-cert.pem`
|
|
can not be uploaded directly but must be sent embedded in a valid JSON string,
|
|
which requires `\`, `"`, and control characters must be escaped. This means all
|
|
content is placed in a single string on a single line by encoding the line
|
|
endings as `\n`. The command below prepares a whole POST body and puts it into a
|
|
file named: `install_ca.json`.
|
|
|
|
```
|
|
cat << END > install_ca.json
|
|
{
|
|
"CertificateString":"$(cat CA-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')",
|
|
"CertificateType": "PEM"
|
|
}
|
|
END
|
|
```
|
|
|
|
To install the CA certificate on the OpenBMC server post the content of
|
|
`install_ca.json` with this command:
|
|
|
|
Where `${bmc}` should be `bmc.example.com`. It is convenient to export it as an
|
|
environment variable.
|
|
|
|
```
|
|
curl --user root:0penBmc -d @install_ca.json -k -H "Content-Type: application/json" -X POST https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates
|
|
|
|
```
|
|
|
|
Credentials `root:0penBmc` can be replaced with any system user name and
|
|
password of your choice but with proper access rights to resources used here.
|
|
|
|
After successful certificate installation you should get positive HTTP response
|
|
and a new certificate should be available under this resource collection.
|
|
|
|
```
|
|
curl --user root:0penBmc -k https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates
|
|
|
|
```
|
|
|
|
An auto-generated self-signed server certificate is already present on OpenBMC
|
|
by default. To use the certificate signed by our CA it must be replaced.
|
|
Additionally we must upload to OpenBMC the private key that was used to sign the
|
|
server certificate. A proper message mody can be prepared the with this command:
|
|
|
|
```
|
|
cat << END > replace_cert.json
|
|
{
|
|
"CertificateString":"$(cat server-key.pem server-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')",
|
|
"CertificateUri":
|
|
{
|
|
"@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1"
|
|
},
|
|
"CertificateType": "PEM"
|
|
}
|
|
END
|
|
```
|
|
|
|
To replace the server certificate on the OpenBMC server post the content of
|
|
`replace_cert.json` with this command:
|
|
|
|
```
|
|
curl --user root:0penBmc -d @replace_cert.json -k -H "Content-Type: application/json" -X POST https://${bmc}/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/
|
|
|
|
```
|
|
|
|
## Enable TLS authentication
|
|
|
|
To check current state of the TLS authentication method use this command:
|
|
|
|
```
|
|
curl --user root:0penBmc -k https://${bmc}/redfish/v1/AccountService
|
|
```
|
|
|
|
and verify that the attribute `Oem->OpenBMC->AuthMethods->TLS` is set to true.
|
|
|
|
To enable TLS authentication use this command:
|
|
|
|
```
|
|
curl --user root:0penBmc -k -X PATCH -H "Content-Type: application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": true} } } }' https://${bmc}/redfish/v1/AccountService
|
|
```
|
|
|
|
To disable TLS authentication use this command:
|
|
|
|
```
|
|
curl --user root:0penBmc -k -X PATCH -H "Content-Type: application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": false} } } }' https://${bmc}/redfish/v1/AccountService
|
|
```
|
|
|
|
Other authentication methods like basic authentication can be enabled or
|
|
disabled as well using the same mechanism. All supported authentication methods
|
|
are available under attribute `Oem->OpenBMC->AuthMethods` of the
|
|
`/redfish/v1/AccountService` resource.
|
|
|
|
## Using TLS to access OpenBMC resources
|
|
|
|
If TLS is enabled, valid CA certificate was uploaded and the server certificate
|
|
was replaced it should be possible to execute curl requests using only client
|
|
certificate, key, and CA like below.
|
|
|
|
```
|
|
curl --cert client-cert.pem --key client-key.pem -vvv --cacert CA-cert.pem https://${bmc}/redfish/v1/SessionService/Sessions
|
|
```
|
|
|
|
## Common mistakes during TLS configuration
|
|
|
|
- Invalid date and time on OpenBMC,
|
|
|
|
- Testing Redfish resources, like `https://${bmc}/redfish/v1` which are always
|
|
available without any authentication will always result with success, even
|
|
when TLS is disabled or certificates are invalid.
|
|
|
|
- Certificates do not meet the requirements. See paragraphs
|
|
[Verify certificates](#Verify-certificates).
|
|
|
|
- Attempting to load the same certificate twice will end up with an error.
|
|
|
|
- Not having phosphor-bmcweb-cert-config in the build.
|