In this article, I will explore how to provide network access to devices connected to a Linux host. An actual troubleshooting case will be used to explain this process in detail, and finally the script will be used to complete various inspections and configuration work.
background:
The customer has a RK3568 motherboard running Ubuntu Linux system. This motherboard has two Ethernet interfaces: Assume that eth0 (internal network) and eth1 (external network) are defined. The customer wants to provide external network access via RK3568 to a Windows PC connected to eth0.
In short, the Windows PC is connected to the internal network port of the RK3568 motherboard through a network cable, and then www.baidu.com (external network) can be accessed from the Windows PC.
Windows PC settings:
The PC is Windows 10 and the default gateway needs to be set through the graphical interface or command line:
- Open the Control Panel.
- Select Network and Sharing Center.
- On the left, click "Change adapter settings."
- Right-click on the network connection (probably "Ethernet" or something similar) and select "Properties."
- Find and double-click "Internet Protocol Version 4 (TCP/IPv4)" in the list.
- Select "Use the following IP address" and enter your IP address and subnet mask. In Default Gateway, enter
192.168.52.2
. - Click "OK" to save the settings.
#执行ipconfig简单确认下
ipconfig
RK3568 Ubuntu settings:
1. Troubleshooting steps:
1. Configure NAT (Network Address Translation)
Make sure you have the correct NAT rules set up on your Linux host.
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.
Very good, this step went wrong. Check the information. I added iptables nat config when debugging RK3399 docker before, and then I remembered that I need to turn on the config function in the kernel.
Let's first solve the problem of the iptables nat command. First, let the kernel boot support be opened kernel/arch/arm64/configs/rockchip_linux_defconfig
and added. Some of the following content may not be ignored first, copy the configuration into it and study it later.
+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
Compile kernel boot.img and re-burn it into the RK3568 system and restart.
Re-verify whether the function can be executed. If no error is reported after execution, this step is completed.
root@xxx:/# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
2. Enable IP forwarding:
The Linux host must allow IP forwarding.
echo 1 > /proc/sys/net/ipv4/ip_forward
And make sure /etc/sysctl.conf
you have the following lines in the file:
net.ipv4.ip_forward=1
3. Check the configuration of dual network port environment:
If there is not an interface on the same subnet as the gateway you are trying to add, you may need to configure an interface to use this subnet. For example, if you have an eth0
interface named , you can assign it an IP address using the following command:
ifconfig eth0 192.168.52.2 netmask 255.255.255.0 up
The following ip
command was tested and found to be not added to the route. If it does not work, do not use it :
ip addr add 192.168.52.2/24 dev eth0
ip link set eth0 up
Here, 192.168.52.2
is a sample IP address, you can choose any available address on that subnet.
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 See that eth0 above has been configured with IP and routing.
4. Check whether the network is connected:
If your Windows 10 PC cannot access the external network through RK3568, you need to perform a series of troubleshooting steps.
Ping test :
- Ping the RK3568's internal IP address (192.168.52.2) from the PC. Make sure it's open. (OK)
- Ping the PC's IP address (192.168.52.1) from the RK3568. Make sure it's passable too. (OK)
- Ping an external website from RK3568, such as 8.8.8.8. Make sure the external network is accessible. (OK)
- ping 8.8.8.8 from PC. If this doesn't work, but all of the above steps do, the problem may be with NAT or routing.
Check NAT settings : Make sure NAT is set up correctly on the RK3568. Run the following command again:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Check DNS : The problem may be related to DNS resolution. Try pinging a domain name from your PC, eg www.baidu.com
. If this doesn't work, but pinging 8.8.8.8 does, you may need to set up a static DNS on your PC, such as Google's 8.8.8.8 and 8.8.4.4.
RK3568 verification:
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 verification:
first verify that the internal network is not accessible (OK)
and then verify that the external network is not accessible (OK).
In fact, you can already access the Internet here. If you don’t believe it, look at the icon in the lower right corner of the PC and open the browser.
5. Firewall settings:
Make sure the Linux host's firewall allows traffic. (I didn’t do this step. If the above steps still don’t work, you can try to remove the firewall)
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
6. Section:
If you encounter problems, please follow step 4 to check in detail. The following two items are important and do not miss them:
1. External connection test:
Ping 8.8.8.8 from the Linux host to make sure it can access the external network.
2. PC network settings:
Make sure the PC's default gateway is set to the Linux host's internal IP address.
3. Final Internet access status:
route
or
ip route
Below are the various configurations that finally made me OK and able to access the Internet.
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. Screenplay:
During the debugging process, I was confused and gradually became clear. I also learned a lot of concepts and tried many times. Finally, after repeated attempts, I found a pattern that meets the needs of the customer. The commands are a bit cumbersome. According to my characteristics, I must create a script to automate it. Executed.
#!/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 "脚本执行完毕!"
You can now run the script using the following command:
./enable_nat_routing.sh eth0 192.168.52.2 eth1
Script execution results:
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
脚本执行完毕!
Supplement:
Later tests found that the route rules would suddenly disappear, and the ifconfig eth0 ip was also gone.
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
normal circumstances
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
Summarize:
Providing network access to devices connected to a Linux host can require multiple configuration steps. By carefully examining each configuration and performing step-by-step troubleshooting, we can successfully resolve these types of issues.
Hope this blog is helpful to you!