Ubuntu 16双服务器MySQL连接异常:局域网连接走公网IP求助
嘿,我来帮你拆解这个问题,咱们一步步来搞定它:
一、为啥连接数据库会走公网?
你遇到的情况,大概率是下面几个原因之一:
- Laravel配置没到位:你以为自己用的是局域网IP连接,但说不定
.env文件里的DB_HOST填的是数据库的公网IP或者域名,而域名解析指向了公网地址——这就导致请求直接绕去公网了。 - Web服务器路由表乱了:如果Web服务器有多网卡或者之前改过路由规则,可能系统把172.16.0.0网段的流量错误导向了公网网关,而不是局域网的网关。
- DNS解析拖后腿:要是你用域名连接数据库,本地DNS缓存或者DNS服务器把域名解析到了公网IP,那流量自然走公网了。
二、先排查核心问题(优先解决这些)
1. 先查Laravel的数据库配置
登录Web服务器,进到你的Laravel项目根目录,看看.env里的数据库主机配置:
cd /path/to/your/laravel-project cat .env | grep DB_HOST
要是输出的是公网IP或者域名,赶紧改成数据库服务器的局域网IP(比如172.16.0.x),然后重启你的Web服务(比如PHP-FPM、Nginx或者Apache),让配置生效。
2. 检查Web服务器的路由表
在Web服务器上敲这个命令看路由表:
route -n
找172.16.0.0网段对应的条目,看看Gateway列是不是你的局域网网关(比如172.16.0.1),而不是公网网关。如果这条路由要么不存在,要么网关错了,就添加正确的路由:
# 假设局域网网关是172.16.0.1,添加路由让172.16.0.0/24的流量走局域网 sudo route add -net 172.16.0.0 netmask 255.255.255.0 gw 172.16.0.1
要是想让这个路由重启服务器后还生效,编辑/etc/network/interfaces文件,加一行:
up route add -net 172.16.0.0 netmask 255.255.255.0 gw 172.16.0.1
然后重启网络服务:
sudo systemctl restart networking
3. 排查DNS解析(如果用域名连接数据库)
如果你的DB_HOST填的是域名,在Web服务器上解析一下这个域名看看:
nslookup your-db-domain.com
要是返回的是公网IP,那就是DNS的锅。你可以在Web服务器的/etc/hosts里加一条本地解析,强制让域名指向局域网IP:
echo "172.16.0.x your-db-domain.com" | sudo tee -a /etc/hosts
替换172.16.0.x为数据库的局域网IP,your-db-domain.com是你的数据库域名。
三、关于3306端口转发(备选方案)
如果上面的方法都解决不了,或者你有特殊需求要做端口转发,那可以在Web服务器上用iptables配置转发,把本地3306端口的请求转到数据库的局域网IP的3306端口:
# 先开启IP转发 sudo sysctl -w net.ipv4.ip_forward=1 # 配置转发规则 sudo iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to-destination 172.16.0.x:3306 sudo iptables -t nat -A POSTROUTING -p tcp -d 172.16.0.x --dport 3306 -j SNAT --to-source 172.16.0.y
这里172.16.0.x是数据库的局域网IP,172.16.0.y是Web服务器的局域网IP。
要是想让这些iptables规则重启后不消失,装个iptables-persistent保存规则:
sudo apt-get install iptables-persistent sudo netfilter-persistent save
不过得提醒你:端口转发是备选方案,优先解决路由或者配置问题才是更合理的,毕竟转发会多一层网络开销,不如直接让流量走局域网来得高效。
内容的提问来源于stack exchange,提问作者Hamidreza Bayat

