Skip to content

Instantly share code, notes, and snippets.

@fukasawah
Last active November 4, 2020 10:35
Show Gist options
  • Save fukasawah/56edff292ebe725b695649a2b823e47b to your computer and use it in GitHub Desktop.
Save fukasawah/56edff292ebe725b695649a2b823e47b to your computer and use it in GitHub Desktop.
Nginx向けにKeyVaultから証明書を書きだす雑なバッチ
#!/bin/bash
# usage) get-keyvault-certificate.sh my-keyvault fukasawah-dev
set -ue
umask 027
GROUP=nginx
KEYVAULT_NAME=${1}
CERTIFICATE_NAME=${2}
OUTPUT_DIR=${3:-/etc/letsencrypt}
TMP_DIR="/var/tmp/get-keyvault-certificate-$$"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
mkdir "$TMP_DIR"
function tear_down(){
rm -rf "$TMP_DIR"
exit
}
trap "tear_down" EXIT
TMP_CERT_DIR="${TMP_DIR}/${CERTIFICATE_NAME}"
TMP_DUMP_PFX="${TMP_DIR}/dump.pfx"
# Get PKCS12 File from KeyVault
ACCESS_TOKEN=$(curl --fail -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?resource=https://vault.azure.net&api-version=2018-02-01" | python -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')
SECRET_URL="https://${KEYVAULT_NAME}.vault.azure.net/secrets/${CERTIFICATE_NAME}/?api-version=2016-10-01"
curl --fail -H "Authorization: Bearer $ACCESS_TOKEN" "$SECRET_URL" | python -c 'import sys,json; print(json.load(sys.stdin)["value"])' | base64 -id > "${TMP_DUMP_PFX}"
# Convert to PEM
mkdir "$TMP_CERT_DIR"
# Private Key
openssl pkcs12 -in "${TMP_DUMP_PFX}" -nocerts -password "pass:" -nodes -out "${TMP_CERT_DIR}/privkey.pem"
# CA CERT
openssl pkcs12 -in "${TMP_DUMP_PFX}" -cacerts -password "pass:" -nokeys -out "${TMP_CERT_DIR}/chain.pem"
# Cert
openssl pkcs12 -in "${TMP_DUMP_PFX}" -clcerts -password "pass:" -nokeys -out "${TMP_CERT_DIR}/cert.pem"
# Fullchain
cat "${TMP_CERT_DIR}/cert.pem" "${TMP_CERT_DIR}/chain.pem" > "${TMP_CERT_DIR}/fullchain.pem"
#chmod 0440 "${TMP_CERT_DIR}/"*".pem"
# Verify
KEY_MD5=$(openssl rsa -noout -modulus -in "${TMP_CERT_DIR}/privkey.pem" | openssl md5)
CERT_MD5=$(openssl x509 -noout -modulus -in "${TMP_CERT_DIR}/cert.pem" | openssl md5)
if [ "$KEY_MD5" != "$CERT_MD5" ]; then
echo "Failed verification. ($KEY_MD5 != $CERT_MD5)" >&2
exit 1
fi
LIVE_DIR="${OUTPUT_DIR}/live"
NAMED_DIR="${OUTPUT_DIR}/${TIMESTAMP}"
mkdir -p "${OUTPUT_DIR}"
if [ -f "${LIVE_DIR}/${CERTIFICATE_NAME}/cert.pem" ]; then
CERT_TEXT_MD5=$(openssl x509 -text -noout -in "${TMP_CERT_DIR}/cert.pem")
LIVE_CERT_TEXT_MD5=$(openssl x509 -text -noout -in "${LIVE_DIR}/${CERTIFICATE_NAME}/cert.pem")
if [ "$CERT_TEXT_MD5" = "$LIVE_CERT_TEXT_MD5" ]; then
echo "Unchanged." >&2
exit 0
fi
fi
mkdir "$NAMED_DIR"
# move to OUTPUT_DIR
mv "${TMP_CERT_DIR}" "${NAMED_DIR}/${CERTIFICATE_NAME}"
ln -nfs "${NAMED_DIR}" "${LIVE_DIR}"
chgrp -R "$GROUP" "$OUTPUT_DIR"
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/fukasawah-dev/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fukasawah-dev/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/fukasawah-dev/chain.pem;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment