0x01 前言
我的服务器在家里,其中一台虚拟机作为DMZ主机,我并没有打开过多的端口。有时候又不想通过VPN连接家里的服务器,这时候就需要通过SSH或RDP连接。
如果使用默认的SSH和RDP端口进行通讯,这将会引发安全问题,那通过iptables对端口和流量进行管理就变得无比重要。
0x02 禁止与放行
我的使用环境对安全的要求并不是很严格,我直接将进站的所有数据包设为全部丢弃,对需要使用的端口逐一放行。
在此之前需要先检查iptables的状态与目前所存有的规则。无论是centos7还是之前的版本,都可以使用service进行启动与关闭:
#iptables 未启动的状态 [root@test ~]# service iptables status Redirecting to /bin/systemctl status iptables.service ● iptables.service - IPv4 firewall with iptables Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled) Active: inactive (dead) #iptables 启动的状态 [root@test ~]# service iptables status Redirecting to /bin/systemctl status iptables.service ● iptables.service - IPv4 firewall with iptables Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled) Active: active (exited) since 五 2016-08-12 21:33:16 CST; 4s ago Process: 2802 ExecStart=/usr/libexec/iptables/iptables.init start (code=exited, status=0/SUCCESS) Main PID: 2802 (code=exited, status=0/SUCCESS) 8月 12 21:33:16 test.t.com systemd[1]: Starting IPv4 firewall with iptables... 8月 12 21:33:16 test.t.com iptables.init[2802]: iptables: Applying firewall rules: [ OK ] 8月 12 21:33:16 test.t.com systemd[1]: Started IPv4 firewall with iptables.
将iptables设为开机启动并立即启动iptables:
#将iptables 设为开机启动 [root@test ~]# systemctl enable iptables Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service. #立即启动iptables [root@test ~]# systemctl start iptables
检查iptables现有的规则:
[root@test ~]# iptables -L -vn --line-number Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination #此条规则意为对已存在的连接的数据包作放行处理 1 294 20768 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED #此条规则意为对icmp数据包作放行处理 2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 #此条规则意为对内部lo数据包作放行处理 3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 #此条规则意为对SSH默认的TCP协议,端口22的数据包作放行处理 4 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 #如果入站数据包不符合以上任何一条规则,则返还host prohibited信息给源主机。 5 8 1846 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT 160 packets, 25600 bytes) num pkts bytes target prot opt in out source destination
在将入站数据包默认规则修改为丢弃之前,请确认你的SSH端口在放行规则之列。否则你将失去对系统的连接:
[root@test ~]# iptables -P INPUT DROP [root@test ~]# service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ] [root@test ~]# iptables -L -vn --line-number Chain INPUT (policy DROP 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 553 41713 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 4 1 60 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 26 6040 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT 56 packets, 6736 bytes) num pkts bytes target prot opt in out source destination
从上面两端代码高亮处可看出,默认的规则已经从ACCEPT修改为DROP。接下来需要将默认的两段reject-with icmp-host-prohibited删掉。
#删掉INPUT链中第5行的规则 [root@test ~]# iptables -D INPUT 5 #删掉FORWARD链中第1行的规则 [root@test ~]# iptables -D FORWARD 1 #保存修改 [root@test ~]# service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ] #查看现有规则 [root@test ~]# iptables -L -vn --line-number Chain INPUT (policy DROP 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 986 67722 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 4 1 60 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 25 packets, 2568 bytes) num pkts bytes target prot opt in out source destination #重启iptables [root@test ~]# service iptables restart
如果想开放某个端口或对某个IP开放某个端口,可以参考:
# -A INPUT 将规则附加到INPUT链中 # -s [ip] 源主机ip # -d [ip] 目标主机ip # -p 协议,可以是tcp或udp # --dport 目标端口 # -j 规则 # 下面这段的意思是:对源主机ip为10.1.1.0/24发送到主机192.168.1.0/24:8443的数据包作放行处理 [root@test ~]# iptables -A INPUT -s 10.1.1.0/24 -d 192.168.1.0/24 -p tcp --dport 8443 -j ACCEPT #如果不需要使用那么详细的设置,也可以用下面的命令 [root@test ~]# iptables -A INPUT -p tcp --dport 8443 -j ACCEPT
添加规则后如果不保存,在使用service iptables restart重启iptables服务后,未保存的规则将会被抹掉。如果想保存新加入的iptables规则,可使用如下命令:
#保存iptables [root@test ~]# service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ] #重启iptables服务 [root@test ~]# service iptables reload Redirecting to /bin/systemctl reload iptables.service
0x03 转发
如果接触过VPN服务器,那么下面的命令你肯定了解:
iptables -t nat -A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE
因为VPN客户端所获的的IP是服务器分配的内网IP,那么只需要使用POSTROUTING进行源地址转换,而MASQUERADE则可以自动获取eth0网卡的IP,自动将10.10.1.0/24这个网段的IP进行SNAT。
如果像我的使用环境:外网–>[8443]DMZ(10.1.1.12)–>[22]Server1(10.1.1.16),就需要下面这两条规则:
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8443 -j DNAT --to-destination 10.1.1.16:22 iptables -t nat -A POSTROUTING -p tcp -m tcp --dport 22 -j SNAT --to-source 10.1.1.12
因为我是处于DMZ主机外,不但要使用第一条规则将8443端口的数据包转发到10.1.1.16:22,还要将从10.1.1.1:22返还的数据包通过8443端口发出去。
0x04 结语
确实是有点复杂,但慢慢理解,也是能消化的。
源地址发送数据--> {PREROUTING-->路由规则-->POSTROUTING} -->目的地址接收到数据
上面的流程图说明了转发的过程。在VPN环境中,用户是处于路由规则之内,所以只需要用POSTROUTING;而在外网访问内网时,用户处于路由规则之外,就需要使用PREROUTING进行地址转换。