原文地址:https://zzz.buzz/zh/2016/04/03/enable-ssl-for-gitlab-with-letsencrypt/
Let's Encrypt 是一家全新的 SSL 证书颁发机构,为用户提供免费、自由、自动化的证书颁发流程。我们可以通过 Let's Encrypt 申请 SSL 证书来为我们的 GitLab 提供 HTTPS 接入。
安装 Let's Encrypt 客户端
首先,通过 git 下载 Let's Encrypt 的客户端:
git clone https://github.com/certbot/certbot
cd certbot
./certbot-auto --help
(注:自 2016 年 5 月起,letsencrypt
项目改名为 certbot
,letsencrypt-auto
工具改名为 certbot-auto
。不过为了保持兼容性,克隆仓库时仍可使用 https://github.com/letsencrypt/letsencrypt
,使用命令时也仍可用 letsencrypt-auto
。)
申请证书
下载完 Let's Encrypt 客户端后,我们可以借助随 GitLab 启动的 nginx 服务器来验证我们的域名,进而获得证书。
./certbot-auto --agree-tos --email email@example.com certonly --webroot -w /opt/gitlab/embedded/service/gitlab-rails/public/ -d www.example.com
上述命令中:
--agree-tos
- 同意用户协议。
--email
- 首次申请证书时,需要邮箱地址来创建 Let's Encrypt 的账号。不过,并不会验证此账号。
- 邮箱地址用于接受证书过期提醒。
certonly
- 只申请证书。
--webroot
- 通过在当前运行的 web 服务器下存放验证文件来验证身份。
-w
- 指定当前运行的 web 服务器的根目录。
- 对于通过 Omnibus 安装的 GitLab 的默认的 nginx 服务器的根目录位于
/opt/gitlab/embedded/service/gitlab-rails/public/
。 -d
- 指定要申请证书的域名。
证书申请成功后,会有类似如下输出:
Requesting root privileges to run certbot...
/home/zzz.buzz/.local/share/letsencrypt/bin/letsencrypt --agree-tos --email email@example.com certonly --webroot -w /opt/gitlab/embedded/service/gitlab-rails/public/ -d www.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Performing the following challenges:
http-01 challenge for www.example.com
Using the webroot path /opt/gitlab/embedded/service/gitlab-rails/public for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/www.example.com/fullchain.pem. Your cert
will expire on 2017-07-22. To obtain a new or tweaked version of
this certificate in the future, simply run certbot-auto again. To
non-interactively renew *all* of your certificates, run
"certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
得到的证书及私钥存放在 /etc/letsencrypt/live/www.example.com/
目录下,其中
cert.pem
: 网站自身的证书;chain.pem
: 网站证书链中的上级证书;fullchain.pem
: 包含了网站自身证书和上级证书的完整证书链;privkey.pem
: 网站自身证书对应的私钥。
更新证书
由于证书的有效期为三个月,因此我们需要定时执行以下命令来更新证书:
./certbot-auto renew
注意如果证书还有较长时间才会过期,那么证书并不会得到更新,并会得到类似如下输出:
Requesting root privileges to run certbot...
/home/zzz.buzz/.local/share/letsencrypt/bin/letsencrypt renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/gitlab.zzz.buzz.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal
The following certs are not due for renewal yet:
/etc/letsencrypt/live/gitlab.zzz.buzz/fullchain.pem (skipped)
No renewals were attempted.
而如果证书即将过期(有效期不足 20 天,10 天和 1 天时),用户却还未执行命令更新证书,那么 Let's Encrypt 会自动发邮件至申请证书时所留的邮件地址,提醒更新证书。
更新完证书后,还需要让 nginx 重新加载新证书:
sudo gitlab-ctl hup nginx
除了手动执行外,也可以把以上命令加入 cron 任务来定时执行。
使用以下命令来编辑 cron 任务:
sudo su -
crontab -e
在打开的文件中,添加以下内容:
0 3 * * 1 /home/zzz.buzz/certbot/certbot-auto renew && gitlab-ctl hup nginx
以上命令会在每周一的 3 点尝试更新证书,即如果证书将在 30 日内过期,则会被更新,否则将不会被更新;
同时还会发送 HUP 信号给 nginx 进程,以使其加载新证书。
注意将 certbot-auto
的路径替换为实际的路径。
在 GitLab 中应用证书
配置 GitLab 使用 HTTPS 协议
修改 /etc/gitlab/gitlab.rb
文件,配置 external_url
为 https
开头的地址,如:
external_url 'https://gitlab.zzz.buzz'
如果需要将经过 HTTP 的流量重定向至 HTTPS 还需要在 /etc/gitlab/gitlab.rb
文件中,进行如下配置:
nginx['redirect_http_to_https'] = true
配置证书
配置 GitLab 将要使用的证书有两种方式,一种是将之前通过 Let's Encrypt 申请的证书放置到 GitLab 默认要求的配置,如下文链接证书所示;另一种则是修改 GitLab 的配置文件,将证书的路径指向之前通过 Let's Encrypt 申请的证书,如下文修改配置所示。两种方式选一即可。
配置方法一:链接证书
根据通过 Omnibus 安装的 GitLab 的默认配置,会寻找存放在 /etc/gitlab/ssl/
目录下的 www.example.com.key
和 www.example.com.crt
文件,其中的 www.example.com
应当替换为在上文中 external_url
里设置的域名。
我们可以通过如下命令来将之前通过 Let's Encrypt 申请的证书链接到所需的位置。
# 切换至 root 用户(如已是 root 用户,则无需此步)
sudo su -
# 使用 root 用户执行以下命令
mkdir -p /etc/gitlab/ssl
chmod 700 /etc/gitlab/ssl
cd /etc/gitlab/ssl
ln -s ../../letsencrypt/live/www.example.com/fullchain.pem www.example.com.crt
ln -s ../../letsencrypt/live/www.example.com/privkey.pem www.example.com.key
配置方法二:修改配置
修改 GitLab 的配置文件 /etc/gitlab/gitlab.rb
,添加以下内容:
nginx['ssl_certificate'] = "/etc/letsencrypt/live/www.example.com/fullchain.pem"
nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/www.example.com/privkey.pem"
启用新配置
配置完成后,使用如下命令启用新配置:
sudo gitlab-ctl reconfigure
参考
Let's Encrypt
- Getting Started - Let's Encrypt - Free SSL/TLS Certificates
- Introduction — Let's Encrypt documentation
- certbot/certbot