六、Bind和OpenVpn的联合使用达到特殊环境的访问限制
概要
写的第六篇记录就不知道该起个什么什么标题了,感觉以后会越来越多。。言归正传,所有的架构都是在不断的迭代中进行完善的,无论是向好的方向还是坏的方向。
在我司安全研究员小胖子无意间在公网上发现了开发环境的后台而且还存在弱口令之后,我们也准备着手将所有的开发环境进行访问限制。
由于目前各种架构上的问题,开发环境的域名必须要映射到出口防火墙上,在防火墙上对域名可以做黑白名单的限制。
我们在防火墙针对开发环境域名的限制:
1、白名单放通了办公网的出口IP,保证所有开发在公司办公时可以访问;
2、黑名单针对“/”根uri进行了阻塞,由于白名单优先级高于黑名单,所以达到了仅允许办公网访问开发域名的要求。
那么需要思考的就是对于移动办公人员,该如何访问开发环境,针对目前的架构做了如下修改:
1、目前移动办公人员有使用云服务器区域提供的Openvpn(在我的专辑中前两天提到过),如果可以让移动办公人员访问开发环境的流量通过Openvpn进行访问,那边就可以固定该人员的出口IP地址,固定之后就可以在防火墙上针对该IP地址进行放通,那么我们第一步将云服务器的IP地址添加至防火墙的白名单中。
2、第二步需要解决的就是如何让移动办公人员的访问开发环境的流量固定到VPN中,如果设置0.0.0.0/0的路由将所有的流量引入VPN势必是不可为的,会造成云服务器带宽的占用。可行的就是需要将开发域名对应的IP地址下发一个32位的路由给VPN客户端即可。在Openvpn的配置文件中添加一条route配置即可。
3、坑爹的第三步就要来了,由于云上防火墙的出口IP是动态的,而且每个地区解析到的结果都不相同,但是使用任何一个地区解析到的IP地址都可以访问。那么就需要解决让所有客户端解析该域名都得到同样IP地址的问题,此时就需要一个DNS服务器了,DNS服务器提供一个目前时段可用的IP地址给openvpn的客户端使用,并且在DNS解析地址变更后,Openvpn下发的路由也需要做相应的调整才可以。

解决步骤
按照上述的思路需要先准备一台DNS服务器,我使用了提供Openvpn服务的服务器同时作为DNS服务器使用
[root@dev ~]# yum install -y bind
[root@dev ~]# vi /etc/named.conf
options {
listen-on port 53 { 172.16.16.4; 127.0.0.1; }; #添加对外提供服务的IP地址进行监听,默认只监听在127.0.0.1无法对外提供服务,注意语法格式
allow-query { any; }; #允许查询的对象,默认为localhost,需要做更改,可以是仅允许查询的网段,此处我设置为any
allow-query-cache { any; };
recursion yes; #打开递归查询,不了解的话需要补充DNS的基础知识。。。
// dnssec-enable no; #由于是内网非权威DNS,关闭所有安全选项
// dnssec-validation no;
// bindkeys-file "/etc/named.iscdlv.key";
// managed-keys-directory "/var/named/dynamic";
};
新增本地域,将所有该域名的解析都在本地完成,未定义的子域名查询请求直接返回No such Name A xxx.xxx.com SOA ns.xxx.com
[root@dev ~]# vi /etc/named.rfc1912.zones
zone "armo.com" IN { #定义在本地查询的zone,所有armo.com子域名的查询都将在本地库中完成,具体的子域名解析配置文件在file中定义
type master;
file "armo.com.zone";
};
定义本地zone解析库,/var/named文件夹路径在named.conf中定义
[root@dev ~]# vi /var/named/armo.com.zone
$TTL 1d
@ IN SOA ns.armo.com. admin.armo.com( #"ns.armo.com."管理的域名,通常为ns记录,和下面定义的NS记录域名相同;"admin.armo.com"管理者邮箱,不用加@
2017081702
1H
5M
7D
1D)
IN NS ns.armo.com. #定义NS域名记录,域名后面必须有个"."
ns IN A 172.16.16.4 #定义ns域名的A记录,表明该ns域名的将由A记录的地址完成解析,A记录地址为DNS服务器地址
node1 IN A 1.1.1.1 #接下来定义所有子域名的A记录,假设目前解析到开发域名的IP为1.1.1.1;未定义的子域名直接返回No such Name A
node2 IN A 1.1.1.1
node3 IN A 1.1.1.1
...
...
...
DNS服务器本地Iptables放通tcp和udp53端口,让所有的查询流量能够到达用户空间的DNS服务
[root@dev ~]# iptables -I INPUT 1 -s 10.10.10.0/24 -p udp --dport 53 -j ACCEPT
[root@dev ~]# iptables -I INPUT 1 -s 10.10.10.0/24 -p tdp --dport 53 -j ACCEPT
线上的服务器一般都默认有一条优先级最低针对all的REJECT规则,对所有的请求进行icmp-host-prohibited,请求端会收到一个ICMP的host-prohibited报文
#将DNS和1.1.1.1的路由通过Openvpn下发给VPN客户端,在配置文件中新增如下两行
[root@dev ~]# vi /etc/openvpn/server.conf
push "route 1.1.1.1 255.255.255.255"
push "dhcp-option DNS 172.16.16.4"
#启动DNS服务并重载Openvpn
[root@dev ~]# service named start
[root@dev ~]# service openvpn reload
此时登录VPN的客户端会使用172.16.16.4作为DNS,并且路由表新增1.1.1.1的路由指向VPN通道。客户端使用172.16.16.4解析开发域名得到1.1.1.1之后的会将流量发送到Openvpn服务器,通过云服务器出口去访问开发域名达到访问控制的效果。
那么接下来需要解决的就是如果让我们自己的DNS也能够解析到动态的开发域名IP地址,并且同步至Openvpn的客户端。
[root@dev ~]# vi /etc/openvpn/check_domain.sh
#!/bin/bash
# check and sync armo.com
# version 20170818
# by armo
#获取目前域名解析得到的IP地址
newip=`/usr/bin/nslookup dev.armo.com | grep Address | sed -n 2p | cut -d ":" -f 2`
#获取之前域名解析得到的IP地址,在openvpn配置文件中第11行的配置为下发的路由信息push "route 1.1.1.1 255.255.255.255",从此处提取出oldip为1.1.1.1
oldip=`/bin/sed -n 11p /etc/openvpn/server.conf | cut -d " " -f 3`
nowdate=`date +%x-%X`
if [[ $newip == $oldip ]];then
break
else
sed -i "s/$oldip/$newip/g" /var/named/armo.com.zone
sed -i "s/$oldip/$newip/g" /etc/openvpn/server.conf
echo "$nowdate the ip changed,the new ip is $newip" >> /etc/openvpn/ipchange.log
/etc/init.d/openvpn reload
/etc/init.d/named reload
fi
[root@dev ~]# chmod +x /etc/openvpn/check_domain.sh
#将check_domain.sh配置为定时任务,自动完成域名解析地址的更新
[root@dev ~]# crontab -e
*/1 * * * * /etc/openvpn/check_domain.sh &
[root@dev ~]# service crond restart