Here I've consolidated what is useful for my purposes from the excellent OpenSSL Cookbook by Ivan Ristić.

Read: There is a hell of a lot more to the book than what is covered here.

My primary interest in this post is creating CSRs for websites, to be fulfilled by a commercial CA.

Preparation

Ensure OpenSSL is installed.

# Ubuntu
$ sudo apt install openssl

# CentOS
$ sudo yum install openssl

Generate Private Key

# Generate the private key
$ openssl genrsa -aes128 -out mitol.key 2048

# Output
Generating RSA private key, 2048 bit long modulus (2 primes)
........+++++
....................................................................+++++
e is 65537 (0x010001)
Enter pass phrase for mitol.key:
Verifying - Enter pass phrase for mitol.key:

# You can check the key structure with:
$ openssl rsa -text -in mitol.key

The breakdown

Option Description
genrsa RSA (as in genrsa is the key algorithm) is typically used for web servers, which is my primary focus.
-aes128 Specifies the encryption used to protect the key using the supplied passphrase
-out Defines the file to write the key to.
2048 Defines the key size. 2048 is considered secure at the time of writing. Once upon a time 512 was considered secure, and it is absolutely not any more, so this is a constantly evolving beast.
passphrase Used to encrypt the key. You are prompted for the passphrase when the command is run/ It is optional but recommended. Doesn't make the certificate more secure, but secures the certificate when it is not in use on a system.

Create CSR

# Generate single domain CSR
$ openssl req -new -SHA256 -key mitol.key -out mitol.csr

# Output
Enter pass phrase for mitol.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:QLD
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MITOL
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:www.musingitoutloud.com
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

The breakdown

Option Description
req Specifies that we are creating or processing a certificate request.
-new Specifies the action is a new request.
-SHA256 Defines the message digest for the certificate signature algorithm.
-key Specifies the private key to use for the request.
-out Defines the file to write the CSR to.
challenge password

Verify CSR

# Check validity of standard CSR
$ openssl req -text -in mitol.csr -noout

# Output
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = AU, ST = QLD, L = Brisbane, O = MITOL, CN = www.musingitoutloud.com, emailAddress = [email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c2:97:e2:c1:93:10:8d:5f:16:27:cd:1a:c0:75:
                    3a:e7:00:53:de:d2:91:16:93:68:d3:d9:df:82:85:
                    65:65:3e:e6:a4:b1:08:bc:08:ae:11:ac:df:53:a3:
                    90:af:f6:47:44:98:1c:c8:79:ed:5d:0b:70:c7:b3:
                    1b:9c:01:95:58:b0:a8:72:01:13:1d:b3:78:c5:e4:
                    8d:f2:08:14:4f:13:ba:98:ed:98:64:c2:c4:48:44:
                    f1:d3:96:7c:61:a7:49:52:54:9c:98:eb:e7:60:03:
                    93:27:bb:d2:bc:a2:e6:be:86:08:c6:c8:ca:70:8a:
                    4f:fe:c7:b2:cc:a2:7b:05:5b:00:cc:dd:4f:ff:c4:
                    f7:01:a7:99:5e:e8:00:6a:82:17:17:63:79:5c:bd:
                    cd:55:1f:9f:55:2e:69:ea:61:06:e3:ba:8c:0f:8c:
                    0e:3d:b0:ba:3a:e6:6a:2d:15:b0:b0:e2:0a:be:1c:
                    d6:ca:a9:64:55:c0:e1:bc:5c:ab:00:33:22:e0:4e:
                    86:e0:be:4e:1f:e6:ec:92:94:89:1f:20:f9:fd:c3:
                    cb:90:39:20:16:39:a6:45:5d:11:0c:d0:ab:5f:1c:
                    28:4f:9d:01:5b:d9:9d:dd:07:21:83:53:8c:68:78:
                    92:9b:5c:8e:25:b2:4c:12:e7:cf:3b:cb:c4:5a:f5:
                    aa:11
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         07:dc:f1:0c:fc:b2:04:31:42:3d:10:4f:c4:85:5f:a2:7d:a9:
         e2:67:18:b3:04:5c:02:fc:4a:8a:f9:c3:fd:ef:0b:68:12:44:
         80:65:44:af:3c:9b:b5:c6:f7:25:e0:10:92:f8:7f:88:24:70:
         62:83:ad:2f:03:6a:9e:6b:92:ea:3d:37:e0:b1:9b:ec:a5:92:
         4d:f4:7f:04:74:2c:b0:50:12:4f:04:dc:fa:8f:6b:01:56:03:
         2c:fe:6e:00:17:84:d0:db:e9:cf:5b:07:16:81:c8:89:48:23:
         72:cd:a7:7a:04:33:13:35:f1:0b:54:36:91:8d:9f:ad:76:60:
         2d:f4:07:23:3a:6c:38:a3:6d:2e:f8:02:7d:60:10:dd:70:83:
         2f:1a:56:20:2b:6a:eb:c4:ba:83:1f:e0:78:83:6c:cd:6d:74:
         fb:21:b8:84:23:2f:4f:b4:0f:ff:78:05:22:17:7b:a0:b5:e7:
         fe:74:08:d6:7c:6f:1f:d6:47:f7:89:25:04:43:75:ce:56:37:
         dc:64:56:d2:a8:91:02:4f:99:1d:2b:e5:7e:27:6c:b1:76:be:
         a6:ef:86:a1:0d:2f:31:87:2f:42:5f:34:ce:0d:8e:99:f2:86:
         d4:a0:48:8a:86:d9:ad:05:9a:12:83:28:d1:cb:75:7a:7d:a9:
         3c:c0:9e:65

The breakdown

Option Description
req Specifies that we are creating or processing a certificate request.
-text Specifies we want to print the csr contents.
-key Specifies the CSR to use for the request.
-noout Specifies to not display the encoded certificate at the end of the output.

Generate CSR Configuration File

[req]
prompt = no
default_md = SHA256
default_bits = 2048
distinguished_name = DN
req_extensions = Extensions
input_password = PRIVATE_KEY_PASSPHRASE

[DN]
countryName            = "AU"                           # C=
stateOrProvinceName    = "Queensland"                   # ST=
localityName           = "Brisbane"                     # L=
organizationName       = "MITOL"                        # O=
commonName             = "www.musingitoutloud.com"      # CN=
emailAddress           = "[email protected]"    

[Extensions]
subjectAltName = DNS:www.musingitoutloud.com,DNS:musingitoutloud.com,DNS:pihole.musingitoutloud.com
Option Description
prompt Specifies whether to prompt for input. If you don't include the passphrase in the config file, you will be prompted for it regardless of this setting (OpenSSL 1.1.1 on Ubuntu 18.10 ).
default_md Defines the message digest for the certificate signature algorithm.
default_bits Defines the key size. 2048 is considered secure at the time of writing. Once upon a time 512 was considered secure, and it is absolutely not any more, so this is a constantly evolving beast.
distinguished_name Used to reference the [DN] section of the file, which contains answers to questions asked in interactive mode. This doesn't have to be DN, as long as this setting and the heading below match.
req_extensions As with DN, used to reference the Extensions section of the file. Same rules as DN, names need to match.
input_password Password used to encrypt the key (if required.)
[DN] Contains answers to questions asked during the interactive mode.
subjectAltName Used to define multiple hostnames. If only a single domain is required, this can be omitted as commonName in DN will be used.

Note: When a certificate contains alternative names, all common names are ignored. Newer certificates produced by CAs may not even include any common names. For that reason, include all desired hostnames on the alternative names list.

# Create the CSR from the configuration file
$ openssl req -new -config mitol.cnf -key mitol.key -out mitol.csr

# Check validity of SAN CSR (Same as the above validity check.)
$ openssl req -text -in mitol.csr -noout

# Output
openssl req -text -in mitol.csr -noout
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = AU, ST = Queensland, L = Brisbane, O = MITOL, CN = www.musingitoutloud.com, emailAddress = [email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c2:97:e2:c1:93:10:8d:5f:16:27:cd:1a:c0:75:
                    3a:e7:00:53:de:d2:91:16:93:68:d3:d9:df:82:85:
                    65:65:3e:e6:a4:b1:08:bc:08:ae:11:ac:df:53:a3:
                    90:af:f6:47:44:98:1c:c8:79:ed:5d:0b:70:c7:b3:
                    1b:9c:01:95:58:b0:a8:72:01:13:1d:b3:78:c5:e4:
                    8d:f2:08:14:4f:13:ba:98:ed:98:64:c2:c4:48:44:
                    f1:d3:96:7c:61:a7:49:52:54:9c:98:eb:e7:60:03:
                    93:27:bb:d2:bc:a2:e6:be:86:08:c6:c8:ca:70:8a:
                    4f:fe:c7:b2:cc:a2:7b:05:5b:00:cc:dd:4f:ff:c4:
                    f7:01:a7:99:5e:e8:00:6a:82:17:17:63:79:5c:bd:
                    cd:55:1f:9f:55:2e:69:ea:61:06:e3:ba:8c:0f:8c:
                    0e:3d:b0:ba:3a:e6:6a:2d:15:b0:b0:e2:0a:be:1c:
                    d6:ca:a9:64:55:c0:e1:bc:5c:ab:00:33:22:e0:4e:
                    86:e0:be:4e:1f:e6:ec:92:94:89:1f:20:f9:fd:c3:
                    cb:90:39:20:16:39:a6:45:5d:11:0c:d0:ab:5f:1c:
                    28:4f:9d:01:5b:d9:9d:dd:07:21:83:53:8c:68:78:
                    92:9b:5c:8e:25:b2:4c:12:e7:cf:3b:cb:c4:5a:f5:
                    aa:11
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:www.musingitoutloud.com, DNS:musingitoutloud.com, DNS:pihole.musingitoutloud.com
    Signature Algorithm: sha256WithRSAEncryption
         79:a9:f0:40:c8:b6:10:3d:0a:c5:f3:3f:fc:7e:b4:9c:d4:e4:
         0e:53:a8:33:92:63:39:92:57:3f:c4:fb:43:d2:1c:fc:87:f4:
         d3:2a:1b:f7:ea:7e:3f:8f:91:bb:b1:40:55:69:31:7b:b0:c9:
         0a:e8:7e:a9:ce:d7:e3:52:0c:8e:75:ac:b5:9e:4d:c0:fd:4d:
         ef:2a:5b:06:9e:c0:3d:b5:53:68:41:fe:b9:30:fa:76:5d:86:
         bf:86:21:15:28:f9:dc:32:17:41:27:1a:c6:36:b9:6d:30:3e:
         1b:f9:b8:4f:de:e8:d7:0a:8a:66:35:be:38:5c:fa:29:22:2c:
         b4:80:49:f0:cb:12:33:b1:77:28:12:e6:25:48:e7:58:80:8b:
         44:78:8a:bc:10:b0:da:d7:9b:87:cd:93:21:24:11:b5:b1:2e:
         ab:d0:88:8d:10:7d:90:b7:f2:29:6d:be:41:ab:02:1a:f2:80:
         69:87:ea:98:85:04:56:db:23:2a:bb:93:da:f4:72:81:c7:12:
         d3:4a:e8:17:c3:9f:a8:16:ef:9b:4a:40:5a:9c:ea:5c:8d:34:
         62:90:74:70:89:fd:b9:f9:79:3f:61:60:0d:fd:e3:a7:ec:69:
         1a:2f:3b:7c:39:ce:af:8b:3b:94:bf:cc:10:4c:bb:87:13:df:
         47:60:15:f6

The breakdown

Option Description
req Specifies that we are creating or processing a certificate request.
-new Specifies the action is a new request.
-config Specifies the config file to use.
-key Specifies the private key to use for the request.
-out Defines the file to write the CSR to.

Key & Certificate Conversion

PEM & DER

Logically quite easy to remember this syntax. You need to define the inbound format inform and file in and the corresponding outbound format outform and file out.

# PEM to DER
$ openssl x509 -inform PEM -in mitol.pem -outform DER -out mitol.der

# DER to PEM
$ openssl x509 -inform DER -in mitol.der -outform PEM -out mitol.pem
PEM & PFX (PKCS#12)
# PEM to PFX
$ openssl pkcs12 -export \
    -name "MITOL" \
    -out mitol.p12 \
    -inkey mitol.key \
    -in mitol.crt \
    -certfile chain.crt

# PFX to PEM
$ openssl pkcs12 -in fd.p12 -out fd.pem -nodes   

Note: This creates a single PEM file that needs to be separated into individual PEM files for the respective key, cert and chain components. There will be additional metadata to remove as well.

References

OpenSSL Cookbook by Ivan Ristić.
Official Docs