Bash 如何验证ECDSA和RSA证书
我将在中央Web服务器上运行AcmeTiny,以便为我的两个Nginx反向代理颁发证书。新创建的证书通过https发布,并可通过下载提供给反向代理 我希望Nginx服务器在用新证书替换旧证书之前检查新创建的证书。为此,我编写了以下bash脚本,它在每个Nginx服务器上运行。我想知道我是否遗漏了什么,或者你是否有改进的想法。还是有更好的方法来实现这一点Bash 如何验证ECDSA和RSA证书,bash,ssl,openssl,certificate,lets-encrypt,Bash,Ssl,Openssl,Certificate,Lets Encrypt,我将在中央Web服务器上运行AcmeTiny,以便为我的两个Nginx反向代理颁发证书。新创建的证书通过https发布,并可通过下载提供给反向代理 我希望Nginx服务器在用新证书替换旧证书之前检查新创建的证书。为此,我编写了以下bash脚本,它在每个Nginx服务器上运行。我想知道我是否遗漏了什么,或者你是否有改进的想法。还是有更好的方法来实现这一点 #!/bin/bash set -e # Commands for deriving the public keys: # openssl
#!/bin/bash
set -e
# Commands for deriving the public keys:
# openssl ec -in ecdsa.key -pubout > ecdsa_public_key.pem
# openssl rsa -in rsa.key -pubout > rsa_public_key.pem
curl -O https://example.org/ecdsa.pem
curl -O https://example.org/intermediate.pem
curl -O https://example.org/rsa.pem
# Are the certificates not expired?
# Have they (ecdsa.pem, rsa.pem) been recently issued (validity >= 80 days)?
openssl x509 -checkend 6912000 -noout -in intermediate.pem
openssl x509 -checkend 6912000 -noout -in ecdsa.pem
openssl x509 -checkend 6912000 -noout -in rsa.pem
# Do the private keys and certificates belong together?
openssl x509 -in ecdsa.pem -pubkey | \
sed -n '/-----BEGIN PUBLIC KEY-----/,/-----END PUBLIC KEY-----/p' | \
cmp - ecdsa_public_key.pem
openssl x509 -in rsa.pem -pubkey | \
sed -n '/-----BEGIN PUBLIC KEY-----/,/-----END PUBLIC KEY-----/p' | \
cmp - rsa_public_key.pem
# Is the certificate chain valid?
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt intermediate.pem
openssl verify -CAfile intermediate.pem ecdsa.pem
openssl verify -CAfile intermediate.pem rsa.pem
# Are the certificates issued for the correct domain names?
(openssl x509 -noout -subject -in ecdsa.pem | awk -F'CN=' '{print $2}' | \
awk -F'/' '{print $1}'; \
openssl x509 -noout -text -in ecdsa.pem | grep "^[[:space:]]*DNS:" | \
xargs | tr ' ' '\n' | grep ^DNS | sed 's/^DNS://' | sed 's/,$//')| \
sort | uniq | cmp - domains.txt
(openssl x509 -noout -subject -in rsa.pem | awk -F'CN=' '{print $2}' | \
awk -F'/' '{print $1}'; \
openssl x509 -noout -text -in rsa.pem | grep "^[[:space:]]*DNS:" | \
xargs | tr ' ' '\n' | grep ^DNS | sed 's/^DNS://' | sed 's/,$//')| \
sort | uniq | cmp - domains.txt
更新1:
正如我所说的,我想检查证书的各个方面,而不仅仅是证书链的有效性。它目前检查:
- 链的有效性
- 私钥和证书是否匹配
- 证书是否最近签发,需要更换旧证书
- 是否已为所需域名颁发证书
#!/bin/bash
set -e
# Execute the script:
# ( cd /path_to_workdir && \
# su - james -c "./check_cert.sh https://www.example.org intermediate.pem ecdsa.pem ecdsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
# su - james -c "./check_cert.sh https://www.example.org intermediate.pem rsa.pem rsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
# cat ecdsa.pem intermediate.pem > /etc/nginx/ssl/ecdsa_bundle.pem ) && \
# cat rsa.pem intermediate.pem > /etc/nginx/ssl/rsa_bundle.pem ) && \
# /etc/init.d/nginx reload
# Download URL, e.g. https://example.org
URL=$1
# Intermediate certificate of certificate chain
INTERMEDIATE=$2
# Issued certificate, e.g. ecdsa.pem
CERT=$3
# Public key derived from private key via:
# openssl ec -in ecdsa.key -pubout > ecdsa_pubkey.pem
# openssl rsa -in rsa.key -pubout > rsa_pubkey.pem
PUBKEY=$4
# ca-certificates file, e.g. /etc/ssl/certs/ca-certificates.crt
CACERTS=$5
# Domains that the cert should cover
DOMAINS=$6
# password-file.txt possible content:
# machine example.org login james password H3Llo
PASS=$7
# Download files if newer than local.
if [[ $(curl -s -O --netrc-file "$PASS" -w "%{http_code}" -z "$CERT" "$URL/$CERT") -eq 304 ]]; then
echo "No new certificate issued. Nothing to do!"
exit 1
fi
curl -s -O --netrc-file "$PASS" -z "$INTERMEDIATE" "$URL/$INTERMEDIATE"
# Is the certificate chain valid?
openssl verify -CAfile "$CACERTS" -untrusted "$INTERMEDIATE" "$CERT"
# Do the private keys and certificates belong together?
openssl x509 -in "$CERT" -pubkey | \
sed -n '/-----BEGIN PUBLIC KEY-----/,/-----END PUBLIC KEY-----/p' | \
cmp - "${PUBKEY}"
# Has the Let's Encrypt certificate been recently issued (validity >= 80 days)?
openssl x509 -checkend 6912000 -noout -in "$CERT"
# Are the certificates issued for the correct domain names?
(openssl x509 -noout -subject -in "$CERT" | awk -F'CN=' '{print $2}' | \
awk -F'/' '{print $1}'; \
openssl x509 -noout -text -in "$CERT" | grep "^[[:space:]]*DNS:" | \
xargs | tr ' ' '\n' | grep ^DNS | sed 's/^DNS://' | sed 's/,$//')| \
sort | uniq | cmp - "$DOMAINS"
代码可能通过cronjob运行:
0 1 * * * /usr/local/bin/update_cert.sh >/dev/null 2>&1
update_cert.sh的内容可能是:
#!/bin/bash
( cd /path_to_workdir && \
su - james -c "./check_cert.sh https://www.example.org intermediate.pem ecdsa.pem ecdsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
su - james -c "./check_cert.sh https://www.example.org intermediate.pem rsa.pem rsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
cat ecdsa.pem intermediate.pem > /etc/nginx/ssl/ecdsa_bundle.pem ) && \
cat rsa.pem intermediate.pem > /etc/nginx/ssl/rsa_bundle.pem ) && \
/etc/init.d/nginx reload
另请参见和。您似乎没有检查任何命令的返回值或输出。您正在查看输出并进行验证吗?@Fazlin:使用“set-e”时,bash脚本的进一步处理将中止,并返回一个返回码0。基本上,如果上面的bash脚本返回0,则旧证书将被替换。@jww:普通的“openssl验证”是不够的。bash脚本检查的不仅仅是链的有效性。另请参见和。您似乎没有检查任何命令的返回值或输出。您正在查看输出并进行验证吗?@Fazlin:使用“set-e”时,bash脚本的进一步处理将中止,并返回一个返回码0。基本上,如果上面的bash脚本返回0,则旧证书将被替换。@jww:普通的“openssl验证”是不够的。bash脚本检查的不仅仅是链的有效性。