私网环境启用 https

本文是搭建私网环境下的 go 自动集成环境的一部分。

go 项目使用 go mod 作依赖包管理,遇到一些问题。
对于依赖库是保存在内网仓库的情况,拉取代码会失败,原因是 go mod 获取
依赖包版本需要使用 https 请求,而自建的 git 服务没有启用 https 。

如果是传统的 gopath 依赖项目, 只需要 go get -insecure 即可绕过 https 限制,
但是这里我们选择用 go mod ,一方面这是 go 官方推荐的方式,也是未来的发展趋势,
另一方面是不希望依赖包放在 vendor 目录下一起提交到版本库造成源码目录过于庞大。

接下来讲一讲如何在私网中启用 https, 服务端系统以 CentOS7 为例。

环境准备

为了达到实验目的,先修改本地机器的 host 文件。

web 服务运行在 192.168.20.44 的局域网 IP 的主机上
添加一条虚拟的域名映射到这个 IP 。

1
192.168.20.44 vcs.private.org

创建 SSL 证书

创建目录

1
2
3
4
5
6
7
8
# 创建目录用于保存公共证书
sudo mkdir /etc/ssl/certs

# 创建目录用于保存私钥文件
sudo mkdir /etc/ssl/private

# 关键目录,设置访问权限
sudo chmod 700 /etc/ssl/private

创建自签名密钥证书对

1
2
3
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key \
-out /etc/ssl/certs/selfsigned.crt

命令参数解释

openssl 用于创建和管理OpenSSL证书,密钥和其他文件的基本命令行工具。

req -x509 表示我们想要使用 X.509 证书签名请求(CSR,certificate signing request)生成签名证书。

-nodes 跳过用密码保护证书的选项。

-days 365 有效期 365 天。

-newkey rsa:2048 同时生成新证书和新密钥,生成 2048 位的 RSA 密钥。

-keyout 密钥输出目录。

-out 证书输出目录。

接下来会被要求填写一些证书的基本信息,需要注意的一点是
CommonName 要填写服务相关的域名或者公共 IP 地址。
此处咱们填写 vcs.private.org



还可以一条命令完成

1
2
3
4
sudo openssl req -x509 -nodes -days 365 \
-subj "/C=CN/ST=ZJ/L=HZ/O=private.org/CN=vcs.private.org" \
-newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key \
-out /etc/ssl/certs/selfsigned.crt


创建 Diffie-Hellman 组

据说用于与客户端协商 PFS (Perfect Forward Secrecy),能在私钥受损的情况下保证会话密钥不受损害。

创建要几十秒,需要稍微等一下。

1
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

这个 DH 组到底有多强大呢,等我学习后再总结下…… Orz

配置 Nginx 使用 SSL

安装 Nginx

1
2
3
4
5
6
7
8
# 启用 EPEL 库
sudo yum install epel-release
# 安装
sudo yum install nginx
# 开启
sudo systemctl start nginx
# 检查状态
systemctl status nginx

防火墙配置(如果未开启了防火墙,可跳过)

  • firewalld 相关
1
2
3
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
sudo firewall-cmd --runtime-to-permanent
  • iptables 相关
1
2
sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT

添加 TLS/SSL 服务配置块

sudo vim /etc/nginx/conf.d/ssl.conf

内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;

server_name vcs.private.org;

ssl_certificate /etc/ssl/certs/selfsigned.crt;
ssl_certificate_key /etc/ssl/private/selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;

root /usr/share/nginx/html;

location / {
}

error_page 404 /404.html;
location = /404.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

参考这篇文章添加更多安全性配置

启用新配置

先检查配置文件是否有错误

1
sudo nginx -t

重载新配置

1
sudo service nginx reload

测试

1
curl https://vcs.private.org

你会看到报错

1
2
3
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html
.....

更新客户端信任证书

服务端启用了 https,接下来让客户端接受这个自签署的证书。

  • ArchLinux

签署好的 selfsigned.crt 文件复制到 /etc/ca-certificates/trust-source/anchors 目录下
运行 sudo update-ca-trust, 没有任何输出即更新成功。

  • CentOS7

签署好的 selfsigned.crt 文件复制到 /etc/pki/ca-trust/source/anchors 目录下
运行 sudo update-ca-trust extract, 没有任何输出即更新成功。

  • Windows10

添加比较麻烦参考这篇文章
虽然添加完成后 chrome 依旧是不接受这个证书的(应该是浏览器策略的问题),但是
cmd 里 curl 验证可以通过。

客户端信任了证书之后,再次 curl 请求就能成功了。

参考