Split Dns 内网外分别访问 同一个HTTPS服务
Table of Contents
内外兼修:如何安全地为你的内网服务配置 HTTPS,并实现内外网分别访问
前言
大家部署内网服务的或多或少都有根据用户位置分流的需求。本文将介绍如何使用 Nginx 和 certbot,为你的内网服务配置 HTTPS,并实现内网直接访问内网服务,公网访问公网服务的内外网分离访问模式。
我们将以 Gotify 为例,演示如何配置,从而确保内网访问速度和安全性,同时不影响公网用户的访问。
背景
假设你已经:
- 拥有一个公网域名
gotify.smallparking.eu.org。 - 在内网部署了 Gotify 服务 (http)。
- 在公网 VPS 上部署了 nginx,并通过 certbot 获取了该域名的 SSL 证书,公网用户通过域名访问该服务 (https)。
- 现在,你希望在内网也能就近访问gotify服务,并使用 HTTPS 安全地访问它。
- 核心目标: 内网用户通过
gotify.smallparking.eu.org访问内网 Gotify 服务(https),公网用户也仍能通过gotify.smallparking.eu.org访问公共的服务(https)。
步骤
-
准备工作
- 确保你已经在内网服务器上安装了 Nginx。
- 确保你已经安装了 Certbot (或 Lego)。
- 关键:配置内网 DNS 服务器,将
gotify.smallparking.eu.org解析到你的内网 Gotify 服务器的 IP 地址。 这是实现内外网分离访问的关键。(可以使用nslookup或dig验证dns解析情况) - 确认你的内网服务器可以访问公网(用于certbot 的 DNS 验证)。
-
申请内网 SSL 证书
在你的内网机器上,使用 Certbot (或 Lego) 申请 另一个 SSL 证书。 这是与公网证书隔离的关键一步。 Lego 命令示例:
export CLOUDFLARE_DNS_API_TOKEN="你的cloudflare api token" sudo -E lego --email="[email protected]" --dns cloudflare --domains="gotify.smallparking.eu.org" --path="/etc/lego" run--email: 你的邮箱地址。--dns cloudflare: 使用 Cloudflare API 进行 DNS 验证。 需要配置 Cloudflare API 密钥。--domains: 你要申请 SSL 证书的域名。--path: 证书存储路径。
重点: 由于内网服务器通常无法直接通过 HTTP 验证,我们使用 DNS 验证。Certbot/Lego 会在你的 DNS 服务商(如 Cloudflare)上创建 TXT 记录来验证你对域名的所有权。
-
配置 Nginx
在你的内网 Nginx 配置文件中,配置 HTTPS 相关信息,指向刚刚申请的内网证书。 例如:
server { listen 443 ssl; server_name gotify.smallparking.eu.org; ssl_certificate /etc/lego/certificates/gotify.smallparking.eu.org.crt; # 内网证书路径 ssl_certificate_key /etc/lego/certificates/gotify.smallparking.eu.org.key; # 内网私钥路径 # 其他 Gotify 相关配置... location / { proxy_pass http://gotify; proxy_http_version 1.1; proxy_buffering off; # Ensuring it can use websockets proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto http; proxy_redirect http:// $scheme://; # The proxy must preserve the host because gotify verifies the host with the origin # for WebSocket connections proxy_set_header Host $http_host; # These sets the timeout so that the websocket can stay alive proxy_connect_timeout 7m; proxy_send_timeout 7m; proxy_read_timeout 7m; access_log logs/gotify.smallparking.eu.org-access.log; error_log logs/gotify.smallparking.eu.org-error.log info; } } upstream gotify { # Set the port to the one you are using in gotify server 192.168.31.175:8114; } map $http_upgrade $connection_upgrade { default upgrade; '' close; }ssl_certificate: 内网 SSL 证书的路径。ssl_certificate_key: 内网 SSL 私钥的路径。
-
重启 Nginx
配置完成后,重启内网 Nginx,使配置生效:
sudo nginx -s reload -
验证
-
内网验证: 在你的内网机器上,使用
curl命令验证 HTTPS 连接是否正常。curl -v https://gotify.smallparking.eu.org如果
curl命令能够成功建立 HTTPS 连接,并且返回内网 Gotify 服务的页面,域名解析到了内网ip,并且证书是内网证书,则说明配置成功。结果应该如下:
❯ curl -v https://gotify.smallparking.eu.org * Uses proxy env variable no_proxy == '127.0.0.1,sf3-cn.feishucdn.com' * Host gotify.smallparking.eu.org:443 was resolved. * IPv6: (none) * IPv4: 192.168.31.175 #解析到了内网ip * Trying 192.168.31.175:443... * ALPN: curl offers h2,http/1.1 ... ... < HTTP/1.1 200 OK #服务正常 -
公网验证: 在公网环境下(例如,使用移动网络),通过浏览器访问
https://gotify.smallparking.eu.org, 确保仍然访问的是公网 VPS 上的 Gotify 服务,域名解析到了公网ip,并且显示的是公网证书。
-
-
确认一下dns
dig gotify.smallparking.eu.org; <<>> DiG 9.20.9 <<>> gotify.smallparking.eu.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19915 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;gotify.smallparking.eu.org. IN A ;; ANSWER SECTION: gotify.smallparking.eu.org. 0 IN A 192.168.31.175 # 这是我的内网服务的ip ;; Query time: 2 msec ;; SERVER: 192.168.31.1#53(192.168.31.1) (UDP) ;; WHEN: Sat May 24 19:58:46 CST 2025 ;; MSG SIZE rcvd: 86dig gotify.smallparking.eu.org @223.5.5.5; <<>> DiG 9.20.9 <<>> gotify.smallparking.eu.org @223.5.5.5 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25318 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ;gotify.smallparking.eu.org. IN A ;; ANSWER SECTION: gotify.smallparking.eu.org. 1 IN A 142.171.xxx.xxx # 这是我的公网服务的ip ;; Query time: 5 msec ;; SERVER: 223.5.5.5#53(223.5.5.5) (UDP) ;; WHEN: Sat May 24 19:59:23 CST 2025 ;; MSG SIZE rcvd: 71
遇到的问题与解决方案
-
问题: 即使 DNS 解析仍然指向公网 IP,内网证书仍然申请成功了。
- 解决方案: certbot 使用权威 DNS 服务器进行 DNS 挑战验证。 Certbot/Lego 通过 DNS API 在权威 DNS 服务器上添加 TXT 记录完成验证。
-
问题: 内网访问总是访问公网服务。
- 解决方案: 这是因为内网 DNS 没有正确配置。 确保你的内网 DNS 服务器将
gotify.smallparking.eu.org正确解析到你的内网 Gotify 服务器的 IP 地址。
- 解决方案: 这是因为内网 DNS 没有正确配置。 确保你的内网 DNS 服务器将
总结
本文详细介绍了如何在内网部署 HTTPS,并实现内外网分别访问不同服务的场景。 核心在于:
- 独立的内网证书: 保证内外网证书隔离,提高安全性。
- 正确的 DNS 配置: 这是实现内外网分离访问的关键。内网 DNS 解析指向内网 IP,公网 DNS 解析指向公网 IP。
通过合理的配置,你可以在享受 HTTPS 安全性的同时,优化内网访问速度,并且保证内外网服务互不干扰。
希望本文对你有所帮助! 如果你有任何问题,欢迎留言讨论。