如何在 Ubuntu 16.04 上使用 Let's Encrypt SSL 证书配置 GoCD

介绍

GoCD是一个强大的连续集成和交付平台,旨在自动化测试和发布流程. 拥有许多先进的功能,如比较构建,可视化复杂工作流程和自动构建版本跟踪,GoCD是一个灵活的工具,可以帮助团队为生产环境提供经过测试的软件。

在上一篇文章中,我们 安装了 GoCD 服务器,设置了一个代理,并配置了身份验证。 在本指南中,我们将配置 GoCD 以使用可信的 Let's Encrypt SSL 证书来防止浏览器在访问 Web 界面时发出警告。

第一种方法将安装一个 Nginx 网页服务器作为反向代理,将连接转发到 GoCD 的 HTTP 终端。

我们将讨论的第二种方法将获取Let's Encrypt的证书,然后切换出GoCD的HTTPS端点所使用的证书. 虽然这取消了对单独网络服务器的要求,可能节省资源,但GoCD使用Java keytore SSL证书寄存器,它与Let's Encrypt提供的证书格式不直接相容. 我们需要创建一个脚本,以便在每次更新时将证书自动转换为预期的格式. 如果您的服务器资源最少, 而您想要将所有可用的资源分配给 GoCD 本身, 此选项最好 .

前提条件

如果您尚未在 Ubuntu 16.04 上配置 GoCD 服务器,则需要在启动本指南之前配置一个。 基础服务器需要至少 2G 的 RAM 和 2 个 CPU 核心。 GoCD 还需要一个专用分区或磁盘用于文物存储。

服务器设置后,您可以使用以下指南进行一些初始配置并安装 GoCD:

要从 Let’s Encrypt 获得 SSL 证书,您的服务器需要有一个 域名

进一步的要求取决于您想要追求的方法,并将在适当的部分中解释。当您准备好继续时,选择您想要使用的方法并遵循相关指示。

选项1:将 Nginx 配置为 GoCD 的反向代理

如果您想将 Nginx 设置为 GoCD 的 SSL 终止反向代理,请遵循本节。在此配置中, Nginx 将配置为使用 Let’s Encrypt 证书服务 HTTPS 流量。它将解密客户端连接,然后使用常规 HTTP 将流量传输到 GoCD 的 Web 接口。

附加要求

如果您想使用 Nginx 作为 GoCD 的反向代理,您需要先安装 Nginx 和 Let’s Encrypt 客户端,然后为您的域申请证书。

一旦您完成了上述指南,GoCD 仍然可以通过访问 https://your_domain:8154来使用自签证书,并在删除端口规格时使用 Let's Encrypt 证书显示默认的 Nginx 页面。

现在,我们可以将 Nginx 配置为 GoCD 后端的代理请求,以便客户端连接通过 Let’s Encrypt 证书进行加密。

将 Nginx 配置为 GoCD 的 HTTP Web 接口的代理

我们从 Let’s Encrypt 下载了 SSL 证书,并将 Nginx 配置为在默认 SSL 端口上提供请求时使用该证书。

要开始,打开配置为使用 Let’s Encrypt 证书的默认 Nginx 服务器封锁文件:

1sudo nano /etc/nginx/sites-available/default

在文件的顶部,在服务器区块之外,打开一个新的上游部分,我们将这个区块称为gocd,以便我们稍后能够轻松识别它。内部,指定 Nginx 可以使用的地址来联系 GoCD 的 HTTP 接口。

1[label /etc/nginx/sites-available/default]
2upstream gocd {
3    server 127.0.0.1:8153;
4}
5
6server {
7    . . .

接下来,在服务器区块中,找到位置/区块。内部,评论try_files指令,以便我们可以指定我们的代理配置。而不是try_files行,添加一个代理传输到我们定义的gocd上游,使用http://协议。 包括proxy_params文件来设置我们位置区块所需的其他代理设置:

 1[label /etc/nginx/sites-available/default]
 2. . .
 3
 4server
 5    . . .
 6
 7    location / {
 8        #try_files $uri $uri/ =404;
 9        proxy_pass http://gocd;
10        include proxy_params;
11    }
12
13    . . .

保存并关闭文件,当你完成。

一旦您回到命令行,请通过键入检查 Nginx 配置语法错误:

1sudo nginx -t

如果没有发现任何错误,请重新启动 Nginx 服务,键入:

1sudo systemctl restart nginx

您的 GoCD 网页用户界面现在应该通过您的常规域名与 https:// 协议可访问。

<美元 > [注] 注: 虽然我们在通过Nginx的80和443端口上代理请求,但我们仍然需要在我们的防火墙上保持8154 HTTPS端口的开放. GoCD代理需要能够直接(没有代理)联系到GoCD服务器,这样服务器就可以直接验证客户端的SSL证书. 离开端口 8154 打开后,外部代理可以正确联系服务器,而通过浏览器的普通网络请求可以通过代理. < $ > (美元)

我们需要调整的最后一项是 GoCD 的 Web UI 中的网站 URL 设置。

更新 GoCD 网站 URL 以使用新地址

重新启动 Nginx 后,唯一剩余的任务是修改 GoCD 内部使用的网站 URL 设置以构建适当的链接。

在您的 Web 浏览器中访问您的 GoCD 服务器域,并在必要时登录:

1https://example.com

接下来,在顶部菜单栏中点击 ADMIN ,并从下载菜单中选择** Server Configuration** :

GoCD configure server link

服务器管理部分中,修改网站 URL以从末尾删除:8154端口规格。

GoCD site URL setting

滚动到页面底部,然后点击 SAVE 立即实施更改. 您的网站现在已设置为通过 Nginx 向 GoCD Web UI 代理所有域名请求。

选项 2:配置GoCD的原始SSL以使用加密证书

如果您想要配置 GoCD 自己的 Web 服务器以使用 Let’s Encrypt 证书,请遵循本节,在此配置中,我们将用 Let’s Encrypt 提供的可信证书替换 GoCD 服务器已经使用的自签证书,但要做到这一点,我们需要将证书文件转换为新的格式,并将其导入到 Java 键盘文件中。

附加要求

如果您想从 GoCD 内部处理所有 SSL 操作,则需要在没有 Web 服务器配置程序的情况下从 Let’s Encrypt 下载证书。

一旦您完成了上述指南,GoCD仍然可以通过访问https://your_domain:8154访问自签证书,并在/etc/letsencrypt/live/your_domain目录中找到所提供的 Let's Encrypt 证书文件。

创建证书转换脚本

GoCD 使用 Java keystore来处理 SSL 证书. 不幸的是,这是一个不同于 Let's Encrypt 使用的格式。 要使用我们的 Let's Encrypt 证书与 GoCD,我们将不得不使用非常具体的程序来转换它们。

由于程序的复杂性以及我们每次更新证书的转换需要,我们将创建一个脚本来自动化程序. 在 /usr/local/bin 目录中,在文本编辑器中创建并打开一个名为 convert_certs_for_gocd.sh 的脚本:

1sudo nano /usr/local/bin/convert_certs_for_gocd.sh

在内部,粘贴下面的脚本. 您需要更新的唯一设置是 base_domain 变量值. 将其设置为 GoCD 服务器的域名(这应匹配 /etc/letsencrypt/live/ 内的目录值):

 1[label /usr/local/bin/convert_certs_for_gocd.sh]
 2#!/bin/bash
 3
 4base_domain="example.com"
 5le_directory="/etc/letsencrypt/live/${base_domain}"
 6working_dir="$(mktemp -d)"
 7gocd_pass="serverKeystorepa55w0rd"
 8
 9clean_up () {
10    rm -rf "${working_dir}"
11}
12
13# Use this to echo to standard error
14error () {
15    printf "%s: %s\n" "$(basename "${BASH_SOURCE}")" "${1}" >&2
16    clean_up
17    exit 1
18}
19
20trap 'error "An unexpected error occurred."' ERR
21
22copy_cert_files () {
23    cp "${le_directory}/fullchain.pem" "${working_dir}"
24    cp "${le_directory}/privkey.pem" "${working_dir}"
25}
26
27convert_to_pkcs12 () {
28    openssl_pkcs12_args=(
29        "pkcs12"
30        "-inkey" "${working_dir}/privkey.pem"
31        "-in" "${working_dir}/fullchain.pem"
32        "-export"
33        "-out" "${working_dir}/${base_domain}.crt.pkcs12"
34        "-passout" "pass:${gocd_pass}"
35    )
36    openssl "${openssl_pkcs12_args[@]}"
37}
38
39import_to_keytool () {
40    keytool_args=(
41        "-importkeystore"
42        "-srckeystore" "${working_dir}/${base_domain}.crt.pkcs12"
43        "-srcstoretype" "PKCS12"
44        "-srcstorepass" "${gocd_pass}"
45        "-destkeystore" "${working_dir}/keystore"
46        "-srcalias" "1"
47        "-destalias" "cruise"
48        "-deststorepass" "${gocd_pass}"
49        "-destkeypass" "${gocd_pass}"
50    )
51    keytool "${keytool_args[@]}"
52}
53
54install_new_keystore () {
55    cp /etc/go/keystore /etc/go/keystore.bak
56    mv "${working_dir}/keystore" "/etc/go/keystore"
57    chown go:go /etc/go/keystore
58    systemctl restart go-server
59}
60
61if (( EUID != 0 )); then
62    error "This script requires root privileges"
63fi
64
65copy_cert_files && convert_to_pkcs12 && import_to_keytool && install_new_keystore && clean_up

让我们来看看这个剧本正在做什么。

一开始,我们设置了几个变量来帮助我们的脚本更容易工作. 我们设置了我们要转换的证书的域名,以及扩展到Let's加密证书目录的变量. 我们用)成为'serverKeystorepa55w0rd',我们设置了另一个变量来持有这个值.

接下来,我们定义了一个函数,该函数在调用时删除临时目录。我们在脚本的末尾使用此函数来清理我们自己之后以及发生任何意想不到的错误时。 为了实现这个第二个可能性,我们创建了一种另一个函数,该函数在退出前显示错误消息并清理。

然后,我们创建了实际转换的函数。 第一个函数将我们的工作空间设置为将私钥和完整链证书复制到工作目录中。 convert_to_pkcs12 函数使用 `openssl' 将完整链证书文件和私钥文件连接到 keytool 使用的组合 PKCS 12 文件中。 这个过程需要导出密码,所以我们使用 GoCD 密码变量。

下一个函数将新 PKCS 12 文件导入到 Java 键盘文件中. 我们导入文件并提供导出密码. 然后我们为键盘文件的各种密码提供相同的密码. 最后,最后一个函数将新 keystore 文件复制到 /etc/go 目录(备份旧 keystore),调整文件所有权,并重新启动 GoCD 服务器。

在脚本结束时,我们通过检查有效的用户ID是否为0,这意味着与 root 相同的权限

完成后,保存并关闭文件以继续。

执行初始转换

现在我们有一个转换脚本,我们应该使用它来执行初始证书转换。

首先,将脚本标记为可执行,以便可以直接执行,而无需调用翻译员:

1sudo chmod +x /usr/local/bin/convert_certs_for_gocd.sh

现在,用sudo调用脚本来执行初始转换,安装生成的keystore文件,并重新启动GoCD过程

1sudo /usr/local/bin/convert_certs_for_gocd.sh

由于 GoCD 服务器必须重新启动,此过程可能需要一段时间。脚本完成后,在服务器准备听到连接之前可能需要另一个或两个时刻。

1sudo watch netstat -plnt

此视图将显示应用程序目前正在收听的 TCP 端口,更新速度为 2 秒。当 GoCD 开始收听端口 8153 和 8154 时,屏幕应该是这样的:

1[secondary_label Output]
2Every 2.0s: netstat -plnt Thu Jul 27 20:16:20 2017
3
4Active Internet connections (only servers)
5Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
6tcp 0 0 0.0.0.0:22 0.0.0.0:*               LISTEN 1736/sshd
7tcp6 0 0 :::22                   :::*                    LISTEN 1736/sshd
8tcp6 0 0 :::8153                 :::*                    LISTEN 8942/java
9tcp6 0 0 :::8154                 :::*                    LISTEN 8942/java

一旦端口 8153 和 8154 出现,请按 CTRL-C 来退出显示器。

应用程序开始听取连接后,通过使用 HTTPS 访问您的 GoCD 域名在端口 8154 检查 Web 界面:

1https://example.com:8154

此前,当访问此页面时,地址栏中的图标表明证书不能信任(请注意,您的浏览器的视觉指标可能不同):

Chrome SSL cert not trusted icon

第一次访问,你可能不得不点击你的浏览器中的警告屏幕:

Browser SSL warning

现在我们已经用 Let's Encrypt 提供的可信证书替换了自签证书,浏览器将表示该证书是可信的,用户将不必绕过浏览器的警告来访问网站。

Chrome SSL cert trusted icon

这意味着GoCD能够使用我们转换的Let’s Encrypt证书。

设置一个 Auto Renew Hook

现在我们已经验证了我们的脚本是否正确地转换了证书资产,我们可以确保certbot每次更新证书时都会拨打我们的脚本。

/etc/letsencrypt/renewal 目录中打开您的域名更新配置文件,键入:

1sudo nano /etc/letsencrypt/renewal/example.com.conf

在文件的[renewalparams]部分中,向脚本的位置添加一个行设置renew_hook:

1[label /etc/letsencrypt/renewal/example.com.conf]
2. . .
3[renewalparams]
4. . .
5renew_hook = /usr/local/bin/convert_certs_for_gocd.sh

certbot软件安装了一个cron任务,它检查是否需要每天更新证书两次.证书更新后,将运行由renew_hook指定的脚本.这样,我们可以确保GoCD始终使用从Let’s Encrypt获得的最新有效证书。

保存并关闭文件,当你完成。

您可以通过干燥运行更新程序来验证您没有在文件中引入任何语法错误。 请注意,这不会运行我们的证书转换脚本,但会打印有关被跳过的通知:

1sudo certbot renew --dry-run
 1[secondary_label Output]
 2Saving debug log to /var/log/letsencrypt/letsencrypt.log
 3
 4-------------------------------------------------------------------------------
 5Processing /etc/letsencrypt/renewal/example.com.conf
 6-------------------------------------------------------------------------------
 7Cert not due for renewal, but simulating renewal for dry run
 8Renewing an existing certificate
 9Performing the following challenges:
10http-01 challenge for example.com
11Waiting for verification...
12Cleaning up challenges
13Dry run: skipping renewal hook command: /usr/local/bin/convert_certs_for_gocd.sh
14
15-------------------------------------------------------------------------------
16new certificate deployed without reload, fullchain is
17/etc/letsencrypt/live/example.com/fullchain.pem
18-------------------------------------------------------------------------------
19** DRY RUN: simulating 'certbot renew' close to cert expiry
20**          (The test certificates below have not been saved.)
21
22Congratulations, all renewals succeeded. The following certs have been renewed:
23  /etc/letsencrypt/live/example.com/fullchain.pem (success)
24** DRY RUN: simulating 'certbot renew' close to cert expiry
25**          (The test certificates above have not been saved.)

上面的输出验证了我们所做的更改没有阻止证书更新,输出也表明更新链条指向正确的脚本位置。

结论

在这份指南中,我们涵盖了两种不同的方式,即用Let's Encrypt的可信SSL证书来保障GoCD安装. 第一种方法是用Nginx设置证书,然后代理流量通到GoCD的网页界面. 第二个选项将Let's加密证书文件转换为PKCS 12格式并导入到一个GoCD本土使用的Java keytore文件. 这两种选项都以可信任的证书确保了GoCD的网络界面,但他们通过不同的策略和独特的取舍来完成这个任务. 适合你的方法将在很大程度上取决于你团队的要求和目标.

Published At
Categories with 技术
comments powered by Disqus