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
<完>