SSL 與 CA

SSL 的全名是 Secure Sockets Layer,即安全通訊端層,簡而言之,這是一種標準的技術,用於保持網際網路連線安全以及防止在兩個系統之間發送的所有敏感資料被罪犯讀取及修改任何傳輸的資訊,包括潛在的個人詳細資料。兩個系統可以是伺服器與用戶端 (例如購物網站與瀏覽器),或者伺服器至伺服器 (例如,含有個人身份資訊或含有薪資資訊的應用程式)。

憑證伺服器 - Certificate Authority (CA),這個伺服器可以用來建立SSL加密連線所需的 Server 及 Root 憑證檔。

對於商用型網站的加密連線,通常會使用 Verisign 或其他第三方認證機構,來簽署需要的憑證檔,但這些需要定期付費,如果不想付費給這些機構做簽署,可以自己架設伺服器來建立及發行所需的憑證檔。

CA 可以使用 Linux 或 Windows 來架設,此篇將以 Linux 為案例,Windows 用戶可以安裝 Windows 元件:Certificate Service。

Resources

Let's Encrypt

Certbun - Certbot alternative

Test SSL

這些工具可以檢測 SSL 網站的所有資訊

Monitoring SSL

SSL Certificates

ACME (Automated Certificate Management Environment)

ACME 是一種通訊協定,由網際網路工程任務組(IETF)制定,目的是要自動化數位憑證的管理過程,包括憑證的申請、驗證、發行,以及之後的更新。由於數位憑證可以確保網站身份,並保護網站和用戶間的資訊交換,是網路安全非常重要的一環。傳統憑證申請和管理過程複雜且費時,ACME解決了這些麻煩,並使過程能夠自動化,因此也減少了管理成本,以及因憑證過期所產生的安全風險。

Certimate - 多憑證管理平台

Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决方案。

做个人产品或者在小企业里负责运维的同学,会遇到要管理多个域名的情况,需要给域名申请证书。但是手动申请证书有以下缺点:

Certimate 就是为了解决上述问题而产生的,它具有以下特点:

URLs:

SSL 常用技巧

Check TLS/SSL certificate expiration date

from a website)

# NOTE: openssl requires at least 1.1.1
SITE_URL="www.cloudcoin.global" 
SITE_SSL_PORT="443" 
## note echo added ## 
echo | openssl s_client -servername ${SITE_URL} -connect ${SITE_URL}:${SITE_SSL_PORT} \
| openssl x509 -noout -dates
# Alternaively
openssl s_client -connect ${SITE_URL}:${SITE_SSL_PORT} -servername ${SITE_URL} 2> /dev/null | openssl x509 -noout -dates

output

depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
verify return:1
depth=1 C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
verify return:1
depth=0 C = US, ST = CA, L = San Francisco, O = "Cloudflare, Inc.", CN = cloudcoin.global
verify return:1
DONE
notBefore=Jun  5 00:00:00 2020 GMT
notAfter=Jun  5 12:00:00 2021 GMT

from a PEM encoded certificate file)

openssl x509 -enddate -noout -in /etc/nginx/ssl/www.cyberciti.biz.fullchain.cer

# find out if the TLS/SSL certificate expires within next 7 days (604800 seconds):
openssl x509 -enddate -noout -in my.pem -checkend 604800

output

notAfter=Dec 29 23:48:42 2020 GMT

Shell script to alert sysadmin

#!/bin/bash
# Purpose: Alert sysadmin/developer about the TLS/SSL cert expiry date in advance
# Author: Vivek Gite {https://www.cyberciti.biz/} under GPL v2.x+
# -------------------------------------------------------------------------------
PEM="/etc/nginx/ssl/letsencrypt/cyberciti.biz/cyberciti.biz.fullchain.cer"
 
# 7 days in seconds 
DAYS="604800" 
 
# Email settings 
_sub="$PEM will expire within $DAYS (7 days)."
_from="system-account@your-dommain"
_to="sysadmin@your-domain"
_openssl="/usr/bin/openssl"
$_openssl x509 -enddate -noout -in "$PEM"  -checkend "$DAYS" | grep -q 'Certificate will expire'
 
# Send email and push message to my mobile
if [ $? -eq 0 ]
then
	echo "${_sub}"
        mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The TLS/SSL certificate ($PEM) will expire soon on $HOSTNAME [$(date)]"
        # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ #
        source ~/bin/cli_app.sh
        push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null
fi

With Python

Get the Server certificate from the website

NOTE: openssl requires at least 1.1.1

echo -n | openssl s_client -showcerts -servername some.web.site -connect some.web.site:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > some-web-site.pem

除了使用 openssl 以外,也可以用 Firefox 或 Chrome 手動下載 Server 憑證檔。

顯示憑證檔 *.crt, *.pem 的詳細資訊

憑證檔的內容是由兩字串 -----BEGIN CERTIFICATE----------END CERTIFICATE----- 所包含的亂數組合,要解析其中的憑證資訊,可以使用 openssl 工具:

openssl x509 -text -noout -in my_CA.pem  
Check the TLS version
nmap --script ssl-enum-ciphers -p 443 www.google.com

# -tls1 for TLSv1
# -tls1_1 for TLSv1.1
# -tls1_2 for TLSv1.2
openssl s_client -connect www.google.com:443 -tls1_3
Generate a CSR (Certificate Signing Request)
sudo apt install openssl  #[On Debian/Ubuntu]
sudo yum install openssl  #[On CentOS/RHEL]
sudo dnf install openssl  #[On Fedora]

openssl req -new -newkey rsa:2048 -nodes -keyout example.com.key -out example.com.csr
Show the Information of the certificate
openssl x509 -noout -text -in your.cer

# For the cert file that is generated by Windows
openssl x509 -noout -text -inform der -in win.cer
More commands
# Generating a Private Key
openssl genpkey -algorithm RSA -out private.key 

# Generating a Certificate Signing Request (CSR) 
openssl req -new -key private.key -out csr.csr

# Generating a Self-Signed Certificate
openssl req -new -x509 -key private.key -out certificate.crt -days 365

# Encrypting Files
openssl enc -aes256 -in sensitive.txt -out sensitive.enc

# Decrypting Files 
openssl enc -aes256 -d -in sensitive.enc -out sensitive.txt

# Converting Certificate Formats
openssl x509 -in certificate.crt -out certificate.pem

# Creating a Certificate Chain
cat intermediate.crt root.crt > chain.crt

# Signing a CSR with a CA
openssl x509 -req -in csr.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out certificate.crt -days 365

# Generating a Random Number
openssl rand -hex 16

# Checking CSR Details
openssl req -in csr.csr -noout -text

# Viewing Certificate Expiry
openssl x509 -enddate -noout -in certificate.crt

# Converting PFX to PEM
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.pem

# Creating a Password-Protected Private Key
openssl genpkey -algorithm RSA -aes256 -out private.key

# Testing SSLv2/v3 Protocol Support
openssl s_client -connect example[dot]com:443 -ssl2/-ssl3

# Extracting Public Key from Private Key
openssl rsa -in private.key -pubout -out public.key

# Encrypting and Decrypting Files with a Passphrase
# Encrypting File:
openssl enc -aes256 -salt -in sensitive.txt -out sensitive.enc
# Decrypting File:
openssl enc -aes256 -d -in sensitive.enc -out sensitive_decrypted.txt


SSL/TLS Web Server

Generate Certificates

Method 1: 不需要 CA 的憑證

mkdir /etc/apache2/certs
cd /etc/apache2/certs
openssl genrsa -out myhomepbx.key 2048
openssl req -new -key myhomepbx.key -out myhomepbx.csr
openssl x509 -req -days 3650 -in myhomepbx.csr -signkey myhomepbx.key -out myhomepbx.crt

Method 2: 需要 CA 的憑證

# generate CA
# organizationName = HomePBX 
# commName = HomePBX CA
# Enter PEM pass phrase: set new password that is used to sign the certicficate.
cd /etc/ssl/homepbxCA
openssl req -new -x509 -extensions v3_ca -keyout ca.key -out ca.crt -days 3650 

# prerequisites
# Edit the openssl.homepbx.cnf as required
cp /etc/ssl/openssl.conf ./openssl.homepbx.cnf
touch index.txt
echo '01' > serial
mkdir newcerts

# generate Server certificates
# organizationName = HomePBX (it must be the same as CA, otherwise it cannot be signed by the CA)
# commName = FQDN of website or *
# Enter PEM pass phrase: It's not required, enter to skip it if wanted.
openssl req -config openssl.homepbx.cnf -new -nodes -keyout server.key -out server.csr
openssl ca -config openssl.homepbx.cnf -days 3650 -in server.csr -out server.crt

# generate PKCS12 for client authentication
# NOTE: you can create PKCS12 file by either server certificate or CA certificate.
# Enter Export Password: set new pasword that is used for importing the PKCS12
openssl pkcs12 -export -clcerts -in ca.crt -inkey ca.key -out homepbx_2021y.p12
# Alternatively
openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out homepbx_2021y.p12

openssl.homepbx.cnf

...
[ CA_default ]

dir             = .             # Where everything is kept  <== Here
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several certs with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.

certificate     = $dir/ca.crt   # The CA certificate <== Here
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/ca.key# The private key  <== Here

x509_extensions = usr_cert              # The extensions to add to the cert
...