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