linux环境使用iptables配置NAT访问外部网络

使用type-c数据线连接电脑后, 出现了一个新的网卡

dmesg -T 显示如下:

[Sun Aug 27 19:59:28 2023] usb 3-5: new high-speed USB device number 8 using xhci_hcd
[Sun Aug 27 19:59:28 2023] usb 3-5: New USB device found, idVendor=3346, idProduct=1009, bcdDevice= 5.10
[Sun Aug 27 19:59:28 2023] usb 3-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Sun Aug 27 19:59:28 2023] usb 3-5: Product: RNDIS
[Sun Aug 27 19:59:28 2023] usb 3-5: Manufacturer: Cvitek
[Sun Aug 27 19:59:28 2023] usb 3-5: SerialNumber: 0123456789
[Sun Aug 27 19:59:28 2023] rndis_host 3-5:1.0 usb0: register 'rndis_host' at usb-0000:00:14.0-5, RNDIS device, 72:80:5a:ac:54:4f
[Sun Aug 27 19:59:28 2023] rndis_host 3-5:1.0 enp0s20u5: renamed from usb0

使用ip命令查看网卡状态

ip a
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 noprefixroute
       valid_lft forever preferred_lft forever
3: enp6s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:e0:af:b7:01:bd brd ff:ff:ff:ff:ff:ff
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 04:cf:4b:21:d1:1c brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.212/24 brd 192.168.2.255 scope global dynamic noprefixroute wlan0
       valid_lft 57551sec preferred_lft 57551sec
    inet6 fe80::6cf:4bff:fe21:d11c/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever
8: enp0s20u5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 72:80:5a:ac:54:4f brd ff:ff:ff:ff:ff:ff

其中enp0s20u5 网卡是RNDIS驱动的网卡设备, wlan0是我链接家庭路由器的网卡.

在这样的初始状态下, 虽然Milk-V Duo内部固定了ip地址 192.168.42.1/24, 但是没有路由, 所以现在是没法ping通或者ssh连接到开发板的.

这里的 enp0s20u5 其实就充当了网关的角色, 我们需要把主机上的网卡给UP起来, 并且给他配置一个ip:

ip a add 192.168.42.254/24 dev enp0s20u5
ip l set enp0s20u5 up

现在检查一下状态

ip a show enp0s20u5
8: enp0s20u5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 72:80:5a:ac:54:4f brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.254/24 scope global enp0s20u5
       valid_lft forever preferred_lft forever
    inet6 fe80::7080:5aff:feac:544f/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever

现在发现能ping通开发板固定的ip地址192.168.42.1了:

ping 192.168.42.1
PING 192.168.42.1 (192.168.42.1) 56(84) bytes of data.
64 bytes from 192.168.42.1: icmp_seq=1 ttl=64 time=0.650 ms
64 bytes from 192.168.42.1: icmp_seq=2 ttl=64 time=0.322 ms
64 bytes from 192.168.42.1: icmp_seq=3 ttl=64 time=0.324 ms

现在我们能正常ssh连接上去:

[root@archlinux ~]# ssh root@192.168.42.1
root@192.168.42.1's password:
[root@milkv]~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN qlen 1000
    link/ether 4a:7c:ad:96:7a:e6 brd ff:ff:ff:ff:ff:ff
3: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 7e:d3:33:9a:4a:21 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.1/24 brd 192.168.42.255 scope global usb0
       valid_lft forever preferred_lft forever

不过还是没法访问外部网络, 原因:

  1. 没有配置默认路由, 找不到
  2. 没有配置域名解析地址(可选)
  3. (最重要的是) 宿主机与Duo开发板目前只存在直连的路由, 访问不了 192.168.42.0/24 以外的网段.

所以接下来我们依次解决这几个问题

  1. 配置开发板默认路由
[root@milkv]~# ip r
192.168.42.0/24 dev usb0 scope link  src 192.168.42.1
[root@milkv]~# ip r add default via 192.168.42.254
[root@milkv]~# ip r
default via 192.168.42.254 dev usb0
192.168.42.0/24 dev usb0 scope link  src 192.168.42.1
  1. 配置域名解析地址
[root@milkv]~# echo 'nameserver 114.114.114.114' >> /etc/resolv.conf
[root@milkv]~# cat /etc/resolv.conf
# Generated by dhcpcd
# /etc/resolv.conf.head can replace this line
# /etc/resolv.conf.tail can replace this line
nameserver 114.114.114.114
  1. 配置宿主机上的iptables规则, 开启SNAT(源地址转换), 注意这一步配置不是在Milk-V Duo开发板上.
iptables -t nat -A POSTROUTING -s 192.168.42.0/24 -o wlan0 -j MASQUERADE

# 检查一下
# iptables -t nat -S
# 删除这条规则
# iptables -t nat -D POSTROUTING -s 192.168.42.0/24 -o wlan0 -j MASQUERADE

另外还需要检查一下内核配置, 是否开启了转发功能, 如果没有, 需要通过sysctl开启:

# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
# sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

现在再进到开发板, 可以发现现在已经能够正常访问外部网络了:

[root@milkv]~# ping baidu.com
PING baidu.com (39.156.66.10): 56 data bytes
64 bytes from 39.156.66.10: seq=0 ttl=44 time=32.189 ms
64 bytes from 39.156.66.10: seq=1 ttl=44 time=31.949 ms
64 bytes from 39.156.66.10: seq=2 ttl=44 time=76.551 ms
^C
--- baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 31.949/46.896/76.551 ms
[root@milkv]~# wget baidu.com
Connecting to baidu.com (110.242.68.66:80)
saving to 'index.html'
index.html           100% |********************************|    81  0:00:00 ETA
'index.html' saved
4 Likes

啊啊啊啊啊太感谢楼主了,我一直在想怎样让duo联网,这下知道了 :star_struck:

昨天研究 iptables 不成功,今天准备再试试

Man, you really saved the day! Thank you!

Tips: the better command to find the network adapter name is:
~$ ls /sys/class/net
enp0s25 lo usb0

In the first section “dmesg -T”, My Linux machine doesn’t rename RNDIS to enp0s20u5.

[Mon Feb 26 18:15:39 2024] usb 3-4: new high-speed USB device number 3 using xhci_hcd
[Mon Feb 26 18:15:39 2024] usb 3-4: New USB device found, idVendor=3346, idProduct=1009, bcdDevice= 5.10
[Mon Feb 26 18:15:39 2024] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Mon Feb 26 18:15:39 2024] usb 3-4: Product: RNDIS
[Mon Feb 26 18:15:39 2024] usb 3-4: Manufacturer: Cvitek
[Mon Feb 26 18:15:39 2024] usb 3-4: SerialNumber: 0123456789
[Mon Feb 26 18:15:39 2024] rndis_host 3-4:1.0 usb0: register ‘rndis_host’ at usb-0000:00:14.0-4, RNDIS device, da:79:18:af:65:5d

In such case, the best command to find the network adapter name is:
~$ ls /sys/class/net
enp0s25 lo usb0
Then use below command to assign IP address on usb0:
sudo ifconfig usb0 192.168.42.254/24 up

Result:
3: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether da:79:18:af:65:5d brd ff:ff:ff:ff:ff:ff
inet 192.168.42.254/24 brd 192.168.42.255 scope global usb0
valid_lft forever preferred_lft forever

I find it much simpler to choose “Shared Connection” for the USB connection on my linux desktop then request dhcp ip from the milkv-board

e.g

Im using Ubuntu 22.04 on my Duo’s

1 Like