首页 > 解决方案 > SSL 证书生成子域使用反向代理和letsencrypt失败

问题描述

使用 LetsEncrypt 生成 SSL 证书时出现问题。我已经使用 DNS 记录 CNAME 在我的主机上创建了我的子域。该证书允许访问多个 Docker 容器(Web、Db、Node),并且证书也由 Docker 下的反向代理管理。脚本多次成功后出现此问题。我成功创建了大约 5 次 3 个证书,然后出现连接被拒绝的新域名。下面是证书的 conf 和生成它的脚本。

subdomain.domain.online.conf

upstream subdomain.domain.online {
        server subdomain;
}

# http server directives
server {
        listen 80;
        server_name subdomain.domain.online;

        location / {
                proxy_redirect off;
                proxy_set_header   X-Forwarded-For $remote_addr;
                proxy_set_header   Host $http_host;
                proxy_ssl_session_reuse off;
                proxy_pass http://subdomain;
        }

        location /.well-known/acme-challenge/ {
                root /var/www/certbot;
        }
}

# https server directives
server {
        listen 443 ssl;
        server_name subdomain.domain.online;

        # ssl certifcates configuration
        ssl_certificate /etc/letsencrypt/live/subdomain.domain.online/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.online/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {
                proxy_pass http://subdomain.domain.online;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

init-letsencrypt_subdomain.sh

#!/bin/bash

if ! [ -x "$(command -v docker-compose)" ]; then
  echo 'Error: docker-compose is not installed.' >&2
  exit 1
fi

domains=(subdomain.domain.online)
rsa_key_size=4096
data_path="/home/unigridadm/ReverseProxy/certs/certbot_subdomain/"
email="%MYEMAIL%@email.com" # Adding a valid address is strongly recommended
staging=1 # Set to 1 if you're testing your setup to avoid hitting request limits

if [ -d "$data_path" ]; then
  read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
  if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
    exit
  fi
fi


if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
  echo "### Downloading recommended TLS parameters ..."
  mkdir -p "$data_path/conf"
  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
  echo
fi

echo "### Creating dummy certificate for $domains ..."
path="/etc/letsencrypt/live/$domains"
mkdir -p "$data_path/conf/live/$domains"
docker-compose run --rm --entrypoint "\
  openssl req -x509 -nodes -newkey rsa:1024 -days 1\
    -keyout '$path/privkey.pem' \
    -out '$path/fullchain.pem' \
    -subj '/CN=localhost'" certbot
echo


echo "### Starting nginx ..."
docker-compose up --force-recreate -d nginx
echo

echo "### Deleting dummy certificate for $domains ..."
docker-compose run --rm --entrypoint "\
  rm -Rf /etc/letsencrypt/live/$domains && \
  rm -Rf /etc/letsencrypt/archive/$domains && \
  rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
echo


echo "### Requesting Let's Encrypt certificate for $domains ..."
#Join $domains to -d args
domain_args=""
for domain in "${domains[@]}"; do
  domain_args="$domain_args -d $domain"
done

# Select appropriate email arg
case "$email" in
  "") email_arg="--register-unsafely-without-email" ;;
  *) email_arg="--email $email" ;;
esac

docker-compose run --rm --entrypoint "\
  certbot certonly --webroot -w /var/www/certbot \
    $email_arg \
    $domain_args \
    --rsa-key-size $rsa_key_size \
    --agree-tos \
    --force-renewal" certbot
echo

echo "### Reloading nginx ..."
docker-compose exec nginx nginx -s reload

脚本执行错误

### Downloading recommended TLS parameters ...

### Creating dummy certificate for subdomain.domain.online ...
Creating reverseproxy_certbot_run ... done
Generating a RSA private key
........+++++
.+++++
writing new private key to '/etc/letsencrypt/live/subdomain.domain.online/privkey.pem'
req: Can't open "/etc/letsencrypt/live/subdomain.domain.online/privkey.pem" for writing, No such file or directory

### Starting nginx ...
Recreating portainer_unigrid ... done
Recreating reverseproxy_unigrid ... done

### Deleting dummy certificate for subdomain.domain.online ...
Creating reverseproxy_certbot_run ... done

### Requesting Let's Encrypt certificate for subdomain.domain.online ...
Creating reverseproxy_certbot_run ... done
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Requesting a certificate for subdomain.domain.online
Performing the following challenges:
http-01 challenge for subdomain.domain.online
Using the webroot path /var/www/certbot for all unmatched domains.
Waiting for verification...
Challenge failed for domain subdomain.domain.online
http-01 challenge for subdomain.domain.online
Cleaning up challenges
Some challenges have failed.

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: subdomain.domain.online
   Type:   connection
   Detail: Fetching
   http://subdomain.domain.online/.well-known/acme-challenge/uMUmoZZqqcQlNuSO8D0HRhLy0lO72Ha79yUW9q1h_pc:
   Connection refused

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

### Reloading nginx ...

标签: dockernginxsslssl-certificatelets-encrypt

解决方案


推荐阅读