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

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

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

内网中不能通过公网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即可完成设置.


自定义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的每一步, 至此, 问题解决.

你可能感兴趣的:(如何在内网下访问不支持Nat Loopback的路由器的公网IP)