家里换了一个光猫, 故重新配置了下端口映射, 但发现不再那么顺利.
和往常一样, 在打电信电话申请了公网IP 并且 给路由器添加了 端口转发之后, 本以为大功告成, 可发现了一个奇怪的现象. 如下图
用关键字"内网无法通过外网Ip访问内网" Google, 发现以下文章:
- 内网主机无法通过公网访问内网服务
- linux服务器NAT后无法在内网通过外部IP访问内部服务的问题
- 解决内网无法用域名访问本地http服务,DD-WRT NAT回流(NAT loopback).
得知这是IP协议本身的限制, 需要支持 NAT loopback的设备才能支持这种情况的访问.
可光猫不支持呀, 刷固件啥的我怕弄坏了, 故另想办法.
搜出来的文章有使用iptables解决此问题的, 但我测试之后没生效, 由于我不熟悉iptables, 所以无法深入研究了.
如果我们无法解决"通过外网访问不了"的问题, 那就只有让域名指向内网IP了.
故问题变为了:
如何在内网中将域名解析为内网IP
方案1. 修改hosts文件
最简单的方案是在你的电脑上配置hosts文件
vim /etc/hosts
添加如下代码
192.168.31.2 yourdomain.com
现在 在你的电脑上就可以访问yourdomain.com了.
但如果你的电脑上有Docker, 在Docker容器中, 这个方案行不通.
我的服务器上有Docker和Drone, 所以进化出了方案2
方案2. 在你的路由器上添加hosts + 配置Docker + 修改drone.yaml.
得看你的路由器支不支持配置hosts, 我用的小米路由器, 幸好小米正好支持, 让我少一点折腾, 使用小米WIFI 安卓APP即可完成设置.
现在, 所有内网ping yourdomain.com
的时候便是内网IP, 访问它当然不成问题.
不过别高兴太早, 在Docker中依然行不通.
好在解决这个问题不难: 我们需要配置Docker的DNS服务器为路由器.
搜索 "Docker 配置 DNS" 并结合官方文档"https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file".
配置如下:
➜ ~ cat /etc/docker/daemon.json
{
... // other config
"dns": ["192.168.31.1"] // 192.168.31.1 为路由器地址
}
接下来重启docker
sudo service docker restart
等待docker启动, 然后在docker容器中ping yourdomain.com
就是内网地址了.
不过不过, 如果你正在使用Drone做CI, 你会发现Drone在构建过程中启动的docker容器依然无法访问yourdomain.com
, 可以使用docker exec -it ID sh
进入容器命令行, ping yourdomain.com
得到的却是外网地址.
搜索"drone dns"能找到这个Issue: DNS should default to local Docker host settings #193
查阅发现docker-in-docker模式中, DNS配置不会继承父容器配置, 所以就没使用到192.168.31.1
作为DNS服务器.
解决方案也在上面的Issue中, 作者提到了可以使用network_mode: bridge
来达到目的.
如下:
steps:
- name: test
image: golang
commands:
- go build
- go test
network_mode: bridge
将network_mode: bridge
添加到需要访问yourdomain.com
的每一步, 至此, 问题解决.