menu Chancel's blog
rss_feed
Chancel's blog
有善始者实繁,能克终者盖寡。

Linux主机实现NAT转发

作者:Chancel Yang, 创建:2021-06-16, 字数:1785, 已阅:87, 最后更新:2024-03-10

假设在一个封闭的内网网络环境内有一台安装了Linux操作系统的双网卡机器A,两个IP如下

  • 内网:192.168.1.100/24
  • 外网:172.16.1.200

同时有一个只连接了内网的单网卡机器B,IP如下

  • 内网:192.168.1.150/24

A与B同为192.168.1.0/24网段,能够互相访问,问题是如何让B通过A的172.16.1.200网卡访问外网呢?

答案是双网卡机器配置NAT转发后,可以实现让内网的B机器获得访问公网的能力

NAT转发配置分为2步

  1. 开启内核转发功能
  2. 配置转发规则,将内网网卡数据包转发给外网网卡

首先看一下A机器双网卡的情况,输出信息已做简略处理,操作系统是Ubuntu1804

Bash
chancel@chancel-server:~$ 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
    ...
# 内网网卡
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 06:40:d3:a4:13:da brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global ens18
       valid_lft forever preferred_lft forever
    inet6 fe80::440:d3ff:fea4:13da/64 scope link 
       valid_lft forever preferred_lft forever
# 外网网卡
3: enx00a0c6000000: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:a0:c6:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.200/24 brd 172.16.1.255 scope global dynamic enx00a0c6000000
       valid_lft 72624sec preferred_lft 72624sec
    inet6 fe80::2a0:c6ff:fe00:0/64 scope link 
       valid_lft forever preferred_lft forever

开通内核的网络转发功能,使用 sudo vim /etc/sysctl.conf,并取消以下的注释

Bash
...
# 找到并取消注释或直接添加该行
net.ipv4.ip_forward=1
...

让刚才的操作生效

Bash
sudo sysctl -p

配置转发规则,将 ens18 网卡的数据包全部转发给 enx00a0c6000000

TEXT
sudo iptables -t nat -A POSTROUTING -s 192.168.1.1/24 -o enx00a0c6000000 -j MASQUERADE

此时可以测试将内网机器B的网关设置为192.168.1.100,再验证能否访问外网

由于Ubuntu1804在重启之后iptables规则会失效,为了保存iptables规则,需要安装iptables-persistent

Bash
sudo apt install iptables-persistent
sudo netfilter-persistent  save

[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]