ssl 证书;certbot+nginx+docker

Nginx as a server

首先我们会启动一个 nginx 容器,将配置文件拷贝到本地:

version: '3'

services:
  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always

接下来我们会对nginx做卷的映射

使用了 Docker 的“卷”功能。这意味着我们将位于/etc/nginx/conf.d/docker 容器的文件夹映射到位于./nginx/conf/我们本地计算机上的文件夹。我们在本地添加、删除或更新到此文件夹中的每个文件都将更新到容器中。

请注意,我:ro在卷声明的末尾添加了一个。ro意思是“只读”。容器将永远无权将文件更新到此文件夹中。这没什么大不了的,但将其视为最佳实践。它可以避免浪费几个宝贵的调试时间。

version: '3'

services:
  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/:ro

现在更新 Docker Compose 文件如下:

version: '3'

services:
  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/:ro
      - ./certbot/www:/var/www/certbot/:ro

并将以下配置文件添加到您的./nginx/conf/本地文件夹中。不要忘记使用您自己的数据进行更新。

server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;
    server_tokens off;

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

    location / {
        return 301 https://example.org$request_uri;
    }
}

使用 Certbot 创建证书

我们需要为 certbot 使用 docker 镜像,并将其作为服务添加到我们的 Docker Compose 项目中。

version: '3'

services:
  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/:ro
      - ./certbot/www:/var/www/certbot/:ro
  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/www/:/var/www/certbot/:rw

我们现在有两种服务,一种用于 nginx,一种用于 Certbot。您可能已经注意到他们声明了相同的卷。这是为了让他们一起交流。

Certbot 将其文件写入./certbot/www/,nginx 将在端口80上为每个请求/.well-know/acme-challenge/. 这就是 Certbot 可以验证我们的服务器的方式。

请注意,对于 Certbot,我们:rw在卷声明的末尾使用了它代表“读写”。如果不这样做,它将无法写入文件夹并且身份验证将失败。

您现在可以通过运行来测试一切是否正常docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d example.org。您应该会收到一条成功消息,例如“试运行成功”。

现在我们可以为服务器创建证书,我们想在 nginx 中使用它们来处理与最终用户浏览器的安全连接。

Certbot 在/etc/letsencrypt/文件夹中创建证书。与 webroot 的原理相同,我们将使用卷在容器之间共享文件。

version: '3'

services:
  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/:ro
      - ./certbot/www:/var/www/certbot/:ro
      - ./certbot/conf/:/etc/nginx/ssl/:ro
  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/www/:/var/www/certbot/:rw
      - ./certbot/conf/:/etc/letsencrypt/:rw

使用 重新启动您的容器docker compose restart。Nginx 现在应该可以访问 Certbot 创建证书的文件夹。

但是,这个文件夹现在是空的。在没有标志的情况下重新运行 Certbot--dry-run以用证书填充文件夹:

docker-compose run --rm  certbot certonly --webroot --webroot-path /var/www/certbot/ -d example.org

由于我们有这些证书,剩下的就是443nginx 上的配置。

server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;
    server_tokens off;

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

    location / {
        return 301 https://example.org$request_uri;
    }
}

server {
    listen 443 default_server ssl http2;
    listen [::]:443 ssl http2;

    server_name example.org;

    ssl_certificate /etc/nginx/ssl/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/example.org/privkey.pem;
    
    location / {
    	# ...
    }
}

现在重新加载 nginx 服务器将使其能够处理使用 HTTPS 的安全连接。Nginx 使用来自 Certbot 卷的证书和私钥。

更新证书

Certbot 和 Let's Encrypt 可能会遇到的一个小问题是证书只能使用 3 个月。如果您不希望人们被浏览器上的丑陋和可怕的消息阻止,您将需要定期更新您使用的证书。

但是由于我们已经有了这个 Docker 环境,更新 Let's Encrypt 证书比以往任何时候都容易!

docker-compose run --rm certbot renew

定时任务

[root@gitea-jenkins ~]# crontab -l
## 更新 gitea 证书,⚠️,执行docker-compose 命令需要在 docker-compose.yaml 文件所在的文件夹内执行;
00 03 * * 1 cd /server;/usr/local/bin/docker-compose run --rm certbot renew
posted @ 2022-12-23 08:56  Star-Hitian  阅读(801)  评论(0编辑  收藏  举报