by Devin Yang

建立于: 2年前 ( 更新: 2年前 )

HAProxy的重载速度很快,跟本感觉不出有重启,所有证书都给HAProxy处理真的很方便。

主机环境需求,请确认您已有下面两个命令
(Ubuntu怎么装? apt-get install -y haproxy cerbot,我猜的,如果不是请自行Google)

root@ptest:/usr/local/scripts# which certbot
/usr/bin/certbot
root@ptest:/usr/local/scripts# which haproxy
/usr/sbin/haproxy


本文介绍,我的如何用bash生成证书全过程。

第一步: 创建生成证书用的bash,我取名叫gen_cert.sh

首先我写了一支产证书的bash叫gen_cert.sh,我的习惯会放到/usr/local/scripts下,只有root可访问

#!/bin/bash
/usr/bin/certbot \
 --email unknow@ccc.tc \
 --no-eff-email \
 --webroot -w /var/www/html \
 -d ccc.tc \
 -d www.ccc.tc \
 中间...略过一大堆
 -d chat.ccc.tc \
 -d speed.ccc.tc \
 -d chat.ccc.tc \
 -d video.ccc.tc \
 certonly

在这里的--webroot -w就是验证档的根目录,代表命令运行时,下方的目录会被放验证档
/var/www/html/.well-known/acme-challenge
其他的-d参数,就是你要申请的证书的域名啦

开始前,我稍微解释一下,我域名的DNS Record设置为*.ccc.tc,
也就是说,所有子域名不指定A Record的情况下IP都会指向220.134.172.98这个IP位置的。

好的,我直接试给大家看

root@ptest:/usr/local/scripts# host -t a eewoieoiewo.ccc.tc
eewoieoiewo.ccc.tc has address 220.134.172.98

因为这样,大家或许猜到了,当我要申请域名时,只要在gen_cert上,补上-d <我要的域名即可>,再运行./gen_cert.sh即可。
例如:  -d dtest.ccc.tc \

/usr/bin/certbot \
 --email unknow@ccc.tc \
 --no-eff-email \
 --webroot -w /var/www/html \
 -d ccc.tc \
 -d www.ccc.tc \
 中间...略过一大堆
 -d chat.ccc.tc \
 -d speed.ccc.tc \
 -d chat.ccc.tc \
 -d video.ccc.tc \
 -d dtest.ccc.tc \
 certonly

以上,这个产证书的bash说明完毕了。
也就是说,当Let's encrpyt要进行验证时,不管子域名是什么,只要后面的路径是/.well-known/acme-challenge,一律导向我设置的本地端HTTP Server即可。

第二步: 我们需要安装一台本地端的HTTP Server
在这里我的例子采用apache2,网站根目录就是/var/www/html,就是上面bash所指定的位置 (--webroot -w /var/www/html)。
您可以用您任何会安装的Web Server或是Docker只要你喜欢,但有一点要注意,就是别开port 80,因为这要留给HAProxy用。

root@ptest:/etc/apache2/sites-enabled# systemctl status apache2
● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2022-11-26 21:47:31 CST; 2 weeks 0 days ago
     Docs: https://httpd.apache.org/docs/2.4/
 Main PID: 701 (apache2)
    Tasks: 55 (limit: 4915)
   CGroup: /system.slice/apache2.service
           ├—  701 /usr/sbin/apache2 -k start
           ├—19344 /usr/sbin/apache2 -k start
           └—19345 /usr/sbin/apache2 -k start

在我的环境中apache2很幸运他启动的连接埠默认是port 8080不是port 80。

root@ptest:/etc/apache2/sites-enabled# head -n1 000-default.conf
<VirtualHost *:8080>
root@ptest:/etc/apache2/sites-enabled# netstat -ntlp|grep :8080
tcp6       0      0 :::8080                 :::*                    LISTEN      701/apache2
root@ptest:/etc/apache2/sites-enabled#


第三步: 设置HAProxy的访问规则
HAProyx的设置档应该会在/etc/haproxy/haproxy.cfg
请用自己常用的编辑器开启进行编辑,开始前先来看底下两个重要设置。

   acl acme path_beg -i /.well-known/acme-challenge
   redirect scheme https code 301 if !{ ssl_fc } !acme

第一条: 设置开始路径为这样的/.well-known/acme-challenge就使用acme访问规则
第二条: 如果不符合acme规则,都自动跳转HTTPS,也就是说,
假如当网址长这样时 http://abc.ccc.tc/.well-known/acme-challenge,是不会被跳转的。
为让大家更有feel,底下的的域名是我随便打的,基本上都开同一个档,您可以试看看,
甚至您随便改子域名的名称,都可以看到Hello World文本。

http://iewoieoieo.ccc.tc/.well-known/acme-challenge/test.txt

http://lksjlkjkalfjlsjlj.ccc.tc/.well-known/acme-challenge/test.txt

现在,我们来看看/etc/haproxy/haproxy.cfg内容,大概就像下方这样,我只列出重点哦,
您有注意到了吗? 内容中底下use_backend local if acme这个设置。
他的意思非常直觉,不管域名是什么,只要路径是/.well-known/acme-challenge符合acme的访问规则,都会使用local这个后端服务(use_backend local)。
local这个名称是我随传打的,您可以取您想要的名称。

frontend proxy
   mode http
   bind :443 ssl crt /etc/ssl/ccc.tc/ccc.tc.pem alpn h2,http/1.1 crt /etc/ssl/ccc.tc/demo.ccc.tc.pem alpn h2,http/1.1  crt /etc/ssl/ccc.tc/e-course.app.pem alpn h2,http/1.1
   bind *:80
   acl acme path_beg -i /.well-known/acme-challenge
   redirect scheme https code 301 if !{ ssl_fc } !acme

   #acme-challenge 您应该跟我一样会有很多backend,acme的lcoal server要放在最上面
   use_backend local if acme
   use_backend material_server if material_url
   use_backend wss_server if wss_url
   use_backend webrtc_server if webrtc_url
   use_backend linebot_server if linebot_url

在use_backend local if acme中,他指向的正是上方「第二步」中设置的主机

    backend local
       mode http
       balance roundrobin
       server ptest 127.0.0.1:8080


我自己的习惯会弄一个别名的验证档,检测haproyx的设置是否有搞错

alias hat='haproxy -f /etc/haproxy/haproxy.cfg -c'

像这样

root@ptest:~# hat
Configuration file is valid

如果没问题,基本上,我要生成证书及子域名,只要调一下gen_cert.sh就可以生成啦,超方便。

要确认您的设置是否有效,可以随传到验证的目录(/var/www/html/.well-known/acme-challenge)下touch个文件,
再从主机端透过网址的方式去开开看有没有效。

因为我已经生成过很多啦,所以下方的例子,会问我是否扩张证书,您也看到下面的画面中,有一堆子域名,
多到我自己都忘了是做什么用的了😆,就知道我用这环境生成证书有多简单啦。

root@ptest:/usr/local/scripts# ./gen_cert.sh
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Attempting to parse the version 1.22.0 renewal configuration file found at /etc/letsencrypt/renewal/ccc.tc.conf with version 0.31.0 of Certbot. This might not work.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You have an existing certificate that contains a portion of the domains you
requested (ref: /etc/letsencrypt/renewal/ccc.tc-0003.conf)

It contains these names: ccc.tc, 627csizs.ccc.tc, admin.ccc.tc, ai.ccc.tc,
auth2.ccc.tc, bbb.ccc.tc, cbk.ccc.tc, ccc-chat.ccc.tc, chat.ccc.tc,
chatroom.ccc.tc, cool.ccc.tc, d2.ccc.tc, ddm.ccc.tc, demo.ccc.tc, drive.ccc.tc,
dtest.ccc.tc, fb.ccc.tc, git.ccc.tc, gw.ccc.tc, imac.ccc.tc, ip.ccc.tc,
laravel.ccc.tc, line.ccc.tc, linebot.ccc.tc, linux.ccc.tc, mail.ccc.tc,
material.ccc.tc, nas.ccc.tc, notes.ccc.tc, pdf.ccc.tc, photo.ccc.tc,
phpenv.ccc.tc, pi4.ccc.tc, push.ccc.tc, reg.ccc.tc, sagent.ccc.tc,
sldrive.ccc.tc, speed.ccc.tc, station.ccc.tc, test.ccc.tc, tn.ccc.tc,
tools.ccc.tc, vbk.ccc.tc, video.ccc.tc, vm.ccc.tc, webrtc.ccc.tc, wss.ccc.tc,
www.ccc.tc, yty.ccc.tc

You requested these names for the new certificate: ccc.tc, 627csizs.ccc.tc,
admin.ccc.tc, chat.ccc.tc, ddm.ccc.tc, drive.ccc.tc, fb.ccc.tc, imac.ccc.tc,
ip.ccc.tc, laravel.ccc.tc, line.ccc.tc, linux.ccc.tc, nas.ccc.tc, notes.ccc.tc,
station.ccc.tc, pdf.ccc.tc, reg.ccc.tc, sagent.ccc.tc, www.ccc.tc, vm.ccc.tc,
cool.ccc.tc, photo.ccc.tc, bbb.ccc.tc, yty.ccc.tc, cbk.ccc.tc, auth2.ccc.tc,
webrtc.ccc.tc, vbk.ccc.tc, d2.ccc.tc, git.ccc.tc, push.ccc.tc, video.ccc.tc,
dtest.ccc.tc, mail.ccc.tc, ccc-chat.ccc.tc, tools.ccc.tc, sldrive.ccc.tc,
tn.ccc.tc, pi4.ccc.tc, gw.ccc.tc, wss.ccc.tc, demo.ccc.tc, test.ccc.tc,
ai.ccc.tc, speed.ccc.tc, linebot.ccc.tc, chatroom.ccc.tc, material.ccc.tc

Do you want to expand and replace this existing certificate with the new
certificate?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(E)xpand/(C)ancel:

我压大写的E,即可进行证书扩张。

第四步: 证书更新renew.sh或证书重载reload.sh
由於证书是给HAProxy控管的,所以当生成新的证书,我们要来重组新证书的内容给HAProyx,并且重载haproxy服务。
您可以建两个文件,一个是会renew证书用的,另一个则无renew命令,这样产新证书时运行reload.sh速度较快,不需检测证书是否需更新。

#!/bin/bash
#更新证书
#/usr/bin/docker run --rm \
#       -v /etc/letsencrypt:/etc/letsencrypt \
#       -v /var/www/html:/html \
#       certbot/certbot:arm32v6-latest \
#       --webroot -w /html/ \
#       renew

/usr/bin/certbot \
--webroot -w /var/www/html/ \
renew

#重组
FOLDER=ccc.tc
cat /etc/letsencrypt/live/${FOLDER}/fullchain.pem \
    /etc/letsencrypt/live/${FOLDER}/privkey.pem > \
    /etc/ssl/ccc.tc/${FOLDER}.pem

#重启HAProxykk
systemctl reload haproxy

第五步: 如果确认renew.sh手动运行没问题,就放入调度每天跑自动更新

0 0 * * * /usr/local/scripts/renew.sh


总结
假定您的设置无误,并且理解我本篇的说明,那所有的经过此HAProxy的后端主机都会经由HAProyx进行加密,
所有的后端主机完全不用设置证书,并且所有后端主机的证书都会被自动更新。

下方为示意说明

    use_backend local if acme

    use_backend material_server if material_url
    use_backend wss_server if wss_url
    use_backend webrtc_server if webrtc_url
    use_backend linebot_server if linebot_url
   
   backend ai_server
       mode http
       balance roundrobin
       fullconn   10000
       cookie SITEID insert indirect nocache
       server tplink 192.168.99.181:8000

    backend gw_router
       mode http
       balance roundrobin
       fullconn   10000
       cookie SITEID insert indirect nocache
       server tplink 192.168.99.254:80

    backend nas
       mode http
       balance roundrobin
       fullconn   10000
       cookie SITEID insert indirect nocache
       server nas 192.168.99.130:5000 check cookie synology

Tags: ssl haproxy certbot

Devin Yang

文章内容无法一一说明,如果您有什么不了解处,欢印提问哦:)

No Comment

Post your comment

需要登入才可留言!

类似文章


openssl

如何移除PEM的密码

您可以使用openssl rsa命令删除密码。 我们传入SSL .key并获得一个.key文档作为输出。

ssl,certbot

攻略docker版Let's Encrypt证书申请

本文主要分享,我如何采用Docker的方式进行Let's Encrypt证书申请, Let's Encrypt有相当多种类的ACME Client, 我将使用官方推^Certbot(ACME Client)做说明。 并且使用docker的方式来运行ACME Client。

fastapi,haproxy

HAProxy与fastapi

HAProxy可以透过acl的定义来决定request要导向那台Backend,本文就来介绍本站的一些设置吧在这里透过path_beg的acl,让送来的request导向其他的服务,而不是域名所指定的后端。