Linux(28) Linux双网卡配置为连接到Linux主机的PC提供外网访问

在本文中,我将探讨如何为连接到Linux主机的设备提供网络访问。将使用一个实际的故障排查案例来详细说明这个过程,最终实现用脚本完成各项检查和配置工作。


背景:

客户有一个RK3568主板,运行Ubuntu Linux系统。该主板有两个以太网接口:假设定义eth0(内网)和eth1(外网)。客户希望通过RK3568为连接到eth0的Windows PC提供外部网络访问。

简而言之就是Windows PC通过网线连接到RK3568主板的内网口 ,就能在Windows PC访问www.baidu.com(外网)。


Windows PC设置:

PC是Windows 10,需要通过图形界面或命令行来设置默认网关:

  1. 打开“控制面板”。
  2. 选择“网络和共享中心”。
  3. 在左侧,点击“更改适配器设置”。
  4. 右键点击网络连接(可能是“以太网”或类似名称),然后选择“属性”。
  5. 在列表中找到并双击“Internet 协议版本 4 (TCP/IPv4)”。
  6. 选择“使用下面的IP地址”并输入你的IP地址、子网掩码。在“默认网关”中,输入 192.168.52.2
  7. 点击“确定”保存设置。
    在这里插入图片描述
#执行ipconfig简单确认下
ipconfig

在这里插入图片描述


RK3568 Ubuntu设置:

1. 故障排查步骤:

1.配置NAT(网络地址转换)

确保在Linux主机上设置了正确的NAT规则。

root@xxx:/# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables v1.8.4 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

很好这一步就出错了 查下资料 我之前调试RK3399 docker的时候加过iptables nat config , 想起来了 需要在kernel 打开config功能。

那我们先解决iptables nat命令的问题 , 先让kernel boot支持 打开kernel/arch/arm64/configs/rockchip_linux_defconfig进行增加 , 下面有些内容可能不是 先不管了 把配置拷进去 后面再研究。

+CONFIG_TUN=y
+
+#------------iptables
+#CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_INET_ESP=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_IPVS=y
+CONFIG_IP_VS=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_RR=y
+CONFIG_IP_VS_NFCT=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_BRIDGE=y
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_THIN_PROVISIONING=y
+CONFIG_DUMMY=y
+CONFIG_MACVLAN=y
+CONFIG_IPVLAN=y
+CONFIG_VXLAN=y
+CONFIG_VETH=y
+CONFIG_BTRFS_FS=y
+CONFIG_BTRFS_FS_POSIX_ACL=y

编译kernel boot.img 重新烧录到RK3568 系统中, 重启。
重新验证下功能是否可以被执行 , 执行完没有任何报错 这一步完成。

root@xxx:/# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

2. 启用IP转发:

Linux主机必须允许IP转发。

echo 1 > /proc/sys/net/ipv4/ip_forward

并确保在 /etc/sysctl.conf 文件中有以下行:

net.ipv4.ip_forward=1

3. 检 查配置双网口环境:

如果没有一个接口在与试图添加的网关相同的子网上,可能需要配置一个接口来使用这个子网。例如,如果有一个名为 eth0 的接口,可以使用以下命令为其分配一个IP地址:

    ifconfig eth0 192.168.52.2 netmask 255.255.255.0 up

下面这个 ip 命令测试发现没有添加到route 不行不要用

   ip addr add 192.168.52.2/24 dev eth0
   ip link set eth0 up

在这里,192.168.52.2 是一个示例IP地址,你可以选择该子网上的任何可用地址。

root@xxx:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::f5d1:863c:90d8:c00e  prefixlen 64  scopeid 0x20<link>
        ether f6:b2:f0:93:bb:ab  txqueuelen 1000  (Ethernet)
        RX packets 121  bytes 9206 (9.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 47  bytes 7793 (7.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 38

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::1b34:5d25:1cc3:eb3d  prefixlen 64  scopeid 0x20<link>
        ether f2:b2:f0:93:bb:ab  txqueuelen 1000  (Ethernet)
        RX packets 1317  bytes 219566 (219.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 55  bytes 5851 (5.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 43

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 166  bytes 11692 (11.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 166  bytes 11692 (11.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
root@xxx:/# ifconfig eth0 192.168.52.2 netmask 255.255.255.0 up
root@xxx:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.52.2  netmask 255.255.255.0  broadcast 192.168.52.255
        ether f6:b2:f0:93:bb:ab  txqueuelen 1000  (Ethernet)
        RX packets 873  bytes 299601 (299.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 98  bytes 15353 (15.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 38

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::1b34:5d25:1cc3:eb3d  prefixlen 64  scopeid 0x20<link>
        ether f2:b2:f0:93:bb:ab  txqueuelen 1000  (Ethernet)
        RX packets 5035  bytes 782225 (782.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 668  bytes 287954 (287.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 43

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 242  bytes 17162 (17.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 242  bytes 17162 (17.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@xxx:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    102    0        0 eth1
192.168.1.0     0.0.0.0         255.255.255.0   U     102    0        0 eth1
192.168.52.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0

OK 看上面的eth0 已经被配置IP和路由了。

4. 检查网络是否通:

如果Windows 10 PC无法通过RK3568访问外部网络,需要进行一系列的故障排查步骤。

Ping测试
- 从PC上ping RK3568的内部IP地址(192.168.52.2)。确保它是通的。(OK)
- 从RK3568 ping PC的IP地址(192.168.52.1)。确保它也是通的。(OK)
- 从RK3568 ping 外部网站,如8.8.8.8。确保外部网络是通的。(OK)
- 从PC ping 8.8.8.8。如果这不起作用,但上述所有步骤都起作用,那么问题可能与NAT或路由有关。

检查NAT设置:确保在RK3568上正确设置了NAT。再次运行以下命令:

   iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

检查DNS:问题可能与DNS解析有关。尝试从PC ping一个域名,如www.baidu.com。如果这不起作用,但ping 8.8.8.8起作用,可能需要在PC上设置一个静态DNS,如Google的8.8.8.8和8.8.4.4。

RK3568验证:

root@btf:/# ping 192.168.52.1
PING 192.168.52.1 (192.168.52.1) 56(84) bytes of data.
64 bytes from 192.168.52.1: icmp_seq=1 ttl=128 time=1.17 ms
64 bytes from 192.168.52.1: icmp_seq=2 ttl=128 time=1.33 ms
64 bytes from 192.168.52.1: icmp_seq=3 ttl=128 time=1.27 ms
64 bytes from 192.168.52.1: icmp_seq=4 ttl=128 time=0.937 ms
64 bytes from 192.168.52.1: icmp_seq=5 ttl=128 time=1.66 ms
64 bytes from 192.168.52.1: icmp_seq=6 ttl=128 time=3.46 ms
64 bytes from 192.168.52.1: icmp_seq=7 ttl=128 time=1.32 ms
64 bytes from 192.168.52.1: icmp_seq=8 ttl=128 time=1.62 ms
64 bytes from 192.168.52.1: icmp_seq=9 ttl=128 time=1.75 ms
64 bytes from 192.168.52.1: icmp_seq=10 ttl=128 time=1.42 ms
^C
--- 192.168.52.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9015ms
rtt min/avg/max/mdev = 0.937/1.593/3.460/0.663 ms
root@btf:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=110 time=184 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=110 time=186 ms
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 183.646/184.745/185.844/1.099 ms
root@btf:/#

PC Windows验证:
先验证内网通不通 (OK)
在这里插入图片描述
再验证外网通不通(OK)
在这里插入图片描述
其实到这里已经可以上网了 不信你看PC右下角图标 以及打开浏览器。

5. 防火墙设置:

确保Linux主机的防火墙允许流量通过。(这一步我是没弄的 , 如果以上步骤还是不行 可以尝试弄下防火墙)

iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

6. 小节:

如果遇到问题 请详细按照第4步骤检查 , 下面2项是重要的 不要遗漏:

1. 外部连接测试:

从Linux主机ping 8.8.8.8,确保它可以访问外部网络。

2. PC的网络设置:

确保PC的默认网关设置为Linux主机的内部IP地址。


3. 最终可上网状态:

route

ip route

下面是我最终OK可以上网的各项配置。

root@xxx:/# ip route
default via 192.168.1.1 dev eth1 proto dhcp metric 101
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.2 metric 101
192.168.52.0/24 dev eth0 proto kernel scope link src 192.168.52.2
root@xxx:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    101    0        0 eth1
192.168.1.0     0.0.0.0         255.255.255.0   U     101    0        0 eth1
192.168.52.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
root@xxx:/# ifconfig -a
can0: flags=128<NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 55

can1: flags=128<NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 56

dummy0: flags=130<BROADCAST,NOARP>  mtu 1500
        ether f2:4c:f0:78:b5:b0  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.52.2  netmask 255.255.255.0  broadcast 192.168.52.255
        ether f6:b2:f0:93:bb:ab  txqueuelen 1000  (Ethernet)
        RX packets 49950  bytes 15323445 (15.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 43930  bytes 7288991 (7.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 38

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::1b34:5d25:1cc3:eb3d  prefixlen 64  scopeid 0x20<link>
        ether f2:b2:f0:93:bb:ab  txqueuelen 1000  (Ethernet)
        RX packets 55814  bytes 9172054 (9.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 49908  bytes 15222325 (15.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 43

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 202  bytes 16611 (16.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 202  bytes 16611 (16.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

usb0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether ae:0c:29:a3:9b:6d  txqueuelen 1000  (Ethernet)
        RX packets 1  bytes 28 (28.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2  bytes 433 (433.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@xxx:/# cat /etc/sysctl.conf | grep net.ipv4.ip_forward=1
#net.ipv4.ip_forward=1  #后面发现这个不打开其实也是可以的
root@xxx:/# cat /proc/sys/net/ipv4/ip_forward
1 #这个要打开设置为1

7. 脚本:

调试过程中一脸懵逼到逐渐清晰 , 中间也学习了很多概念 也尝试了很多遍 最终反复尝试是找到了设置成符合客户需求的规律 , 命令有些繁琐 按照我的特点 肯定是要搞个脚本自动执行啦。

#!/bin/bash

# 检查参数数量
if [ "$#" -ne 3 ]; then
    echo "使用方法: $0 <内网接口名> <内网接口IP地址> <外网接口名>"
    exit 1
fi

# 获取参数
INTERNAL_IF="$1"
IPADDR="$2"
EXTERNAL_IF="$3"

# 启用IP转发
echo "启用IP转发..."
echo 1 > /proc/sys/net/ipv4/ip_forward

# 清理旧的NAT规则
echo "清理旧的NAT规则..."
iptables -F
iptables -t nat -F

# 清理旧的NAT规则
echo "清理旧的NAT规则..."
iptables -t nat -F

# 设置NAT规则
echo "设置NAT规则..."
iptables -t nat -A POSTROUTING -o $EXTERNAL_IF -j MASQUERADE

# 配置内网接口
echo "配置内网接口 $INTERNAL_IF..."
ip addr add $IPADDR/24 dev $INTERNAL_IF
ip link set $INTERNAL_IF up

# 打印网络接口信息
echo "当前网络接口信息:"
ip addr



# 测试外网连接
echo "测试外网连接..."
ping -c 4 8.8.8.8

echo "脚本执行完毕!"

现在 可以使用以下命令来运行脚本:

./enable_nat_routing.sh eth0 192.168.52.2 eth1

脚本执行结果:

root@btf:/opt# ./enable_nat_routing.sh
使用方法: ./enable_nat_routing.sh <内网接口名> <内网接口IP地址> <外网接口名>
root@btf:/opt# ./enable_nat_routing.sh eth0 192.168.52.2 eth1
启用IP转发...
清理旧的NAT规则...
设置NAT规则...
配置内网接口 eth0...
当前网络接口信息:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether aa:e4:19:76:54:43 brd ff:ff:ff:ff:ff:ff
3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can
4: can1: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can
5: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether f6:b2:f0:93:bb:ab brd ff:ff:ff:ff:ff:ff
    inet 192.168.52.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::f5d1:863c:90d8:c00e/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
6: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether f2:b2:f0:93:bb:ab brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 brd 192.168.1.255 scope global dynamic noprefixroute eth1
       valid_lft 86348sec preferred_lft 86348sec
    inet6 fe80::1b34:5d25:1cc3:eb3d/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
7: usb0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether ae:0c:29:a3:9b:6d brd ff:ff:ff:ff:ff:ff
当前路由信息:
default via 192.168.1.1 dev eth1 proto dhcp metric 102
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.2 metric 102
192.168.52.0/24 dev eth0 proto kernel scope link src 192.168.52.2
测试外网连接...
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=110 time=286 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=110 time=283 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=110 time=283 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=110 time=289 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 282.528/285.120/289.283/2.689 ms
脚本执行完毕!

补充:
后面测试发现 route规则会突然消失,并且ifconfig eth0 ip也没了。

root@xxx:/opt# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    102    0        0 eth1
192.168.1.0     0.0.0.0         255.255.255.0   U     102    0        0 eth1

正常情况

root@xxx:/opt# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    102    0        0 eth1
192.168.1.0     0.0.0.0         255.255.255.0   U     102    0        0 eth1
192.168.52.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0

总结:

为连接到Linux主机的设备提供网络访问可能需要多个配置步骤。通过仔细地检查每个配置和进行逐步的故障排查,我们可以成功地解决这类问题。


希望这篇博客对你有所帮助!

猜你喜欢

转载自blog.csdn.net/SHH_1064994894/article/details/132535837