具有本地 IP 的设备的自签名证书
Self-signed certificate for device with local IP
场景:
- 我们有一个类似于 WiFi 路由器的设备 UI 和 API 暴露
- 该设备将 运行 在我们无法控制的任何 LAN 上,就像 WiFi 路由器 运行 在任何房子上一样。
- 设备不属于任何域,可通过浏览器通过其 IP 地址(即 192.168.1.100)访问。
- 协议应为 HTTPS
- 使用的软件是.net Core/Kestrel on Windows
- 目前,我们在所有浏览器中都有警告,告知设备证书无效。
- 约束:任何机器 (desktop/tablet) 都可以访问该设备,并且不能在客户端机器上安装或配置任何东西。
问题是:
消除警告的最佳方法是什么?我们读到 private/local IP 不能有常规证书。
自签名证书似乎可以工作几天,然后错误再次出现。
无法为 IP 地址颁发 SSL 证书;您必须有一个实际的 name 来为其创建证书。为了获得这样的名称,您需要一个 DNS。由于您无权访问该本地网络的内部 DNS,因此您必须为此使用 public DNS 服务器。
这假设该网络中的设备确实可以访问互联网。如果他们不这样做,那你就彻底倒霉了。
如果可以访问互联网,那么您只需将 public(子)域指向您的本地 IP 地址即可。基本上,为您拥有的域配置 DNS,以便在域或其子域之一上有一个 A 条目,指向您的本地 IP 地址 192.168.1.100
.
这样,您就可以将该 public 域传达给其他人,当他们尝试解析该域时,他们将访问 DNS,这将提供本地 IP 地址。因此,该网络内的设备可以访问您的设备并进行访问。由于他们随后通过该域访问它,因此通常会接受该确切域的证书。
从理论上讲,这很有效。在实践中,这可能有点复杂或昂贵。服务器证书过期,因此您必须将证书(安全地!)包含在您的设备中,并提供一些方法在它过期时最终更新它。免费证书,如来自 letsencrypt 的证书,将在几周内过期,但您可以花钱购买过期较慢的证书。
但最后还是会有些痛苦。但不是因为域名,而是因为证书——至少如果你想要一个自动信任的证书。不然你又回到原点了
So If I understand it corretly, without internet access and without
access to internal DNS, there is no way to allow clients (within local
network) to access a REST api listening on "some" device within the
local network over HTTPS. Right?
这是不正确的。您可以使用通过例如生成的通配符证书openssl 并通过 TLS 加密进行安全通信。只是签名不受信任,所以现代浏览器会显示大警告“不安全”。那是非常错误的。与纯 http 相比,它更安全,因为它不确定您是在与您期望的服务器交谈,但您是在安全加密的情况下交谈。
在纯 http 中,只需监听飞过的数据包就足够了。使用 https,您需要伪装成服务器并颁发证书和正确的端点。因此需要付出更大的努力,并且对于本地网络中的大多数用例来说,安全级别足够高。
生成证书
#!/bin/bash
CONFIG="
HOME = /var/lib/cert
[ req ]
default_bits = 4096
default_md = sha256
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = v3_req
[ req_distinguished_name ]
countryName= YourCountryCode
stateOrProvinceName= YourState
localityName= YourTown
organizationName= YourCompany
organizationalUnitName= YourUnit
commonName= *
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = email:whatever@localhost
"
openssl genrsa -out /var/usr/cert/name.key 4096
openssl req -x509 -new -nodes -key /var/usr/cert/name.key \
-config <(echo "$CONFIG") -days 365 \
-out /var/usr/cert/name.crt
将其应用到您的服务中。
对于浏览器,它会显示这个丑陋的大消息
对于连接到服务的应用程序,您通常需要设置一个标志,禁用签名检查,例如:
- curl -k 或 --insecure
- 涌入-ssl-unsafeSsl
(google 对您的申请有帮助)
场景:
- 我们有一个类似于 WiFi 路由器的设备 UI 和 API 暴露
- 该设备将 运行 在我们无法控制的任何 LAN 上,就像 WiFi 路由器 运行 在任何房子上一样。
- 设备不属于任何域,可通过浏览器通过其 IP 地址(即 192.168.1.100)访问。
- 协议应为 HTTPS
- 使用的软件是.net Core/Kestrel on Windows
- 目前,我们在所有浏览器中都有警告,告知设备证书无效。
- 约束:任何机器 (desktop/tablet) 都可以访问该设备,并且不能在客户端机器上安装或配置任何东西。
问题是: 消除警告的最佳方法是什么?我们读到 private/local IP 不能有常规证书。
自签名证书似乎可以工作几天,然后错误再次出现。
无法为 IP 地址颁发 SSL 证书;您必须有一个实际的 name 来为其创建证书。为了获得这样的名称,您需要一个 DNS。由于您无权访问该本地网络的内部 DNS,因此您必须为此使用 public DNS 服务器。
这假设该网络中的设备确实可以访问互联网。如果他们不这样做,那你就彻底倒霉了。
如果可以访问互联网,那么您只需将 public(子)域指向您的本地 IP 地址即可。基本上,为您拥有的域配置 DNS,以便在域或其子域之一上有一个 A 条目,指向您的本地 IP 地址 192.168.1.100
.
这样,您就可以将该 public 域传达给其他人,当他们尝试解析该域时,他们将访问 DNS,这将提供本地 IP 地址。因此,该网络内的设备可以访问您的设备并进行访问。由于他们随后通过该域访问它,因此通常会接受该确切域的证书。
从理论上讲,这很有效。在实践中,这可能有点复杂或昂贵。服务器证书过期,因此您必须将证书(安全地!)包含在您的设备中,并提供一些方法在它过期时最终更新它。免费证书,如来自 letsencrypt 的证书,将在几周内过期,但您可以花钱购买过期较慢的证书。
但最后还是会有些痛苦。但不是因为域名,而是因为证书——至少如果你想要一个自动信任的证书。不然你又回到原点了
So If I understand it corretly, without internet access and without access to internal DNS, there is no way to allow clients (within local network) to access a REST api listening on "some" device within the local network over HTTPS. Right?
这是不正确的。您可以使用通过例如生成的通配符证书openssl 并通过 TLS 加密进行安全通信。只是签名不受信任,所以现代浏览器会显示大警告“不安全”。那是非常错误的。与纯 http 相比,它更安全,因为它不确定您是在与您期望的服务器交谈,但您是在安全加密的情况下交谈。
在纯 http 中,只需监听飞过的数据包就足够了。使用 https,您需要伪装成服务器并颁发证书和正确的端点。因此需要付出更大的努力,并且对于本地网络中的大多数用例来说,安全级别足够高。
生成证书
#!/bin/bash
CONFIG="
HOME = /var/lib/cert
[ req ]
default_bits = 4096
default_md = sha256
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = v3_req
[ req_distinguished_name ]
countryName= YourCountryCode
stateOrProvinceName= YourState
localityName= YourTown
organizationName= YourCompany
organizationalUnitName= YourUnit
commonName= *
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = email:whatever@localhost
"
openssl genrsa -out /var/usr/cert/name.key 4096
openssl req -x509 -new -nodes -key /var/usr/cert/name.key \
-config <(echo "$CONFIG") -days 365 \
-out /var/usr/cert/name.crt
将其应用到您的服务中。
对于浏览器,它会显示这个丑陋的大消息 对于连接到服务的应用程序,您通常需要设置一个标志,禁用签名检查,例如:
- curl -k 或 --insecure
- 涌入-ssl-unsafeSsl
(google 对您的申请有帮助)