A simple Docker image to create certificate requests for web servers
- (Optional) Build:
docker build -t gunet/cert-req:latest .
- (Typical) Run:
docker run --rm -e ORG=<ORG> -e SERVER=<hostname> -v $PWD/certs:/var/cert-req/certs gunet/cert-req <argument>
- Example:
docker run --rm -e ORG=sch.gr -e SERVER=sso-01-test.sch.gr -v $PWD/certs:/var/cert-req/certs gunet/cert-req create
- If we want to pass the passphrase in stdin then we need to add the
-it
option. - Files (certificates, private keys, CSRs etc) will be in folder
$PWD/certs
- Possible arguments
create
: Create a new private key and server.csrprint
: Print CSRrenew
: Regenerate the CSR reusing the same keyencrypt
: Encrypt the private key with a pass phrasedecrypt
: Remove the passphrase from an encrypted keyencrypt-file
: Encrypt the file provided in theFILE
environment variable with thePASSPHRASE
(or we will request it) with symmetrical encryption. The resulting file will get a.aes
extensiondecrypt-file
: Decrypt the file with symmetrical encryption. For the output file we remove the.aes
extension. If it does not exist, we fail.self-sign
: Create a new private key and CSR and self-sign the certificate.self-sign-ca
: Create a CA, a private key and CSR and self-sign a certificate. Thecerts/
folder will include the CSR and private key.resign-ca
: Re-sign the server certificate using the existing CA.dh
: Create adh.pem
DH parameters file
- Passphrase:
- Generally, the passphrase will be requested.
- If an environment variable called
PASSPHRASE
is present then that will be used - If the environment variable is present and the command is
self-sign
orself-sign-ca
then we will use it to encrypt the private key as well.
- Filenames:
- Certificate:
server.crt
- CSR:
server.csr
- Private key (no passphrase):
privkey.pem
- Private key (encrypted with passphrase):
privkey.key
- Certificate:
- Build:
docker-compose build
- Run:
docker-compose run -e ORG=<ORG> -e SERVER=<hostname> --rm cert-req <command>
- CSR and private key will be in $PWD/certs
ORG
: Organization (ieGUNET
)SERVER
: The server DNS namePASSPHRASE
: The passphrase to use when encryting/decrypting. If it is not passed as an environment variable, it will be requested (you need to pass-it
option in this case)SUBJALTNAMES
: A comma separated list of subAltNames to be included in the certificate request/self-signed certificate.FILE
: The (absolute) path (in the container context) for a file to be encrypted or decrypted
- gunet/cert-req: 82.5MB
- debian:bullseye-slm: 80.5MB
- Create certificate request with new key:
openssl req -new -newkey rsa:4096 -nodes -keyout privkey.pem -out server.csr -config server.cnf -batch
- Create a self-signed certificate with new key:
openssl req -x509 -newkey rsa:4096 -nodes -keyout privkey.pem -out server.csr -config server.cnd -sha256 -days 7300 -batch
- Self-sign a certificate using an already existing CSR and private key:
openssl req -x509 -in server.csr -config server.cnf -key privkey.pem -out server.crt -days 7300 -sha256 -batch
- Renew certificate request reusing key:
openssl req -new -key certs/privkey.pem -out certs/server.csr -config server.cnf -batch
- Print CSR:
openssl req -text -noout -verify -in certs/server.csr
- Check if a private key is encrypted or not:
openssl rsa -text -noout -in <name of key>.key
- Encrypt a private key or change the passphrase:
openssl rsa -aes256 -passout PASS -in <unencrypted name> -out <encrypted name>
- Note: Some algorithms like
des
are not supported by default by OpenSSLv3.0
and should not be used
- Note: Some algorithms like
- Remove the passphrase:
openssl rsa -in <encrypted name> -out <unencrypted name>
- Remove the passphrase (passing the passphrase):
openssl rsa -passin PASS -in <encrypted named> -out <unencrypted name>
- It is usually recommended to have the unencrypted private key end in
.pem
and the encrypted in.key
- Symmetrical encryption on a file (passphrase in env variable):
- Encrypt:
openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -pass PASS -in <unencrypted> -out <encrypted>
- Decrypt:
openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -d -pass PASS -in <encrypted> -out <unencrypted>
- Encrypt:
PASS
can be one of:pass:${PASS}
: A text passphraseenv:PASS
: The passphrase will take the value of the environment variablePASS
- Create a DH params file (4096 bits length):
openssl dhparam -out certs/dh.pem 4096
- Print certificate:
openssl x509 -text -in server.crt
- Print a certificate which is stored in DER format (usually certificates taken from an
Authority Information Access
endpoint):openssl x509 -text -inform der -in <cert-file>
- Print certificate chain:
openssl crl2pkcs7 -nocrl -certfile server.crt | openssl pkcs7 -print_certs -noout
- Print md5 checksums:
- For certificate:
openssl x509 -noout -modulus -in server.crt| openssl md5
- For key:
openssl rsa -noout -modulus -in privkey.pem| openssl md5
- For CSR:
openssl req -noout -modulus -in server.csr| openssl md5
- For certificate:
- Expiration:
- Show expiration:
openssl x509 -noout -enddate -in server.crt
- Show all dates:
openssl x509 -noout -dates -in server.crt
- Check expiration:
openssl x509 -noout -checkend <seconds> -in server.crt
- Show expiration:
- crt.sh is a tool to check/download Sectigo certificates online
- Return a JSON strcture with non-expired leaf certificates for a specific domain:
https://crt.sh/?Identity=<domaain>&exclude=expired&deduplicate=Y&output=json
- We can use
openssl s_client
to directly connect to a server and check the TLS protocol - The usual run is:
openssl s_client -connect <name>:443
- To quit just after TLS connection establishment:
time echo "Q" | openssl s_client -connect <name>:443 2>1 >/dev/null
- If we add the
-servername
argument then openssl also does SNI
- Use the
-quiet
and the-crlf
options - Example:
# openssl s_client -connect sso.asfa.gr:443 -quiet -crlf
GET /login HTTP/1.1
Host: sso.asfa.gr
- Reference
- Connect to an SMTP server with StartTLS:
openssl s_client -quiet -connect relay.grnet.gr:587 -starttls smtp
- The
-quiet
flag is important in order to be able to issue capitalized SMTP commands with no problem. - Total test:
# openssl s_client -quiet -connect relay.grnet.gr:587 -starttls smtp
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = NL, O = GEANT Vereniging, CN = GEANT OV RSA CA 4
verify return:1
depth=0 C = GR, ST = Attik\C3\AD, O = National Infrastructures for Research and Technology, CN = relay.grnet.gr
verify return:1
250 HELP
MAIL FROM: <kkalev@noc.ntua.gr>
250 OK
RCPT TO: <kkalev@gunet.gr>
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: Test
test
.
250 OK id=1q6SbR-0007fb-Tr
QUIT
221 relay.grnet.gr closing connection
- Test SMTP auth:
# echo -n "username" | base64
dXNlcm5hbWU=
# echo -n "password" | base64
cGFzc3dvcmQ=
(cut)
250 8BITMIME
AUTH LOGIN
334 VXNlcm5hbWU6
dXNlcm5hbWU=
334 UGFzc3dvcmQ6
cGFzc3dvcmQ=
235 2.7.0 Authentication successful
- The
testssl.sh
can run a set of SSL/TLS tests against a server. A Docker image is available - The simpe run is
docker run --rm -ti drwetter/testssl.sh <host>[:<port>]
- OpenSSL also provides an option to time SSL connections for a server:
openssl s_time -connect <host>:<port>
- Reference: OpenVPN Cookbook 2nd edition, Chpt. 8
- Modern CPUs have the AES-NI instruction set which speeds up encryption
- You can run
openssl
speed test with:openssl speed -evp aes-256-gcm
to test theAES-256-GCM
cipher familyopenssl speed -evp aes-256-cbc
to test theAES-256-CBC
cipher family- Use the
OPENSSL_ia32cap=0
environment variable to disable theAES-NI
instruction set