1# How to configure the server TLS certificates for authentication 2Author: 3 Zbigniew Kurzynski <zbigniew.kurzynski@intel.com> 4 5Created: 6 May 8, 2020 7 8Related documents: 9* [Redfish TLS User Authentication](https://github.com/openbmc/docs/blob/master/designs/redfish-tls-user-authentication.md) 10 11## Introduction 12With help of this guidebook you should be able to create both client and 13server certificates signed by a CA that can be used to authenticate user 14requests to an OpenBMC server. You will also learn how to enable and test 15the OpenBMC TLS authentication. 16 17## Certificates 18For a certificate to be marked as valid, it (and every certificate in the 19chain) has to meet these conditions: 20 21* `KeyUsage` contains required purpose `digitalSignature` and `keyAgreement` 22(see rfc 3280 4.2.1.3) 23* `ExtendedKeyUsage` contains required purpose `clientAuth` for client 24certificate and `serverAuth` for server certificate (see rfc 3280 4.2.1.13) 25* public key meets minimal bit length requirement 26* certificate has to be in its validity period 27* `notBefore` and `notAfter` fields have to contain valid time 28* has to be properly signed by certificate authority 29* certificate is well-formed according to X.509 30* issuer name has to match CA's subject name for client certificate 31* issuer name has to match the fully qualified domain name of your OpenBMC 32host 33 34If you already have certificates you can skip to [Enable TLS authentication 35](#Enable-TLS-authentication) or go to [Verify certificates](#Verify-certificates) 36and check if they meet the above requirements. 37 38### Prepare configuration files 39 40To generate certificates with required parameters some modification must be 41made to the default openssl configuration file. 42 43First create a new folder named `ca` and create a configuration file using 44the default configuration as a template (we do not want to change the 45original one). The location of the configuration file may vary depending on 46the operating system. For Ubuntu it is usually `/usr/lib/ssl/openssl.cnf`, 47but can also can be at `/etc/ssl/openssl.cnf`. For Cygwin it might be 48`/etc/defaults/etc/pki/tls/openssl.cnf` or `/etc/pki/tls/openssl.cnf`. 49 50``` 51mkdir ~/ca 52cd ~/ca 53cp /usr/lib/ssl/openssl.cnf openssl-client.cnf 54``` 55 56Then open the client `~/ca/openssl-client.cnf` file in your favorite editor, 57for example `vi`. 58 59``` 60vi ~/ca/openssl-client.cnf 61``` 62 63Find the sections listed below and add or choose the presented values. 64 65``` 66[ req ] 67req_extensions = v3_req 68 69[ usr_cert ] 70extendedKeyUsage = clientAuth 71 72[ v3_req ] 73extendedKeyUsage = clientAuth 74keyUsage = digitalSignature, keyAgreement 75``` 76 77Now create a server configuration `openssl-server.cnf` by copying the client 78file 79 80``` 81cp ~/ca/openssl-client.cnf openssl-server.cnf 82``` 83 84and changing values presented in the sections listed below. 85 86``` 87[ usr_cert ] 88extendedKeyUsage = serverAuth 89 90[ v3_req ] 91extendedKeyUsage = serverAuth 92``` 93 94Create two additional configuration files `myext-client.cnf` and 95`myext-server.cnf` for the client and server certificates respectively. 96Without these files no extensions are added to the certificate. 97 98``` 99cat << END > myext-client.cnf 100[ my_ext_section ] 101keyUsage = digitalSignature, keyAgreement 102extendedKeyUsage = clientAuth 103authorityKeyIdentifier = keyid 104END 105``` 106``` 107cat << END > myext-server.cnf 108[ my_ext_section ] 109keyUsage = digitalSignature, keyAgreement 110extendedKeyUsage = serverAuth 111authorityKeyIdentifier = keyid 112END 113``` 114 115### Create a new CA certificate 116First we need to create a private key to sign the CA certificate. 117``` 118openssl genrsa -out CA-key.pem 2048 119``` 120 121Now we can create a CA certificate, using the previously generated key. 122You will be prompted for information which will be incorporated into the 123certificate, such as Country, City, Company Name, etc. 124 125``` 126openssl req -new -config openssl-client.cnf -key CA-key.pem -x509 -days 1000 -out CA-cert.pem 127``` 128 129### Create client certificate signed by given CA certificate 130To create a client certificate, a signing request must be created first. For 131this another private key will be needed. 132 133Generate a new key that will be used to sign the certificate signing request: 134``` 135openssl genrsa -out client-key.pem 2048 136``` 137Generate a certificate signing request. 138 139You will be prompted for the same information as during CA generation, but 140provide **the OpenBMC system user name** for the `CommonName` attribute of 141this certificate. In this example, use **root**. 142 143``` 144openssl req -new -config openssl-client.cnf -key client-key.pem -out signingReqClient.csr 145``` 146 147Sign the certificate using your `CA-cert.pem` certificate with following 148command: 149``` 150openssl 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 151``` 152The file `client-cert.pem` now contains a signed client certificate. 153 154### Create server certificate signed by given CA certificate 155For convenience we will use the same CA generated in paragraph [Create a new 156CA certificate](#Create-a-new-CA-certificate), although a different one could 157be used. 158 159Generate a new key that will be used to sign the server certificate signing 160request: 161``` 162openssl genrsa -out server-key.pem 2048 163``` 164Generate a certificate signing request. You will be prompted for the same 165information as during CA generation, but provide **the fully qualified 166domain name of your OpenBMC server** for the `CommonName` attribute of this 167certificate. In this example it will be `bmc.example.com`. A wildcard can 168be used to protect multiple host, for example a certificate configured for 169`*.example.com` will secure www.example.com, as well as mail.example.com, 170blog.example.com, and others. 171 172``` 173openssl req -new -config openssl-server.cnf -key server-key.pem -out signingReqServer.csr 174``` 175 176Sign the certificate using your `CA-cert.pem` certificate with following 177command: 178``` 179openssl 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 180``` 181The file `server-cert.pem` now contains a signed client certificate. 182 183### Verify certificates 184To verify the signing request and both certificates you can use following 185commands. 186 187``` 188openssl x509 -in CA-cert.pem -text -noout 189openssl x509 -in client-cert.pem -text -noout 190openssl x509 -in server-cert.pem -text -noout 191openssl req -in signingReqClient.csr -noout -text 192openssl req -in signingReqServer.csr -noout -text 193``` 194 195Below are example listings that you can compare with your results. Pay special 196attention to attributes like: 197 * Validity in both certificates, 198 * `Issuer` in `client-cert.pem`, it must match to `Subject` in `CA-cert.pem`, 199 * Section *X509v3 extensions* in `client-cert.pem` it should contain proper 200values, 201 * `Public-Key` length, it cannot be less than 2048 bits. 202 * `Subject` CN in `client-cert.pem`, it should match existing OpemBMC user 203name. 204In this example it is **root**. 205 * `Subject` CN in `server-cert.pem`, it should match OpemBMC host name. 206In this example it is **bmc.example.com **. (see rfc 3280 2074.2.1.11 for name constraints) 208 209Below are fragments of generated certificates that you can compare with. 210``` 211CA-cert.pem 212 Data: 213 Version: 3 (0x2) 214 Serial Number: 16242916899984461675 (0xe16a6edca3c34f6b) 215 Signature Algorithm: sha256WithRSAEncryption 216 Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA 217 Validity 218 Not Before: May 11 11:40:48 2020 GMT 219 Not After : Feb 5 11:40:48 2023 GMT 220 Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA 221 Subject Public Key Info: 222 Public Key Algorithm: rsaEncryption 223 Public-Key: (2048 bit) 224 Modulus: 225 00:d4:24:c1:1d:ac:85:8c:5b:42:e4:f8:a8:d8:7c: 226 ... 227 55:83:8b:aa:ac:ac:6e:e3:01:2b:ce:f7:ee:87:21: 228 f9:2b 229 Exponent: 65537 (0x10001) 230 X509v3 extensions: 231 X509v3 Subject Key Identifier: 232 ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE 233 X509v3 Authority Key Identifier: 234 keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE 235 236 X509v3 Basic Constraints: 237 CA:TRUE 238 Signature Algorithm: sha256WithRSAEncryption 239 cc:8b:61:6a:55:60:2b:26:55:9f:a6:0c:42:b0:47:d4:ec:e0: 240 ... 241 45:47:91:62:10:bd:3e:a8:da:98:33:65:cc:11:23:95:06:1b: 242 ee:d3:78:84 243``` 244``` 245client-cert.pem 246 Data: 247 Version: 3 (0x2) 248 Serial Number: 10150871893861973895 (0x8cdf2434b223bf87) 249 Signature Algorithm: sha256WithRSAEncryption 250 Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA 251 Validity 252 Not Before: May 11 11:42:58 2020 GMT 253 Not After : May 11 11:42:58 2021 GMT 254 Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=root 255 Subject Public Key Info: 256 Public Key Algorithm: rsaEncryption 257 Public-Key: (2048 bit) 258 Modulus: 259 00:cf:d6:d0:a2:09:62:df:e9:a9:b1:e1:3d:7f:2f: 260 ... 261 30:7b:48:dc:c5:2c:3f:a9:c0:d1:b6:04:d4:1a:c8: 262 8a:51 263 Exponent: 65537 (0x10001) 264 X509v3 extensions: 265 X509v3 Key Usage: 266 Digital Signature, Key Agreement 267 X509v3 Extended Key Usage: 268 TLS Web Client Authentication 269 X509v3 Authority Key Identifier: 270 keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE 271 272 Signature Algorithm: sha256WithRSAEncryption 273 7f:a4:57:f5:97:48:2a:c4:8e:d3:ef:d8:a1:c9:65:1b:20:fd: 274 ... 275 25:cb:5e:0a:37:fb:a1:ab:b0:c4:62:fe:51:d3:1c:1b:fb:11: 276 56:57:4c:6a 277``` 278``` 279server-cert.pem 280 Data: 281 Version: 3 (0x2) 282 Serial Number: 10622848005881387807 (0x936beffaa586db1f) 283 Signature Algorithm: sha256WithRSAEncryption 284 Issuer: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com 285 Validity 286 Not Before: May 22 13:46:02 2020 GMT 287 Not After : May 22 13:46:02 2021 GMT 288 Subject: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com 289 Subject Public Key Info: 290 Public Key Algorithm: rsaEncryption 291 Public-Key: (2048 bit) 292 Modulus: 293 00:d9:34:9c:da:83:c6:eb:af:8f:e8:11:56:2a:59: 294 ... 295 92:60:09:fc:f9:66:82:d0:27:03:44:2f:9d:6d:c0: 296 a5:6d 297 Exponent: 65537 (0x10001) 298 X509v3 extensions: 299 X509v3 Key Usage: 300 Digital Signature, Key Agreement 301 X509v3 Extended Key Usage: 302 TLS Web Server Authentication 303 X509v3 Authority Key Identifier: 304 keyid:5B:1D:0E:76:CC:54:B8:BF:AE:46:10:43:6F:79:0B:CA:14:5C:E0:90 305 306 Signature Algorithm: sha256WithRSAEncryption 307 bf:41:e2:2f:87:44:25:d8:54:9c:4e:dc:cc:b3:f9:af:5a:a3: 308 ... 309 ef:0f:90:a6 310 311``` 312 313## Installing CA certificate on OpenBMC 314 315The CA certificate can be installed via Redfish Service. The file `CA-cert.pem` 316can not be uploaded directly but must be sent embedded in a valid JSON 317string, which requires `\`, `"`, and control characters must be escaped. 318This means all content is placed in a single string on a single line by 319encoding the line endings as `\n`. The command below prepares a whole POST 320body and puts it into a file named: `install_ca.json`. 321 322``` 323cat << END > install_ca.json 324{ 325 "CertificateString":"$(cat CA-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')", 326 "CertificateType": "PEM" 327} 328END 329``` 330 331To install the CA certificate on the OpenBMC server post the content of 332`install_ca.json` with this command: 333 334Where `${bmc}` should be `bmc.example.com`. It is convenient to export it 335as an environment variable. 336 337``` 338curl --user root:0penBmc -d @install_ca.json -k -X POST https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates 339 340``` 341 342Credentials `root:0penBmc` can be replaced with any system user name and 343password of your choice but with proper access rights to resources used here. 344 345 346After successful certificate installation you should get positive HTTP 347response and a new certificate should be available under this resource 348collection. 349``` 350curl --user root:0penBmc -k https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates 351 352``` 353 354An auto-generated self-signed server certificate is already present on 355OpenBMC by default. To use the certificate signed by our CA it must be 356replaced. Additionally we must upload to OpenBMC the private key that was 357used to sign the server certificate. A proper message mody can be prepared 358the with this command: 359 360``` 361cat << END > replace_cert.json 362{ 363 "CertificateString":"$(cat server-key.pem server-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')", 364 "CertificateUri": 365 { 366 "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1" 367 }, 368 "CertificateType": "PEM" 369} 370END 371``` 372 373To replace the server certificate on the OpenBMC server post the content of 374`replace_cert.json` with this command: 375 376``` 377curl --user root:0penBmc -d @replace_cert.json -k -X POST https://${bmc}/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/ 378 379``` 380 381## Enable TLS authentication 382 383To check current state of the TLS authentication method use this command: 384 385``` 386curl --user root:0penBmc -k https://${bmc}/redfish/v1/AccountService 387``` 388and verify that the attribute `Oem->OpenBMC->AuthMethods->TLS` is set to true. 389 390To enable TLS authentication use this command: 391 392``` 393curl --user root:0penBmc -k -X PATCH -H "ContentType:application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": true} } } }' https://${bmc}/redfish/v1/AccountService 394``` 395 396To disable TLS authentication use this command: 397 398``` 399curl --user root:0penBmc -k -X PATCH -H "ContentType:application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": false} } } }' https://${bmc}/redfish/v1/AccountService 400``` 401 402Other authentication methods like basic authentication can be enabled or 403disabled as well using the same mechanism. All supported authentication 404methods are available under attribute `Oem->OpenBMC->AuthMethods` of the 405`/redfish/v1/AccountService` resource. 406 407## Using TLS to access OpenBMC resources 408 409If TLS is enabled, valid CA certificate was uploaded and the server 410certificate was replaced it should be possible to execute curl requests 411using only client certificate, key, and CA like below. 412 413``` 414curl --cert client-cert.pem --key client-key.pem -vvv --cacert CA-cert.pem https://${bmc}/redfish/v1/SessionService/Sessions 415``` 416## Common mistakes during TLS configuration 417 418* Invalid date and time on OpenBMC, 419 420* Testing Redfish resources, like `https://${bmc}/redfish/v1` which are 421always available without any authentication will always result with success, 422even when TLS is disabled or certificates are invalid. 423 424* Certificates do not meet the requirements. See paragraphs 425[Verify certificates](#Verify-certificates). 426 427* Attempting to load the same certificate twice will end up with an error. 428 429* Not having phosphor-bmcweb-cert-config in the build. 430