software:openssl:internalca:createcert
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| software:openssl:internalca:createcert [2025/10/25 03:08] – removed - external edit (Unknown date) 127.0.0.1 | software:openssl:internalca:createcert [2025/10/25 03:11] (current) – ↷ Links adapted because of a move operation rodolico | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Create Service Certificate ====== | ||
| + | I use the term //" | ||
| + | |||
| + | On our workstations, | ||
| + | |||
| + | Doing this requires building a certificate, | ||
| + | |||
| + | ===== Creating the Certificate ===== | ||
| + | |||
| + | Creating the certificate is similar to creating a CA: We create a key file, then turn it into a certificate. The difference is, as an intermediate step, we create a CSR (Certificate Request) which uses the key, then we use that to create and sign the certificate with the CA. The basic functionality is shown in the following four steps. | ||
| + | |||
| + | - Create an EXT (extension) file containing the names which the service will be called by. | ||
| + | - Generate a private key | ||
| + | - Create a signing request | ||
| + | - Generate the certificate and sign them with the CA | ||
| + | |||
| + | That first step, creating the extension file, is useful for repeated tasks. It is basically an openssl.cnf file, with some additional information (and, ignoring some CA specific information). Since I'm lazy, I simply copy the openssl.cnf file to a new file name, modify it, then I'm ready to go. | ||
| + | |||
| + | We'll take each one in turn, then I'll show you a simple script that can automate the process. | ||
| + | |||
| + | ==== Create EXT file ==== | ||
| + | |||
| + | The EXT file defines how to create the cert and what services it is valid for. You can have one or more names which the certificate is valid for. For example, if a web server can be called as web.example.local, | ||
| + | |||
| + | An EXT file is a lot like a openssl.cnf file, but with some additional stanzas. To simplify things, I tend to copy the openssl.cnf file to a new file name, then add/modify the additional stanzas, then use that new file file for both. | ||
| + | |||
| + | Here is an example of an ext file which has been merged with an openssl.cnf file to allow it to be used for both functions. | ||
| + | |||
| + | <code conf www.example.local.ext> | ||
| + | [ req ] | ||
| + | default_bits | ||
| + | default_md | ||
| + | distinguished_name = req_distinguished_name # definition used for DN | ||
| + | req_extensions | ||
| + | prompt | ||
| + | |||
| + | [ req_distinguished_name ] | ||
| + | # Required field, must be different for each certificate | ||
| + | # server and ca | ||
| + | CN = example.com | ||
| + | # not required | ||
| + | C = US | ||
| + | ST = Texas | ||
| + | O = Example Corp | ||
| + | L = Dallas | ||
| + | OU = Headquarters | ||
| + | emailAddress = info@example.com | ||
| + | |||
| + | [ v3_req ] | ||
| + | keyUsage | ||
| + | extendedKeyUsage | ||
| + | subjectAltName | ||
| + | basicConstraints | ||
| + | |||
| + | [ alt_names ] | ||
| + | DNS.1 = www.example.local | ||
| + | DNS.2 = example.local | ||
| + | DNS.3 = mail.example.local | ||
| + | IP.1 = 192.168.1.1 | ||
| + | </ | ||
| + | |||
| + | This is basically the openssl.cnf file, with the addition of the // | ||
| + | |||
| + | In the // | ||
| + | |||
| + | Finally, we give it // | ||
| + | |||
| + | In the alt_names, we list on or more names which the service may be called as, using the form | ||
| + | DNS=URL | ||
| + | |||
| + | openssl configuration files can not list the same key more than once, we modify it slightly by adding arbitrary text after a period. openssl will ignore anything between the period and the equals sign except to allow them to coexist in the same configuration file, so we just list them as | ||
| + | DNS.1=name | ||
| + | DNS.2=alias | ||
| + | DNS.3=another alias | ||
| + | |||
| + | **Note**: For an IP address, use **IP** instead of **DNS** for correctness, | ||
| + | |||
| + | This is used when we build a Certificate Request and then integrated as alternate names in the subject for the DN. | ||
| + | |||
| + | I save this file as name (the primary name of the service) with an extension of .ext, so each service (server) will have a different file, which can be reused to recreate the Server Certificate. | ||
| + | |||
| + | ==== Generate Private Key ==== | ||
| + | |||
| + | Private key generation is the same as it was for the CA, except we do not want a password in most cases. If we have a password, it would require you to enter the password every time a service was restarted. | ||
| + | |||
| + | Here, we're creating a private key named www.example.internal.key. This allows us to know which key this is for. Also note we did not include the -des3. Leaving off the encryption algorithm tells genpkey that we don't want to encrypt the key. | ||
| + | |||
| + | <code bash> | ||
| + | openssl | ||
| + | | ||
| + | | ||
| + | -out servername.key \ | ||
| + | | ||
| + | </ | ||
| + | |||
| + | here, replace // | ||
| + | |||
| + | Here is a breakdown of the parameters: | ||
| + | * //genpkey// - openssl has multiple functions. This says you want to generate a private key. Notice there is no dash before the command. | ||
| + | * // | ||
| + | * //-out// - followed by the file name to put the private key in. If not specified, will send output to STDOUT. I use .key as the suffix | ||
| + | * // | ||
| + | |||
| + | **Note**: unlike when we created the CA, we did not use the -des3 in this. If you put a passphrase on the key, you will need to manually start each server as the passphrase will be required to open the key (necessary for the certificate, | ||
| + | |||
| + | ==== Create CSR (Request) ==== | ||
| + | Creating a Certificate Signing Request is simpler since we have the configuration file created earlier. Basically, we call openssl with the req flag and tell it what to do. | ||
| + | |||
| + | A server signing request is simply that. We are asking openssl to create a request from the service to create a certificate, | ||
| + | |||
| + | <code bash> | ||
| + | openssl \ | ||
| + | req \ | ||
| + | -new \ | ||
| + | -key servername.key \ | ||
| + | -out servername.csr \ | ||
| + | | ||
| + | </ | ||
| + | |||
| + | You can almost read this in english. Create a new (-new) signing request (req) using the key // | ||
| + | |||
| + | ==== Generate Certificate and sign ==== | ||
| + | |||
| + | The certificate file is what all of this is about. We generate it using the Signing Request (csr), signing with the key. | ||
| + | |||
| + | <code bash> | ||
| + | openssl \ | ||
| + | x509 \ | ||
| + | -req \ | ||
| + | -in servername.csr \ | ||
| + | -CA CAName.crt \ | ||
| + | | ||
| + | -out servername.crt \ | ||
| + | -days 365 \ | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | The parameters here are: | ||
| + | //x509// - tells openssl we are creating a certificate from a CSR | ||
| + | //-req// - normally, this command expects the certificate passed in on input. This option says "use the csr instead" | ||
| + | //-in// - give it the name of the CSR we are using | ||
| + | //CA// - The CA Certificate we are signing this with | ||
| + | //-CAkey// - the name of the CA's key file. Note that we have to unlock the key during processing, so the passpharse for the key will be requested. | ||
| + | //-out// - name of the certificate to be created. We just use servername.crt, | ||
| + | //-days// - number of days the certifcate is valid for. The expire date is calculated from the date you create it (when you type the command) plus this value. Note that some programs will not accept certificates with this value set too high, so 365 days is about the max (letsencrypt is set for 90 days by default, I believe). | ||
| + | // | ||
| + | |||
| + | **Note**: you can use the parameters // | ||
| + | |||
| + | |||
| + | ===== Deploy Certificate and Key ===== | ||
| + | |||
| + | You have created the certificate, | ||
