NAT网关设计
目的
本文的目的是将Linux
配置成NAT
网关,具备NAT、DHCP、DNS
功能,实现内网访问外网的通信、实现外网对特定主机的访问、实现内网主机的IP地址动态分配以及域名解析的功能。
环境
实验环境介绍:
一台搭建了
KVM
环境的物理服务器,命名为Server
,并在该服务器上创建两台虚拟机VM
;第一台虚拟机用作NAT网关,命名为
Gateway
,分配两张网卡,eth0
连接内网,eth1
连接外网;第二台虚拟机作为内网主机,命名为
Host
,分配一张网卡eth0
连接内网。内网网段为:
10.0.0.0/24
外网网段为:
192.168.1.0/24
注:本实验其实也可以在
VMware workstation
或者virtualBox
环境下进行,但是由于博主的电脑配置不高,不想在个人电脑上搭建该环境,且身边的服务器刚好有空闲的资源,所以就在服务器上搭建了该环境,至于如何在服务器上搭建KVM
环境可以参照我的另一篇博客的部分内容 快速链接。
搭建实验环境:
创建内部网桥:服务器
Server
上创建一个虚拟网桥br-int,作为连接内网的交换机。1
2
3
4
5
6
7$ sudo brctl addbr br-int
$ brctl show
bridge name bridge id STP enabled interfaces
br-int 8000.000000000000 no
$ sudo ifconfig br-int up注:在
VMware workstation
中搭建环境时需要在虚拟网络编辑器中将使用本地DHCP服务将IP分配给虚拟机选项取消勾选,因为我们需要实现NAT网关来给虚拟机分配IP。另外在创建虚拟网桥后一定要开启该网桥。创建NAT网关虚拟机
其网络配置信息如下:
eth0
eth1
通过
ifconfig
查看网络信息:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17$ ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:1c:83:53
inet6 addr: fe80::5054:ff:fe1c:8353/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
eth1 Link encap:Ethernet HWaddr 52:54:00:de:e8:51
inet addr:192.168.1.123 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fede:e851/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
...可见NAT网关的
eth0
网卡因为没有DHCP服务器所以没有分配到IP,但外网网卡eth1
已经有一个外网IP。
创建内部主机虚拟机
其网络配置信息如下:
eth0
通过
ifconfig
查看网络信息:1
2
3
4
5
6
7
8
9
10
11$ ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:1a:a1:78
inet6 addr: fe80::5054:ff:fe1a:a178/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
...可见其内网网卡
eth0
没有分配IP。其实,在启动这两个虚拟机时,因为内部网络没有DHCP服务器,他们的内网网卡会一直等待DHCP服务器给它们分配IP,等待的时间大概是5分钟,最终还是没有获得IP。
修改两个虚拟机的网络配置文件
NAT网关:
$ sudo vi /etc/network/interfaces
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
address 10.0.0.1
netmask 255.255.255.0
gateway 10.0.0.1
auto eth1
iface eth1 inet dhcp因为NAT网关的
eth0
将做内网的网关,故将其IP设置为静态IP:10.0.0.1
,这样更容易识别,且不会因为重启而改变。内部主机:
$ sudo vi /etc/network/interfaces
1
2
3
4
5
6
7
8
9source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet dhcp
在服务器Server上查看虚拟网桥的信息:
1
2
3
4$ brctl show br-int
bridge name bridge id STP enabled interfaces
br-int 8000.fe54001aa178 no vnet1
vnet3可以看到虚拟网桥
br-int
上面已经有两个网络接口,对应两个虚拟机的内部网卡。
NAT 功能实现
NAT网关的功能是通过Linux中自带的iptables来实现,NAT功能包括SNAT和DNAT。SNAT是源地址转换,在内网主机访问外网时发挥作用,可以将内网主机的ip地址转换为网关的ip地址。DNAT是目的地址转换,在外网的主机通过NAT网关的ip和端口对内网主机发起访问时发挥作用,可以将NAT网关的ip地址与端口转换为对应内网主机的ip,从而实现从外网对内网中某一特定主机的访问。当然要将Linux虚拟机配置成NAT网关,首先得要开启Linux虚拟机的网络转发功能。下面将介绍NAT功能的实现过程:
开启网络转发功能
临时开启网络转发功能,需要切换到
root
用户,命令如下:# echo 1 > /proc/sys/net/ipv4/ip_forward
这样在下次虚拟机重启后该功能会自动关闭,因此可以修改配置文件的方式来开启该功能并永久生效。
永久开启网络转发功能:
# vi /etc/sysctl.conf
在文件里面添加一行
net.ipv4.ip_foward=1
,在下次重启之后就不会还原了。
SNAT的实现
在
iptables
的nat表
的POSTROUTING规则链
中添加规则,使得从10.0.0.0/24
网络发到NAT网关的数据包,从eth1
转发出去,并将数据包的源ip地址修改为NAT网关的外网地址,命令如下 :sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth1 -j SNAT --to-source 192.168.1.123
192.168.1.123
是NAT网关的外网网卡eth1
的IP。DNAT的实现
在
iptables
的nat表
的PREROUTING规则链
中添加规则,使得从外网发往NAT网关固定端口(如:8080)的TCP
(这里也可以添加其他网络协议)数据包转发到内网的某固定主机上,命令如下:sudo iptables -t nat -A PREROUTING -i eth1 -d 192.168.1.67 -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.107:22
10.0.0.107
是内网某主机的IP,这里说明一下:实际实现的过程中,最好先实现DHCP与DNS的功能。保存
iptables
规则sudo iptables-save | sudo tee /etc/iptables.sav
编辑
/etc/rc.local
文件,将下面的一行添加到"exit 0"
之前:iptables-restore < /etc/iptables.sav
这样每次重启机器时都会自动加载NAT相关的
iptables
规则。
DHCP与DNS功能实现
实现DHCP服务器可以使用isc-dhcp-server
工具包,实现DNS服务器可以使用bind9
工具包,但是本实验考虑使用DNSmasq
工具来同时实现DHCP服务器与DNS服务器的功能。DNSmasq
是一个小巧且方便地用于配置DHCP和DNS的工具,适用于小型网络。作为域名解析服务器(DNS),DNSmasq
可以通过缓存DNS请求来提高对访问过的网址的连接速度。作为DHCP服务器,DNSmasq
可以用于为局域网电脑分配内网ip地址和提供路由。
安装DNSmasq工具:
$ sudo apt-get install dnsmasq
编辑
DNSmasq
的配置文件/etc/dnsmasq.conf
,添加下面两行:1
2interface=eth0
dhcp-range=10.0.0.100,10.0.0.200,72h其中
interface
是用作内网网关的网卡,也就是NAT网关的eth0
网卡;dhcp-range
是动态分配的IP地址池;72h
表示分配的IP的有效时间是72个小时,到时间后需要重新分配IP。重启
DNSmasq
服务:1
2$ sudo /etc/init.d/dnsmasq restart
[ ok ] Restarting dnsmasq (via systemctl): dnsmasq.service.到这里就配置内容就完成了。然后需要重启这两个虚拟机。
测试结果
DHCP服务
在完成DHCP服务器配置重启虚拟机后,会发现在启动过程中不再需要等待5分钟来获取IP了,进入内部主机查看网络信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18$ ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:1a:a1:78
inet addr:10.0.0.176 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fe1a:a178/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:17 errors:0 dropped:0 overruns:0 frame:0
TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
collisions:36 txqueuelen:1000
RX bytes:1642 (1.6 KB) TX bytes:2182 (2.1 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:164 errors:0 dropped:0 overruns:0 frame:0
TX packets:164 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:12200 (12.2 KB) TX bytes:12200 (12.2 KB)可以看到eth0分配到了一个在DHCP地址池内的一个IP:
10.0.0.176
。DNS与NAT服务
这里将同时对DNS服务与NAT服务进行测试
内网到外网
由于我所在的网络所有的
ping
外网的报文都会被拦截,所以没有办法通过ping
来测试网络的连通性,这里采用wget
命令在内部主机测试:1
2
3
4
5
6
7
8
9
10
11$ wget http://www.baidu.com
--2018-07-08 16:30:37-- http://www.baidu.com/
Resolving www.baidu.com (www.baidu.com)... 180.97.33.108, 180.97.33.107
Connecting to www.baidu.com (www.baidu.com)|180.97.33.108|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2381 (2.3K) [text/html]
Saving to: ‘index.html’
index.html 100%[================================>] 2.33K --.-KB/s in 0s
2018-07-08 16:30:37 (61.1 MB/s) - ‘index.html’ saved [2381/2381]上面的测试说明内网主机到外网的连通性,并且也实现了域名解析的功能。
外网到内网
在博主的个人Windows电脑上去访问内网主机,以此来测试外网到内网的连通性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34[c:\~]$ ssh openstack-image@192.168.1.152 8080
Connecting to 192.168.1.152:8080...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-87-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
134 packages can be updated.
55 updates are security updates.
Last login: Sun Jul 8 16:13:54 2018
openstack-image@ubuntu:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:d0:51:38
inet addr:10.0.0.176 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fed0:5138/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:96 errors:0 dropped:0 overruns:0 frame:0
TX packets:125 errors:0 dropped:0 overruns:0 carrier:0
collisions:516 txqueuelen:1000
RX bytes:17842 (17.8 KB) TX bytes:15515 (15.5 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:176 errors:0 dropped:0 overruns:0 frame:0
TX packets:176 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:13392 (13.3 KB) TX bytes:13392 (13.3 KB)可以访问,外网到内网也是连通的。到此,需要实现的功能都已经实现了。