如何在内网下访问不支持Nat Loopback的路由器的公网IP

家里换了一个光猫, 故重新配置了下端口映射, 但发现不再那么顺利.

和往常一样, 在打电信电话申请了公网IP 并且 给路由器添加了 端口转发之后, 本以为大功告成, 可发现了一个奇怪的现象. 如下图

内网中不能通过公网ip访问服务

用关键字"内网无法通过外网Ip访问内网" Google, 发现以下文章:

得知这是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即可完成设置.


自定义HOSTS

现在, 所有内网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的每一步, 至此, 问题解决.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容