
两台Linux要“互通”看似简单翻来覆去就是配IP、改路由、放防火墙但真正落到生产环境或自建实验室里各种奇怪问题会接踵而来。我去年帮朋友搭一套内网测试环境两台服务器就隔着一个交换机结果整整折腾了一个下午最后发现是网卡配置文件里的一个小参数写错了。这篇文章就把我这些年配置Linux互通的真实经验从头捋一遍从网络基础模型到具体配置文件从防火墙排查到多网卡和容器场景按最常踩坑的顺序拆开讲。如果你是刚接触Linux运维或者准备参加相关岗位面试这篇文章能帮你把“互通”这件事从命令行操作上升到整体网络思维如果你已经在生产环境摸爬过一段时间相信下面的故障排查链路和配置细节也能让你少走几次弯路。1. 先把“互通”这件事拆开你需要的到底是哪几层通很多人拿到两台Linux机器上来就pingping不通就说网络不通。但“互通”其实是个分层概念我在正式动手前习惯先列一张需求清单搞清楚用户到底要什么。1.1 五层互通模型先对号入座结合实际的运维和开发场景我把 Linux 主机之间的“互通”拆成五个层次层次含义验证工具典型故障链路层网卡是否识别、网线/交换机是否正常ip link、ethtool网卡down、网线松动网络层IP、路由、ARP是否可达ping、ip route、arpIP冲突、网关缺失传输层端口是否放行、服务是否监听telnet、nc、ss防火墙拦截、服务未启动应用层SSH/NFS/HTTP等服务是否正常ssh、curl、mount认证失败、SELinux拦截加密互信层密钥验证、证书信任ssh-keygen、openssl权限错误、known_hosts冲突这个模型不是学术空谈。实际排错时我从来都是按链路层、网络层、传输层、应用层的顺序逐层排查跳层排查往往会把问题搞复杂。比如有一次某台机器能ping通但SSH连不上新手直接去看ssh服务但我习惯先确认防火墙和端口监听因为“能ping通”只代表网络层通传输层的TCP 22端口可能压根没放行。1.2 先规划再动手第个网段分配表配置互通之前我最推荐先画一张网络拓扑简图不需要多专业把这几样标清楚就行每台主机的IP地址和子网掩码网关IP如果有三层设备需要开放的端口清单SSH用22NFS用2049数据库用3306/5432等哪些是临时测试哪些要写死进配置文件我自己踩过的坑早期给实验环境配互通时随手把两台机器配成了完全相同的IP结果两台机器反复掉线ARP冲突导致交换机端口一会儿通一会儿断。后来我买了块小白板专门记IP分配表这个习惯再也没变过。在真实环境里我甚至会顺手写上“这台机器谁在用、什么时候会重启”避免测试时误伤别人正在跑的服务。2. 手把手配置从固定IP到路由表不做表面功夫互通的基础是网络层可达这一段我把Linux两种主流系统的IP配置和路由配置完整写出来。不要再告诉我你用ifconfig临时配一下就行重启就丢配置这种事生产环境没人陪你玩。2.1 立刻生效的地址配置 vs 永久生效的配置文件临时配置适合快速验证# 给ens33配置临时IP/24是常见的子网写法 sudo ip addr add 192.168.1.10/24 dev ens33 # 激活网卡 sudo ip link set ens33 up # 添加默认网关 sudo ip route add default via 192.168.1.1 # 删除临时IPcleanup时很有用 sudo ip addr del 192.168.1.10/24 dev ens33但请注意ip addr add配置的地址不会写入配置文件系统重启后全部丢失。生产环境必须直接操作网卡配置文件。2.2 Rocky Linux / CentOS 系网卡配置文件全解析Red Hat 系的网卡配置文件位于/etc/sysconfig/network-scripts/一般命名规则是ifcfg-网卡名比如ifcfg-ens33。很多人配置互通失败要么是字段拼写错误要么是BOOTPROTO忘记改成static。下面是最小可用配置# /etc/sysconfig/network-scripts/ifcfg-ens33 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic # 静态IP必须写staticdhcp表示自动获取 DEFROUTEyes NAMEens33 DEVICEens33 ONBOOTyes # 开机自动启用网卡忘了这个就等着开机断网 IPADDR192.168.1.10 PREFIX24 # 等价于NETMASK255.255.255.0 GATEWAY192.168.1.1 # 默认网关跨网段互通全靠它 DNS1223.5.5.5这里有两个关键细节我在生产里吃过大亏PREFIX和NETMASK二选一即可但如果两个都写了而且值冲突NetworkManager会按PREFIX优先曾经有台机器子网掩码一直不对排查半天才发现是NETMASK写错而PREFIX正常。DEFROUTEyes表示把默认路由交给这张网卡。多网卡机器如果两张网卡都写DEFROUTEyes路由表会互相打架导致访问外部网络时走错出口。正确做法是只让主用网卡开启备份网卡或管理网卡设成DEFROUTEno。改完配置执行# 重启网络服务不同版本命令有差异 sudo systemctl restart network # 或者用NetworkManager重新加载 sudo nmcli connection reload sudo nmcli connection up ens33验证时不要只看ping自己的IP要分别ping网关、ping对端主机、ping公网地址三层各来一次才能定位转发链路是否完整。2.3 Ubuntu / Debian 系Netplan 是当前主流Ubuntu 18.04 之后默认用 Netplan配置文件在/etc/netplan/下通常是01-network-manager-all.yaml或99-config.yaml。一个典型配置# /etc/netplan/99-static.yaml network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false addresses: - 192.168.1.10/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 223.5.5.5注意Netplan对YAML缩进极其敏感多一个空格都可能报错。改完后先检查再应用sudo netplan try # 尝试应用如果断连超过120秒会自动回滚这是保命命令 sudo netplan apply # 确认无误后正式生效netplan try是个被很多人忽略的好东西。远程连接服务器时如果配置文件写错导致网络中断它会在超时后自动回滚配置把你从“ssh断开了但啥都干不了”的窘境里救出来。我第一次用Netplan时不知道这个命令直接在云服务器上执行apply结果把自己关在了门外最后只能通过管理终端进去改。2.4 静态路由的补充内网多网段怎么通两台机器在同一网段时只要IP配好就能互通。但如果一台在192.168.1.0/24另一台在192.168.2.0/24就必须有路由器和静态路由来桥接。给特定内网网段添加静态路由# 到192.168.2.0/24网段下一跳是192.168.1.1 sudo ip route add 192.168.2.0/24 via 192.168.1.1 # 永久写入Rocky/CentOS系在网卡配置文件里追加 # 或者单独添加路由配置文件 sudo vim /etc/sysconfig/network-scripts/route-ens33route-ens33文件内容格式192.168.2.0/24 via 192.168.1.1Ubuntu系则在Netplan的routes段下追加routes: - to: 192.168.2.0/24 via: 192.168.1.1配置路由后互相ping对端主机时最好在两端都开一个tcpdump -n -i ens33 icmp抓包看看。我遇到过一种情况主机A能ping通网关网关也能ping通主机B但A到B就是不通。抓包后发现A发出的ICMP请求到了B但B的回应走了另一条错误的默认路由变成了异步路由直接被B侧网关丢弃。这种问题光看本地路由表根本看不出毛病必须两头抓包结合看。3. SSH互信与文件互传互通不只是能ping通IP通了只是第一步。绝大多数场景下所谓Linux互通最终都要落到“能远程登录、能传文件、能免密执行命令”这个层面。所以我单独把SSH互信提出来讲这是日常运维里最常用但坑也最多的环节。3.1 SSH密钥认证的完整配置流程假设有两台机器A192.168.1.10需要免密登录B192.168.1.20。在A机器上执行# 生成密钥对-t指定加密算法-b指定位数 ssh-keygen -t rsa -b 4096 -N -f ~/.ssh/id_rsa # 一键推送到B机器 ssh-copy-id -i ~/.ssh/id_rsa.pub user192.168.1.20-N 表示空密码-f指定密钥文件路径。如果你已经有密钥但不确定能否免密登录可以用ssh -v user192.168.1.20查看详细认证过程-v参数输出的日志里能看到它用了哪些认证方法。ssh-copy-id 本质上是把你的公钥追加到目标机~/.ssh/authorized_keys文件里。如果服务器端的sshd配置比较严格也可能导致推送失败常见报错和解决办法我放在3.3节。3.2 免密失效的经典场景权限、属主、SELinux很多初学者配置完SSH免密登录后发现第一次能登录但换了用户或重启后就用不了。最常见的原因是权限不对。SSH对密钥相关文件的权限要求很严格# 目标机器上需要确保 chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_rsa如果权限过松比如 authorized_keys 是644sshd会直接忽略这个文件。我曾经在CentOS上调试到怀疑人生最后 sshd -T 一查日志明确写着“Authentication refused: bad ownership or modes”。另外还有两个容易被忽视的坑SELinux上下文错误。在RHEL/Rocky系机器上如果/root/.ssh/authorized_keys是从其他目录复制过来的SELinux上下文可能不对。排查方法ls -Z /root/.ssh/authorized_keys # 如果不是 ssh_home_t则执行 restorecon -Rv /root/.sshsshd_config里的AuthorizedKeysFile被改过。有的安全基线会把这个路径改到别处导致你明明配好了却还是提示密码。排查时看/etc/ssh/sshd_config里的AuthorizedKeysFile .ssh/authorized_keys这一行。3.3 按场景选传输工具scp、rsync还是sftp文件互传也是互通的刚需经验上看场景推荐工具理由单文件快速拷贝scp简单直接安全性有保证目录批量同步rsync支持增量、压缩、断点续传交互式远程文件管理sftp类似FTP体验基于SSH加密日常备份和同步我几乎只用rsync# 从A机器把/data目录增量同步到B机器 rsync -avz --delete /data/ user192.168.1.20:/backup/data/ # 跨机器拷贝时限制带宽避免占满业务带宽 rsync -avz --bwlimit2048 /data/ user192.168.1.20:/backup/--delete表示源端删除的文件目标端也删除让目标完全镜像源端。但这条参数非常危险我用它误删过一次生产备份从那以后凡是带--delete的同步命令都会先加--dry-run空跑一遍看输出属实是拿教训换来的习惯。scp虽然简单但大目录拷贝不如rsync稳定。如果你需要断点续传scp是做不到的scp的旧版实现即使标记支持真实场景下也经常失败rsync配合--partial才能实现。3.4 sshd_config里几个影响互通的细节服务端配置对互通的体验影响很大我列出生产中最常用的几个调整项# /etc/ssh/sshd_config PermitRootLogin prohibit-password # 禁止root密码登录但允许密钥登录 PasswordAuthentication yes # 是否允许密码认证 PubkeyAuthentication yes # 启用公钥认证 AllowUsers user1 user2 # 白名单用户不在名单内直接拒绝 MaxSessions 10 # 单连接最大会话数注意改完sshd_config一定要先测再重启sudo sshd -t # 语法检查这一步能拦住绝大部分低级错误 sudo systemctl reload sshdsshd -t是个特别有用的命令它只检查配置语法不会重启服务。我在批量修改服务器配置时都会在脚本里强制执行sshd -t失败了就直接中断后续操作避免一台台机器连不上。4. 防火墙与SELinux它俩比你想象的更容易成为拦路虎IP和路由都正常SSH也配好了但两台Linux还是无法互通时绝大部分原因出在防火墙和SELinux。这两个东西是有层级的我按实际排错顺序来说。4.1 firewalld、iptables、nftables的底层关系Red Hat系从CentOS 7开始默认用firewalld但firewalld底层仍然是iptables或者nftables。Ubuntu则是ufw比较常见。改防火墙策略时很多人搞不清楚“我改了firewalld为什么iptables -L看不到变化”其实firewalld会把规则写入iptables的mangle或filter表只是它自己维护了一套XML配置。常用命令直接抄# firewalld永久放行某端口 sudo firewall-cmd --permanent --add-port3306/tcp # 重载使其生效 sudo firewall-cmd --reload # 查看当前已放行端口 sudo firewall-cmd --list-ports # 临时放行重启后失效 sudo firewall-cmd --add-servicessh生产里我不太建议直接关防火墙哪怕在内网也一样。我见过内网两台机器为了省事直接systemctl stop firewalld结果中病毒后横向扩散整个内网直接沦陷。正确做法是精确放行业务端口和管理地址段。firewall-cmd的--permanent和--reload顺序也有讲究只加--permanent不reload规则不会生效只reload不加--permanent规则会丢失。所以常规操作是先加permanent再reload。4.2 SELinux布尔值SSH和NFS最常见的隐形拦截很多运维习惯性地在/etc/selinux/config里把SELINUXdisabled生产环境这么干不是不可以但既然后面要讲NFS互通就必须提一下SELinux对服务的影响。NFS共享配好后客户端挂载时报Permission denied但服务端怎么看都正常。在这个问题上SELinux是头号嫌疑。查看是否被SELinux拦截sudo ausearch -m avc -ts recent如果确实被拦截业务上需要放开NFS相关的布尔值sudo setsebool -P nfs_export_all_rw 1 sudo setsebool -P nfs_export_all_ro 1 # 如果访问挂载点时SELinux上下文错误还可能需要 sudo setsebool -P use_nfs_home_dirs 1-P参数表示持久化重启后依然生效。在这里我想强调一个原则优先调整SELinux布尔值而不是直接禁用SELinux。setsebool -P改的是策略开关setenforce 0是临时禁用而/etc/selinux/config改成disabled是永久禁用。永久禁用的代价是后续任何安全问题都少了一层内核级防护。类似的场景还有允许SSH访问家目录如果你用root做一个特殊服务通过SSH读取其他用户家目录时遇到Permission denied很可能需要setsebool -P ssh_sysadm_login 1。4.3 从“ping通”到“端口不通”的完整排查链路这部分是我最想重点写的。很多人遇到端口不通上来就telnet目标端口失败后直接说被墙了。其实完整的排查链路应该是这样的先确认网络层通ping 目标IP。如果ping不通回到第2章的IP和路由部分排查。再确认对端端口在监听在目标机器上执行ss -lnpt | grep 3306看端口是否有进程监听。没有进程监听就谈不上防火墙拦截。确认本机到对端路由正常ip route get 192.168.1.20看返回的路由出口和网卡确认没走错路。传输层测试执行nc -vz 192.168.1.20 3306或telnet 192.168.1.20 3306。连接失败时看报错信息是“Connection refused”端口没监听或SELinux拒绝还是“No route to host”网络层不通。逐层排查防火墙先在你自己的执行机上iptables -L -n防止本机防火墙挡住出站再到目标机上执行firewall-cmd --list-ports。如果两边防火墙都放行了还不通关掉目标机防火墙做对照测试sudo systemctl stop firewalld nc -vz 192.168.1.20 3306如果关闭后能通说明规则没配对如果关闭后还是不通那就不是防火墙问题回头查SELinux或服务本身。看SELinux日志ausearch -m avc -ts recent这条命令的输出能直接告诉你哪个进程被SELinux拒绝。我处理过一起经典案例MySQL在A机器监听3306B机器telnet不通但A本机通过127.0.0.1连接完全正常。走到第5步时我关了A的firewalldB机器还是不通再跑到A上执行ss -lnpt发现MySQL只监听了127.0.0.1:3306根本没监听0.0.0.0。这时防火墙纯粹是背锅的——问题在MySQL配置里的 bind-address 没改成0.0.0.0或具体内网IP。5. 进阶场景实战虚拟机、双网卡与容器环境下的互通配置基础的两两互通配置学会后现实中的复杂场景更多。我把平时被问得最多、也最容易出问题的三类场景挑出来单独处理。5.1 虚拟机与宿主机互通虚拟机的网卡模式决定一切用 VMware 或 VirtualBox 跑Linux虚拟机时“宿主机访问虚拟机不通”是高频问题。核心在于虚拟网卡的工作模式模式虚拟机与宿主机虚拟机访问外网说明NAT通通虚拟机在虚拟NAT网段宿主机能访问但外部主机不能直接访问桥接通通虚拟机直接占用局域网IP和宿主机处于同一广播域仅主机通不通只能与宿主机互通适合隔离测试生产学习和测试我最推荐桥接模式。把虚拟机的网络适配器设置为“桥接模式”后在虚拟机里执行dhclient或者按第2章配置静态IP让它和宿主机在同一个网段就能像两台物理机一样互通。如果用的是NAT模式宿主机访问虚拟机一般没问题但虚拟机访问宿主机要特别注意防火墙。宿主机Windows防火墙经常拦截来自VMware NAT网段的流量最简单的做法是在Windows防火墙里放行对应虚拟网卡。在 VMware 里还有个常见问题桥接模式选错了桥接网卡。如果宿主机有线和无线网卡并存虚拟机默认桥接到无线网卡结果有线局域网里的其他机器访问不到虚拟机。这时候去VMware虚拟网络编辑器里手动指定桥接到实际在用的物理网卡就好。5.2 双网卡主备与策略路由不是所有流量都走默认网关双网卡是服务器常见的配置一个网卡接办公网或管理网另一个网卡接业务内网。如果配置不当默认路由只走其中一张网卡导致另一张网卡对应的网段不可达。解决办法除了前面提到的DEFROUTEno还有policy routing策略路由。策略路由的典型配置思路是单独给业务网卡建一个路由表# 新建一张自定义路由表编号100名称business echo 100 business /etc/iproute2/rt_tables # 添加业务网段的路由表项 sudo ip route add 192.168.100.0/24 dev eth1 table business # 添加默认路由指向业务网关 sudo ip route add default via 192.168.100.1 dev eth1 table business # 使用ip rule把来自业务网段的流量导向business表 sudo ip rule add from 192.168.100.0/24 table business priority 100这套配置的意义在于来自业务网卡的流量会优先查询business路由表而不会被全局默认路由带偏。生产环境比如双专线接入或者内网与公网隔离的堡垒机场景策略路由非常常见。有时候光改配置文件不行还必须把上面的命令写入开机自启动脚本里因为ip route命令本身不持久化。5.3 Docker容器与宿主机及外部主机的互通Docker环境下的“互通”有另一套概念。默认安装Docker后会创建一个docker0虚拟网桥宿主机通过它和容器通信。容器要访问外部主机默认需要开启IP转发# 查看是否开启IP转发 sysctl net.ipv4.ip_forward # 临时开启 echo 1 /proc/sys/net/ipv4/ip_forward # 永久开启 vim /etc/sysctl.d/99-sysctl.conf # 加入 net.ipv4.ip_forward 1然后执行 sysctl -p如果你在宿主机上能访问容器IP但另一台物理机无法访问容器通常有两个原因容器使用的端口没有映射到宿主机。最常见的做法是在docker run时加-p 8080:80这样外部主机的8080端口流量会转发到容器的80端口。宿主机防火墙没有放行映射端口。Docker会自己在iptables里写入DNAT规则但如果你的防火墙规则顺序不对可能会把Docker的流量提前DROP掉。排查时执行iptables -t nat -L -n看DOCKER链的规则是否存在。容器与宿主机互通还有一种情况Docker默认网桥的IP网段和局域网冲突。比如容器网段刚好也是192.168.1.0/24结果局域网里的机器访问192.168.1.10时路由可能被Docker网桥截胡。解决办法是修改/etc/docker/daemon.json指定bipbridge IP比如{ bip: 172.30.0.1/24 }改完重启Docker容器网段就不会和现有局域网冲突了。这个坑在生产环境很隐蔽因为不是每次都会冲突只有当局域网设备发起跨网段访问时才暴露。5.4 嵌入式开发板与PC互通串口与网口的配合如果有搞嵌入式Linux的朋友热搜词里有一条“linux 网口转串口服务器”大概说的是硬件设备但在开发板调试场景中最经典的需求是开发板通过串口输出日志同时通过网口与PC互通。这时候开发板默认配置往往是DHCP而开发板所在网络没有DHCP服务器或者网口直连PC但没有IP。建议给PC的有线网卡配一个静态IP比如192.168.1.100/24给开发板的网络配置文件指定同一网段的静态IP比如192.168.1.101/24然后使用网线直连。接着在PC上ping 192.168.1.101 ssh root192.168.1.101配置开发板网络时不同的文件系统配置位置不太一样。Buildroot系统通常用/etc/network/interfacesYocto系统在/etc/systemd/network/下处理调整前先看看/sys/class/net/下有哪些网卡别一门心思找eth0接口名可能是enp0s3或者end0。开发板互通还有一个要素如果开发板的串口也接到了PC上记得同时开两个终端一个接串口控制台一个跑ssh。出现网络问题还能通过串口进去改配置不至于变砖。我刚开始接触开发板那会儿就是靠串口救回来好几块网络配置写错的板子。6. 互通配置完成后还差这几步验证配置完成后不验证就走等于白干。我给你一套每次配完互通都会跑的验收清单照着做能提前发现隐藏问题。6.1 基础连通性验证脚本#!/bin/bash # 一个简单的互通验收脚本保存为check_connect.sh TARGET192.168.1.20 PORTS(22 3306 2049) # 网络层 ping -c 3 $TARGET /dev/null 21 if [ $? -eq 0 ]; then echo [OK] ping $TARGET else echo [FAIL] ping $TARGET fi # 传输层 for port in ${PORTS[]}; do timeout 3 bash -c echo /dev/tcp/$TARGET/$port 2/dev/null if [ $? -eq 0 ]; then echo [OK] port $port reachable else echo [FAIL] port $port not reachable fi done/dev/tcp是bash内置的特殊文件不用额外安装工具就能测试端口。这个脚本在最小化安装的Linux上也能跑比nc和telnet更省事。6.2 双向互通的回程验证ping只能证明对端回了ICMP报文但业务流量是双向的。如果A能ping通B但B不能ping通A说明A的防火墙拦了发往B的ICMP响应或者A有丢包。我做过一个比较典型的测试在A机器上执行tcpdump -i any icmp -n同时从B机器ping A如果A收到了ICMP请求但没有发出响应基本可以断定A的防火墙把ICMP响应挡了。在Rocky Linux上需要检查firewalld是否放行ICMPsudo firewall-cmd --list-icmp-blocks # 如果返回有问题可以放行echo-reply sudo firewall-cmd --permanent --add-icmp-block-inversion sudo firewall-cmd --reload如果A的tcpdump完全没抓到包那问题在B到A的二层链路或路由上。这套双向验证的办法帮我抓出过好几台“单向通”的机器。说白了互通是双向的来回路径可能完全不同只看一个方向永远会漏问题。6.3 长期稳定性的监控建议配置完成不等于永久稳定。在长期生产环境中我习惯把互通探活写进定时任务每分钟发一个TCP探活包到关键端口失败了就触发告警*/1 * * * * timeout 5 bash -c echo /dev/tcp/192.168.1.20/22 || echo ssh down /var/log/net_check.log当然这只是个极简示例生产环境可以用Zabbix或者Prometheus黑盒探针来做。核心思路是互通的验证不是一次性的你要通过主动探活尽早感知到链路异常而不是等用户报障才发现两台机器已经断了半天。写在最后从配置IP到放行防火墙从SSH免密到双网卡策略路由Linux互通涉及到的知识点非常碎片化。我个人最大的体会是不要把互通看成一条命令或一个配置它是一条完整的链路每一层都可能断。解决问题的关键不是背命令而是建立分层排查的思维。再分享一个让我记忆深刻的教训有一次两台服务器怎么都ping不通我从IP查到路由、从防火墙查到SELinux折腾近两个小时最后才发现交换机上插的两根网线全是百兆协商且其中一根线序有问题。从那以后我的排错流程永远从物理层开始——先看网卡状态再看交换机指示灯然后才进系统排查。这套顺序看起来笨但能帮你绕开大量看似“软件问题”的硬件坑。希望这篇文章里的配置过程、排查顺序和那些“血泪教训”能让你在配置Linux互通这条路上少走我一多半的弯路。