本次纯属记录,希望有所帮助。
目的,模拟一个内网和外网,内网机器访问外网,并进行 地址转换。
实验环境:
已有一个 192.16.10.0/24 网段的局域网,该网络内拥有一台路由器,用于给网络中的设备分配IP地址。实验时,把该局域网当成外网。以下都以外网称呼。
欲配置一个 192.168.1.0/24 的网段作为内网。
有一台拥有两网卡的Linux主机,将该Linux主机做成网关,其分别连接两个网段,完成两网段间的网络地址的转换工作。以下以网关称呼。
以下操作均在root用户下进行。
网关配置:系统 Ubuntu 18.04,内核版本 5.0.0,网卡1名称:enp1s0,网卡2名称:enx00e04c68066f
(网卡2是一个USB转网卡,可使用ls /proc/sys/net/ipv4/conf
或ifconfig
查看网卡名称)
欲把该网关的 网卡 enp1s0 连接外网网段 192.16.10.0/24。网卡 enx00e04c68066f 连接 内网网段 192.168.1.0/24。
其 interface 文件配置如下:
vim /etc/network/interface
# enp1s0 采用 DHCP,等待分配 ip
auto enp1s0
iface enp1s0 inet dhcp
# enx00e04c68066f 采用 静态 ip,其 ip 是 192.168.1.2
auto enx00e04c68066f
iface enx00e04c68066f inet static
address 192.168.1.2
netmask 255.255.255.0
# gateway 192.168.1.2 # 网关
# dns-nameservers 114.114.114.144 # DNS
# dns-nameservers 8.8.8.8
# 本地回环地址,默认这样配置即可
auto lo
iface lo inet loopback
说明,enp1s0 连接了外网,采用dhcp获得地址(由上述所说的路由器分配地址)。enx00e04c68066f 连接内网,采用了静态网络配置,把ip地址设定为 192.168.1.2。
然后使用/etc/init.d/networking restart
重启网络。为避免不必要的问题,建议重启系统。
可使用ifconfig
查看是否网络配置是否生效了。
本人实验时,enp1s0 分配到ip地址为192.16.10.8.
在网关上,要配置内核转发。
此为永久生效方案,即重启后仍有效
vim /etc/sysctl.conf
大约在文件的第28行,将以下内容的注释去掉(或者新增一个)
net.ipv4.ip_forward=1
使内核转发立即生效:
sysctl -p
将一台Linux主机PC1的网卡eth1连接到 enx00e04c68066f 网卡。将其作为内网机器。
为其配置静态ip地址192.16.10.5。
ifconfig eth1 192.16.10.5
或者,像上面一样,通过修改 interface 文件实现静态网络配置。
配置后,一定用使用 ping 等命令测试 PC1 与 网关的内网 ip 是否连通。如ping 192.168.1.2
,两台机子上都要ping对方机器。
然后加一条路由,告诉内网机器,发送给 192.16.10.0/24 的数据包,交给网关 192.168.1.2 处理。(确保能ping通之后,再加此路由)
route add -net 192.16.10.0/24 gw 192.168.1.2
或
route add -net 0.0.0.0 gw 192.168.1.2
注:重启网络或系统之后路由需重配。
或者在 interface 里面,加上默认网关(gateway字段),指向 网关的内网 ip 地址。
注:使用route -n
可查看当前的路由配置。使用route del -net 192.16.10.0/24 gw 192.168.1.2
可删除上述配置的路由。
如果是Windows系统,在“控制面板” -> “网络和Internet” -> “网络和共享中心” -> 左边“更改适配器设置” -> 双击要配置的指定网卡->弹出的界面上,选择“属性” -> 在“此连接使用下列项目’中,找到并双击“Internet 协议版本4(TCP/IPv4)” -> 选中 “使用下面的IP地址”,并填写相关参数(DNS服务器参数也可提供) -> 确定后关闭即可。
转发时,内网发出的数据包,其目的地址是 外网机器的ip,源地址是内网ip,应由 网关 将内网的 ip 地址 转换成 网关的 外网 ip,然后,再发送出去,故为源地址转换,SNAT。
而外网返回回来的数据包,其源地址是外网机器的ip,目的地址是网关的外网 ip,应由 网关将 此 外网的 ip 地址,转成内网的 ip 地址,然后发送给内网中对应的机器,故为目的地址转换,DNAT。
简要解释,如果数据包源地址是内网 ip ,外网机器 并不能识别这个 内网 ip 在哪里,因此没法返回消息,但 外网机器,可以识别该 网关的外网 ip,因而可以发送给网关,再由网关交给内网中实际的机器。因此 发出去之前,将 源 ip 改成 网关的外网 ip,返回时,要将 目的 ip 变为 内网实际机器的 ip。
在网关上配置如下的 NAT 规则
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o enp1s0 -j MASQUERADE
其指示,来自 192.168.1.0/24 (也可以不指定),并由 enp1s0 发出去 的数据包,应进行 NAT 转换。该 MASQUERADE 会自动进行 SNAT (似乎也会将返回数据包自动DNAT到内网机器上),有关于这个关键字的更多内容,可搜索“iptables -j MASQUERADE”了解。
配置完之后,应在内网 机器 PC1 上,ping 192.16.10.2
查看是否能通信,以及,ping 外网其他 ip 地址查看是否能通信。例如,外网路由器的 ip 地址是 192.16.10.254,需ping 192.16.10.254
。可在网关或外网机器上,使用wireshark等软件,抓包查看 发出来数据包的源ip地址 和 返回的数据包的目的ip地址,是否是那台网关的 外网ip地址。
注:
可使用 iptables -t nat -nL
查看配置的规则。
使用iptables -t nat -F
可清空规则。
或使用下面的,指定删除上述规则。
iptables -t nat -D POSTROUTING -s 192.168.1.0/24 -o enp1s0 -j MASQUERADE
注:此规则,重启电脑后会失效,需重配。也可采用如iptables-save等命令自动重配,此处请自行搜索。
到了这里,配置就完了,内网机器要使用浏览器上网的话,最好再在其上配置dns地址。
上述第三步,内网是采用了静态 ip 的形式进行了配置。也可以在 网关上 配置一个 DHCP 服务器,让其给内网中的机器,分配内网地址和网关地址,以及dns地址。
此处使用 isc-dhcp-server 进行DHCP分配。
以下操作在 网关 机器上进行。
apt-get install isc-dhcp-server
配置第一个文件
vim /etc/default/isc-dhcp-server
配置如下,应配置 网关 的 内网网卡作为 DHCP 服务器监听的网卡。
有的版本可能没有v4和v6的区别,只有INTERFACES一条。
INTERFACESv4="enx00e04c68066f"
# 显然上面是指ipv4,这个是指ipv6
INTERFACESv6=""
配置第二个文件
vim /etc/dhcp/dhcpd.conf
这个是配置ipv4的dhcp用的。如果需要配置ipv6的,同目录下,有个dhcpd6.conf是配置ipv6的dhcp用的。
注:建议配置前备份这两个文件,本人删除后,重装软件等啥操作都试了,还是没有生成这两个文件,不得已在其他虚拟机上安装这个软件,拷贝了这两个文件过来。
该文件配置如下:
# option definitions common to all supported networks...
option domain-name "example.org"; # 可以不改,不知道有什么用
#option domain-name-servers ns1.example.org, ns2.example.org;
option domain-name-servers 202.112.14.21,202.112.14.11; # 这个是DNS,也可填写如114.114.114.114,一般填两个
# 下面两个是使用了默认值,应该和 DHCP 地址租期有关系
default-lease-time 600; #
max-lease-time 7200;
# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none; # 这个不知道干啥,默认吧
# 下面这个就是个人 DHCP 网段配置了,可参照文件里面的示例写
# 网段和掩码
subnet 192.168.1.0 netmask 255.255.255.0 {
# DHCP 分配的地址范围
range 192.168.1.2 192.168.1.100;
# 内网 网关的 ip 地址
option routers 192.168.1.2;
# 广播地址
option broadcast-address 192.168.1.255;
}
请注意上面的字母还有分号啥的不要写错了。
网关 的 内网网卡 enx00e04c68066f, 一般配置成上述 内网 网关 ip,即 192.168.1.2,采用静态配置。这部分的 interface 和上面是一样的。配置完后,建议/etc/init.d/networking restart
重启网络。
使用 server isc-dhcp-server restart
重启 DHCP 服务器。如果出错,这里并不会报错。
使用server isc-dhcp-server status
可以看到状态,如果成功启动,则应看到如下 active(running)等字眼。如下所示:
如果出错,这里会提供一点点报错信息,请仔细检查 上述两个配置中,是否错误输入了什么东西,例如单词拼写错误,空格输入成逗号,没有输入分号,网段输入错误,等等。(本人在这里,因为拼写错误,检查了良久)
如果成功启动 输入netstat -aunp | grep dhcpd
,应看到(单个或多个) dhcpd,如果失败了,则没有结果。或者是ps -ajx | grep dhcpd
(至少会显示 grep 这条,但这个显然不是dhcpd的进程)。
可使用 ifconfig
随时查看网卡状态。
提醒,网关上记得加 iptables 的 NAT 规则。
这些操作在 内网中Linux机器 PC1 上进行
需将 interface 文件中网卡 eth1 改成 DHCP 获取。
vim /etc/network/interface
# eth1 采用 DHCP,等待分配 ip
auto eth1
iface eth1 inet dhcp
# 本地回环地址,默认这样配置即可
auto lo
iface lo inet loopback
然后,/etc/init.d/networking restart
重启网络,或者重启电脑。
因为 DHCP 服务器填有 网关地址,故这里可以不用配置路由。
使用 ifconfig
查看是否分配到了ip地址。
如果是Windows系统,在“控制面板” -> “网络和Internet” -> “网络和共享中心” -> 左边“更改适配器设置” -> 双击要配置的指定网卡->弹出的界面上,选择“属性” -> 在“此连接使用下列项目’中,找到并双击“Internet 协议版本4(TCP/IPv4)” -> 请选中 “自动获得IP地址” -> 确定后关闭即可。
如果 ip 地址获取失败,建议重启网卡或电脑试试。
如果不需要了DHCP服务器,除了卸载软件,或者杀死相关进程,也可使用
systemctl disable isc-dhcp-server
systemctl stop isc-dhcp-server
停掉 DHCP 服务。这时候,使用systemctl status isc-dhcp-server
或service isc-dhcp-server status
看到将显示inactive(dead)(可能需要按Q键退出该模式回到终端)。这样开机之后,也不会启动该服务。
显然,重新启用该服务的命令如下,启动后,一定要用service isc-dhcp-server status
等命令查看是否启动成功。
systemctl enable isc-dhcp-server
systemctl restart isc-dhcp-server # 或者 service isc-dhcp-server restart
在搭建好 内网 网关 之后,内网 中 主机,可以访问外网中主机,例如 在 192.168.1.5 的主机上,可以 ping 通 192.16.10.71 的主机。但反过来ping并不行。
内网访问外网原理简述。
内网中主机 192.168.1.5 ,虽然可能不知道192.16.10.254的主机在哪里,但根据路由表或默认网关,会自动发送给 内网的网关 192.168.1.2,这个网关 由于 同时连接了 内网(192.168.1.2)和外网(192.16.10.8),其根据自己的路由表或默认网关,就会发送到外网中相应的主机上,这个时候,因为做了NAT设置,因而数据包的源地址192.168.1.5,被修改成192.16.10.8,等返回时,返回包的目的地址是192.16.10.8,然后网关再自动NAT,将目的地址改成192.168.1.5,然后 内网中主机就收到返回包,就表现为ping通了。
而外网不能访问内网,是因为 外网 主机(比如 192.16.10.71)不知道 内网主机(192.168.1.5)在哪里,然后它发给自己的默认网关,比如外网的路由器(192.16.10.254),但是这个路由器也不知道内网主机在哪里,因此就没办法通信。
所以,想要从 外网的主机 访问到 内网的主机,一个比较简单的方法原理,就是指定 发往 192.168.1.5 的包,发给 那个同时连接了两个网段的网关即可。
因为,在需要访问内网的那个外网主机(192.16.10.71)上或者是外网网段的路由器上,添加一条路由即可。例如:
route add -net 192.168.1.0/24 gw 192.16.10.8 # linux 下写法
# route add 192.168.1.0/24 192.16.10.8 # windows 下写法,需管理员权限运行 cmd
其指示,发往 192.168.1.0/24 的数据包,发给 192.16.10.8 处理。
注:因为这个内网网段是ip协议里的私有网段,如果是公有网段,那可能影响 主机上网。
另注:抓包发现这个数据包里的ip地址并没有被NAT,不太懂(例如,我在192.16.10.71的主机上,ping 192.168.1.5
时,返回的数据包并没有被 NAT)。
这样,在 外网主机上,访问 内网主机时,直接填写内网主机的IP地址即可。
注:此方法,重启后会失效。
也有其他方式的访问内网实现,例如端口代理之类的。
ubuntu16.04配置网卡
Linux网络的SNAT和DNAT
IPtables中SNAT、DNAT和MASQUERADE的含义
ubuntu16.04上安装配置DHCP服务的详细过程