letsencrypt.sh(GitHub) 是一个获取 Let’s Encrypt 免费90天 SSL 证书的脚本,它可以自动创建 let’s encrypt 帐号、生成 csr、获取 pem、crt 证书。
letsencrypt.sh 需要在网站根目录创建 .well-known 文件夹以验证域名所有权,但 seafile 的 seahub 使用 Django 提供 web 服务,直接在 seahub 根目录 seafile-server-latest/seahub/ 创建 .well-known 目录会出现 404,试过修改 seafile-server-latest/seahub/seahub/settings.py 中的 STATICFILES_DIRS 没有成功,最后通过修改 nginx 配置文件解决:
server {
listen 80;
server_name files.upall.cn;
rewrite ^ https://$http_host$request_uri? permanent;
}
server {
listen 443;
server_name files.upall.cn;
ssl on;
ssl_certificate /data/web/cert/files.upall.cn.chained.crt;
ssl_certificate_key /data/web/cert/files.upall.cn.key;
proxy_set_header X-Forwarded-For $remote_addr;
location / {
fastcgi_pass 127.0.0.1:8000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param HTTPS on;
fastcgi_param HTTP_SCHEME https;
access_log /var/log/nginx/seahub.access.log;
error_log /var/log/nginx/seahub.error.log;
}
location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://127.0.0.1:8082;
client_max_body_size 0;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_request_buffering off;
}
location /media {
root /data/seafile/seafile-server-latest/seahub;
}
location /.well-known {
alias /data/web/files.upall.cn/.well-known;
}
}
letsencrypt.conf
# only modify the values, key files will be generated automaticly. ACCOUNT_KEY="/data/web/cert/letsencrypt-account.key" DOMAIN_KEY="/data/web/cert/files.upall.cn.key" DOMAIN_DIR="/data/web/files.upall.cn" DOMAINS="DNS:files.upall.cn" #ECC=TRUE #LIGHTTPD=TRUE
letsencrypt.sh
#注意第18行1个%和2个%的区别:
KEY_PREFIX="${DOMAIN_KEY%%.*}" : files.upall.cn.key -> files
KEY_PREFIX="${DOMAIN_KEY%.*}" : files.upall.cn.key -> files.upall.cn
#!/bin/bash
# Usage: /etc/nginx/certs/letsencrypt.sh /etc/nginx/certs/letsencrypt.conf
CONFIG=$1
ACME_TINY="/tmp/acme_tiny.py"
DOMAIN_KEY=""
if [ -f "$CONFIG" ];then
. "$CONFIG"
DIRNAME=$(dirname "$CONFIG")
cd "$DIRNAME" || exit 1
else
echo "ERROR CONFIG."
exit 1
fi
#KEY_PREFIX="${DOMAIN_KEY%%.*}"
KEY_PREFIX="${DOMAIN_KEY%.*}"
DOMAIN_CRT="$KEY_PREFIX.crt"
DOMAIN_PEM="$KEY_PREFIX.pem"
DOMAIN_CSR="$KEY_PREFIX.csr"
DOMAIN_CHAINED_CRT="$KEY_PREFIX.chained.crt"
if [ ! -f "$ACCOUNT_KEY" ];then
echo "Generate account key..."
openssl genrsa 4096 > "$ACCOUNT_KEY"
fi
if [ ! -f "$DOMAIN_KEY" ];then
echo "Generate domain key..."
if [ "$ECC" = "TRUE" ];then
openssl ecparam -genkey -name secp256r1 | openssl ec -out "$DOMAIN_KEY"
else
openssl genrsa 2048 > "$DOMAIN_KEY"
fi
fi
echo "Generate CSR...$DOMAIN_CSR"
OPENSSL_CONF="/etc/ssl/openssl.cnf"
if [ ! -f "$OPENSSL_CONF" ];then
OPENSSL_CONF="/etc/pki/tls/openssl.cnf"
if [ ! -f "$OPENSSL_CONF" ];then
echo "Error, file openssl.cnf not found."
exit 1
fi
fi
openssl req -new -sha256 -key "$DOMAIN_KEY" -subj "/" -reqexts SAN -config <(cat $OPENSSL_CONF <(printf "[SAN]\nsubjectAltName=%s" "$DOMAINS")) > "$DOMAIN_C
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py -O $ACME_TINY -o /dev/null
if [ -f "$DOMAIN_CRT" ];then
mv "$DOMAIN_CRT" "$DOMAIN_CRT-OLD-$(date +%y%m%d-%H%M%S)"
fi
DOMAIN_DIR="$DOMAIN_DIR/.well-known/acme-challenge/"
mkdir -p "$DOMAIN_DIR"
python $ACME_TINY --account-key "$ACCOUNT_KEY" --csr "$DOMAIN_CSR" --acme-dir "$DOMAIN_DIR" > "$DOMAIN_CRT"
if [ "$?" != 0 ];then
exit 1
fi
if [ ! -f "lets-encrypt-x3-cross-signed.pem" ];then
wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem -o /dev/null
fi
cat "$DOMAIN_CRT" lets-encrypt-x3-cross-signed.pem > "$DOMAIN_CHAINED_CRT"
if [ "$LIGHTTPD" = "TRUE" ];then
cat "$DOMAIN_KEY" "$DOMAIN_CRT" > "$DOMAIN_PEM"
echo -e "\e[01;32mNew pem: $DOMAIN_PEM has been generated\e[0m"
fi
echo -e "\e[01;32mNew cert: $DOMAIN_CHAINED_CRT has been generated\e[0m"
#service nginx reload
systemctl reload nginx
<完>