内部OTS硬件的TLS证书概念验证

本文详细介绍了为内部OTS硬件配置TLS证书的概念验证过程,包括使用Cloudflare API进行DNS管理、Let's Encrypt证书生成,以及服务器和客户端的Go语言实现。通过完整代码演示了如何为内部IP地址的设备创建有效HTTPS证书。

TLS certs for internal OTS hardware - Proof of Concept

该项目与我的博客文章《内部OTS硬件的TLS证书》相辅相成,提供了我在其中提出的概念的完整概念验证演示。项目的完整代码可在我的GitHub仓库中找到。

设置演示环境

要设置您自己的演示,您只需要:

  • 一个用于颁发证书的域名
  • 一个Cloudflare账户和API密钥

对于域名,请记住,它应该类似于您的主域名,但不能是主域名。

我选择Cloudflare是因为他们简单易用的DNS API。项目的DNS代码是模块化的,因此如果您不同意他们允许使用其平台的对象选择,可以随意将其替换为其他提供商。

您需要将域名设置为由Cloudflare处理DNS,它不需要处理任何Web流量。然后,您需要生成一个API密钥,以便服务器可以交互并生成DNS条目。

编译服务器

如果我能找到正确的方法,我会为主要的平台分发二进制文件,但由于依赖问题,这似乎太棘手了,因此,您需要自己编译。如果您不是开发人员,别担心,这非常简单。我将假设您使用的是基于Linux的系统,如果您使用的是Windows,命令将非常相似,您可能只需要在这里和那里添加“.exe”,并交换斜杠。

首先,您需要安装Go,您可以通过操作系统包管理系统或按照这些入门说明来完成。

一旦安装完成,您可以检出源代码,这通过以下命令完成:

1
go get -v github.com/digininja/ots-cert-demo

现在我们有了代码,让我们构建服务器:

1
2
3
4
cd ~/go/src/github.com/digininja/ots-cert/server
go get -v ./...
go build
cp ots-cert-server.cfg-template ots-cert-server.cfg

在此结束时,您应该有一个名为server的二进制文件和一个空的配置文件。用您选择的域名和Cloudflare API详细信息填充配置文件,您不需要更新任何其他字段,但请查看一下以防万一。

应用程序需要知道主机的IP地址,以便正确设置DNS。由于这是一个演示,它只会绑定在内部IP地址上,因此为了找到一个IP,它会扫描所有可用的接口,寻找RFC 1918范围内的IP,如果只找到一个,它将使用它,如果找到多个,则您必须告诉它您希望它从哪个接口获取地址,您可以在配置文件中或通过命令行使用--interface设置。

然后,您应该能够启动服务器:

1
2
3
4
5
./server 
INFO[0000] Starting the server
INFO[0000] No valid certificate found, going to create a new one 
INFO[0010] Creating DNS record
INFO[0011] Starting web server on: https://iotserver.ots-cert.space:9443

如果没有错误,那么您刚刚测试了系统的所有关键部分,一切正常且工作正常。这是因为,当服务器启动时,它没有证书,也没有可用的DNS名称,所以它首先要做的是去设置自己。它创建一个新证书,向DNS提供商注册其名称,然后启动一个监听HTTPS的Web服务器。为了节省重复调用获取新证书的时间,服务器将证书和密钥本地存储,以便下次启动时不需要再去获取新的。

运行客户端

现在,让我们启动并运行客户端。在新的终端中运行:

1
2
3
4
cd ~/go/src/github.com/digininja/ots-cert/client
go get -v ./...
go build
cp ots-cert-client.cfg-template ots-cert-client.cfg

与之前类似,您现在应该有一个客户端二进制文件和一个空的配置文件。您需要对配置文件进行的唯一更改是设置服务器的主机名。

配置完成后,让我们运行它,看看会发生什么:

1
2
3
4
./client
INFO[0000] The hostname is: nifty-babbage.ots-cert.space
INFO[0010] The certificate was generated
INFO[0010] Setup complete, browse to https://nifty-babbage.ots-cert.space:8443

希望您会得到类似于上面的内容,并且能够浏览到显示的URL:

1
2
curl https://nifty-babbage.ots-cert.space:8443
Congratulations, you should be viewing this over HTTPS on your custom domain.

快速检查服务器,您应该看到它在生成证书并返回证书时所经历的步骤。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
./server
INFO[0000] Starting the server
INFO[0000] No valid certificate found, going to create a new one 
INFO[0010] Creating DNS record
INFO[0011] Starting web server on: https://iotserver.ots-cert.space:9443
INFO[0361] Call to register a client
INFO[0361] The client ID is: aeadc9da-2057-4c3d-8a75-63369c68af43
INFO[0361] Hostname generated for client: nifty-babbage
INFO[0361] Creating DNS record
INFO[0362] Call to generate a certificate
INFO[0372] Certificate generated and being returned to the client

就是这样,您现在有一个在内部IP地址上运行的Web服务器,它具有来自Let’s Encrypt的有效证书。

证书管理

客户端将证书写入磁盘,但故意在下次启动时不重新加载它,这是为了允许演示过程,在现实世界中,客户端会在启动时检查证书,如果有效,则重新使用它。如果服务器或客户端可能会运行一段时间,它们还需要定期检查证书过期日期,以便在适当的时间续订。

如果您想手动检查证书以确认其有效性,可以按以下方式进行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
openssl x509 -in cert.pem -text -noout
Certificate:
  Data:
    Version: 3 (0x2)
    Serial Number:
      03:db:bb:db:00:46:81:9d:88:4d:c6:de:a3:8b:56:5b:25:b3
    Signature Algorithm: sha256WithRSAEncryption

    Validity
      Not Before: Jun 25 09:51:16 2019 GMT
      Not After : Sep 23 09:51:16 2019 GMT
    Subject: CN = nifty-babbage.ots-cert.space

安全考虑

当服务器收到注册客户端的初始请求时,它会检查提供的IP地址是否是内部地址,这是一种防止服务器被用于为可能面向互联网的站点设置DNS条目和证书的方法。尽管使用的域名不是公司的主域名,但让攻击者能够启动具有有效DNS和证书的外部可访问网站可能不是最好的事情。

我原本计划运行一个公共服务器,以便用户可以看到概念在野外运行的情况,但由于我默认的限制是每天只能颁发少量Let’s Encrypt证书,我认为它不会工作得太好,最终可能会让人困惑而不是帮助人们。

如果您喜欢这个演示,并正在考虑基于它创建一些东西,请联系我,知道这个过程在现实世界中被使用,并且有OTS硬件制造商正在认真对待安全,这将是非常棒的。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计