如何配置GoCD,让我们在Ubuntu 16.04上加密SSL证书

GoCD是一个强大的连续集成和交付平台,旨在自动化测试和发布流程。具有许多高级功能,如比较构建的能力,可视化复杂的工作流程,并自动化构建版本跟踪,GoCD ...

介绍

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

在最后一篇文章中,我们安装了GoCD服务器,设置了一个代理,并配置了认证 在本指南中,我们将配置GoCD以使用受信任的Let's Encrypt SSL证书,以防止在访问Web界面时出现浏览器警告。 我们将提供两种不同配置的说明。

第一种方法将安装Nginx Web服务器作为反向代理,将转发到GoCD的HTTP端点的连接。 这个选择提供了一个更加无缝的让我们加密的经验,可能是大多数人最好的选择。

我们将讨论的第二种方法将从Let's Encrypt获取证书,然后切换GoCD的HTTPS端点使用的证书。 虽然这消除了单独的Web服务器的需求,但可能会节省资源,GoCD使用Java密钥库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将被配置为使用“我们的加密”证书提供HTTPS流量。 它将解密客户端连接,然后使用常规HTTP将流量转发到GoCD的Web界面。 这需要Nginx前端的额外开销,但是更直接的方法。

其他要求

如果要使用Nginx作为GoCD的反向代理,首先需要安装Nginx并让我们加密客户端,然后为您的域请求证书。 这些教程提供了获取证书和配置Web服务器所需的步骤:

完成上述指南之后,仍然可以通过访问https:// your_domain :8154使用自签名证书访问https:// your_domain :8154并且在删除端口规范时,应使用Let's Encrypt证书显示默认的Nginx页面。

现在,我们可以将Nginx配置为对GoCD后端的代理请求,以便客户端连接使用“加密”验证加密。

配置Nginx到Proxy到GoCD的HTTP Web界面

我们已经下载了SSL证书,让我们加密并配置了Nginx,以便在默认SSL端口上提供请求时使用证书。 我们的下一步是配置Nginx来代理GoCD的常规HTTP Web界面的请求,可在端口8153上使用。

要开始,请打开配置为使用我们的加密证书的默认Nginx服务器块文件:

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

在文件的顶部,在server块外部,打开一个新的upsteam部分。 我们将把这个块gocd以便我们以后能很容易地识别它。 在里面,指定Nginx可以用来联系GoCD的HTTP接口的地址。 在我们这种情况下,这将使用本地环回设备,所以完整的地址应该是127.0.0.1:8153

在/ etc / nginx的/网站可用/默认
upstream gocd {
    server 127.0.0.1:8153;
}

server {
    . . .

接下来,在server块中找到location /块。 在里面,注释掉try_files指令,以便我们可以指定我们的代理配置。 代替try_files行,使用http://协议添加代理传递给我们定义的gocd上游。 包括proxy_params文件来设置我们的位置块所需的其他代理设置:

在/ etc / nginx的/网站可用/默认
. . .

server
    . . .

    location / {
        #try_files $uri $uri/ =404;
        proxy_pass http://gocd;
        include proxy_params;
    }

    . . .

完成后保存并关闭文件。

一旦你回到命令行,通过键入以下内容检查Nginx配置的语法错误:

sudo nginx -t

如果没有找到错误,请通过键入以下内容重新启动Nginx服务:

sudo systemctl restart nginx

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

注意:尽管我们通过Nginx代理端口80和443上的请求,但仍然需要在防火墙中保留8154 HTTPS端口 GoCD代理需要能够直接与GoCD服务器联系(无代理),因此服务器可以直接验证客户端的SSL证书。 离开端口8154打开将允许外部代理与服务器正确联系,通过浏览器的常规Web请求可以通过代理。

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

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

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

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

https://example.com

接下来,单击顶部菜单栏中的ADMIN ,然后从下拉菜单中选择服务器配置

GoCD配置服务器链接

在“ 服务器管理”部分中,修改站点URL以从最后删除:8154端口规范。 如果您以前使用IP地址而不是域名,请更改URL以使用您的域名:

GoCD站点URL设置

向下滚动到页面的底部,然后单击“ 保存 ”立即实现更改。 您的网站现已设置为通过Nginx向GoCD网络用户界面代理您的域的所有请求。

选项2:配置GoCD的本机SSL使用我们加密证书

如果您要配置GoCD自己的Web服务器以使用我们的加密证书,请按照此部分。 在这种配置中,我们将把GoCD服务器已经使用的自签名证书替换为Let's Encrypt提供的可信证书。 为此,我们需要将证书文件转换为新格式并将其导入到Java密钥库文件中。 我们将创建一个脚本,以便每次更新证书文件时都可以重复该过程。

其他要求

如果您希望处理GoCD本身内的所有SSL操作,则需要从“我们加密”下载一个证书,而不需要使用Web服务器配置过程。 按照本指南下载相应的客户端并获取您的域的证书:

完成上述指南后,GoCD仍然可以通过访问https:// your_domain :8154使用自签名证书进行访问,而让我们加密提供的证书文件应该在/etc/letsencrypt/live/ your_domain目录中可用。

创建证书转换脚本

GoCD使用Java密钥库来处理SSL证书。 不幸的是,这是与我们加密使用的格式不同的格式。 要使用我们的加密证书与GoCD,我们将不得不转换它们使用一个非常具体的程序。

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

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

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

/usr/local/bin/convert_certs_for_gocd.sh
#!/bin/bash

base_domain="example.com"
le_directory="/etc/letsencrypt/live/${base_domain}"
working_dir="$(mktemp -d)"
gocd_pass="serverKeystorepa55w0rd"


clean_up () {
    rm -rf "${working_dir}"
}

# Use this to echo to standard error
error () {
    printf "%s: %s\n" "$(basename "${BASH_SOURCE}")" "${1}" >&2
    clean_up
    exit 1
}

trap 'error "An unexpected error occurred."' ERR

copy_cert_files () {
    cp "${le_directory}/fullchain.pem" "${working_dir}"
    cp "${le_directory}/privkey.pem" "${working_dir}"
}

convert_to_pkcs12 () {
    openssl_pkcs12_args=(
        "pkcs12"
        "-inkey" "${working_dir}/privkey.pem"
        "-in" "${working_dir}/fullchain.pem"
        "-export"
        "-out" "${working_dir}/${base_domain}.crt.pkcs12"
        "-passout" "pass:${gocd_pass}"
    )
    openssl "${openssl_pkcs12_args[@]}"
}

import_to_keytool () {
    keytool_args=(
        "-importkeystore"
        "-srckeystore" "${working_dir}/${base_domain}.crt.pkcs12"
        "-srcstoretype" "PKCS12"
        "-srcstorepass" "${gocd_pass}"
        "-destkeystore" "${working_dir}/keystore"
        "-srcalias" "1"
        "-destalias" "cruise"
        "-deststorepass" "${gocd_pass}"
        "-destkeypass" "${gocd_pass}"
    )
    keytool "${keytool_args[@]}"
}

install_new_keystore () {
    cp /etc/go/keystore /etc/go/keystore.bak
    mv "${working_dir}/keystore" "/etc/go/keystore"
    chown go:go /etc/go/keystore
    systemctl restart go-server
}

if (( EUID != 0 )); then
    error "This script requires root privileges"
fi

copy_cert_files && convert_to_pkcs12 && import_to_keytool && install_new_keystore && clean_up

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

最初,我们设置了一些变量来帮助我们的脚本更容易使用。 我们为要转换的证书设置域名,扩展为Let's Encrypt certificate directory的变量。 我们使用mktemp命令创建一个临时工作目录,并将值分配给另一个变量。 GoCD需要所有Java密钥库密码serverKeystorepa55w0rd ,我们设置另一个变量来保存该值。

接下来,我们定义一个在调用时删除临时目录的函数。 我们在脚本结尾使用这个,在我们自己之后以及发生任何意外的错误时也进行清理。 为了完成第二种可能性,我们创建另一个功能,显示错误消息并在退出之前进行清理。 每当发生错误时,我们使用trap命令自动调用此函数。

之后,我们创建实际转换的功能。 第一个功能通过将私钥和全链证书复制到工作目录来设置我们的工作空间。 convert_to_pkcs12函数使用openssl来加入密钥工具使用的组合PKCS 12文件中的完整链证书文件和私钥文件。 此过程需要导出密码,因此我们使用GoCD密码变量。

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

在脚本结尾,我们通过检查有效的用户ID是否为“0”来检查脚本是否正在被调用,具有相同的权限,这意味着“具有与root相同的权限”。 然后按照适当的顺序调用这些函数来正确转换证书并安装新的keystore文件。

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

执行初始转换

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

首先,将脚本标记为可执行文件,以便可以直接执行,而无需调用解释器:

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

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

sudo /usr/local/bin/convert_certs_for_gocd.sh

由于GoCD服务器必须重新启动,这个过程可能需要一些时间。 脚本完成后,服务器准备好监听连接可能需要一两秒钟。 您可以键入以下内容,查看应用程序正在使用的端口:

sudo watch netstat -plnt

此视图将显示应用程序当前正在使用两秒刷新率的TCP端口。 当GoCD开始监听端口8153和8154时,屏幕应如下所示:

Every 2.0s: netstat -plnt                                                    Thu Jul 27 20:16:20 2017

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1736/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1736/sshd
tcp6       0      0 :::8153                 :::*                    LISTEN      8942/java
tcp6       0      0 :::8154                 :::*                    LISTEN      8942/java

一旦端口8153和8154存在,按CTRL-C退出显示。

应用程序开始监听连接后,请使用HTTPS访问端口8154上的GoCD域,查看Web界面:

https://example.com:8154

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

Chrome SSL证书不信任图标

您第一次访问时,您可能必须在浏览器中点击警告屏幕:

浏览器SSL警告

现在我们用Let's Encrypt提供的受信任的证书替换了自签名证书,浏览器将会指出证书是可信赖的,用户不必绕过浏览器警告来访问该站点。 请注意,您的浏览器可能会缓存先前的证书,直到关闭当前选项卡,窗口或会话:

Chrome SSL认证信任图标

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

设置自动更新挂钩

现在我们已经验证了我们的脚本正确地转换了证书资产,我们可以确保certbot每次更新证书时certbot调用脚本。

通过键入以下内容,在/etc/letsencrypt/renewal目录中打开您的域的续订配置文件:

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

在里面,在文件的[renewalparams]部分,在你的脚本的位置添加一行行renew_hook

/etc/letsencrypt/renewal/example.com.conf
. . .
[renewalparams]
. . .
renew_hook = /usr/local/bin/convert_certs_for_gocd.sh

certbot软件安装一个cron作业,检查每个证书是否应该每天更新两次。 证书更新后,将会运行由renew_hook指定的脚本。 这样,我们可以确保GoCD始终使用从“加密”获取的最新有效证书。

完成后保存并关闭文件。

您可以通过进行更新程序的干式运行来测试您没有对文件引入任何语法错误。 请注意,这不会运行我们的证书转换脚本,但它会打印出一个关于跳过的通知:

sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for example.com
Waiting for verification...
Cleaning up challenges
Dry run: skipping renewal hook command: /usr/local/bin/convert_certs_for_gocd.sh

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/example.com/fullchain.pem
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)

以上输出确认我们所做的更改并未阻止证书更新。 输出还指示更新钩子指向正确的脚本位置。

结论

在本指南中,我们介绍了使用“加密”来保护GoCD安装的可信SSL证书的两种不同方法。 第一种方法是使用Nginx设置证书,然后通过GoCD的Web界面代理流量。 第二个选项将Let's Encrypt证书文件转换为PKCS 12格式,并将其导入到Java密钥库文件中,以便本地使用GoCD。 这两个选项都使用可信赖的证书保护GoCD的Web界面,但是他们使用不同的策略和独特的权衡来完成此任务。 适合您的方法将在很大程度上取决于您团队的要求和目标。