OpenVPN over IKEv2 配置

1. 背景介绍

关于如何绕过实验室的访问策略,直接访问服务器区服务器,之前的文章Strongswan Linux host-to-host配置 已经介绍过,实现的拓扑如图1-1所示:

  • 服务器区的服务器Carol的IP地址为172.18.31.13/16办公区Moon的IP地址为10.30.8.8/19
  • Carol以IKEv2 VPN连接到Moon,获取的办公区虚拟IP地址为10.30.30.13
3-1
图1-1 逻辑拓扑

2. 理论基础

首先参考《PPTP over IKEv2 配置》。

OpenVPN可以配置为路由模式或者交换模式

  • 路由模式为办公区客户端获取的IP地址为虚拟IP地址,以SNAT方式访问服务器区的服务器,对于服务器区而言,因为是SNAT转发,办公区的客户端是不可访问的。
  • 交换模式为办公区客户端获取的IP地址为服务器区的IP地址,对于对于服务器区办公区的客户端是可以访问的。

3. 实现步骤

实验环境

假设服务器区的服务器仍为Carol,办公区的IKEv2 服务器为Moon,办公区的客户端为Bob

设备 所在区域 逻辑所在区域 IP地址 操作系统 VPN角色
Moon 办公区 办公区 10.30.8.8 CentOS 6 IKEv2 VPN服务器IP
Carol 服务器区 服务器区 172.18.31.13 CentOS 7 IKEv2 VPN客户端IP
办公区 10.30.30.13 CentOS 7 IKEv2 VPN虚拟IP
服务器区 192.168.99.1 CentOS 7 Open VPN虚拟网关IP(路由模式)
Bob 办公区 办公区 10.30.5.39 Windows Open VPN客户端IP
服务器区 192.168.99.10 Windows Open VPN虚拟IP(路由模式)
服务器区 172.18.31.10 Windows Open VPN虚拟IP(交换模式)

软件安装

在Carol上安装openvpn以及相关软件

1
2
3
4
yum install epel-release
yum -y install gcc openssl-devel lzo-devel pam-deve
yum -y install easy-rsa
yum -y install openvpn

密钥&证书生成

拷贝easy-rsa配置

1
2
cp -R /usr/share/easy-rsa/ /etc/openvpn/
cd /etc/openvpn/easy-rsa/2.0/

修改变量文件vars,主要修改有,更多选项,参考文件内注释

1
2
3
4
5
6
export KEY_COUNTRY="CN" #自定义国家
export KEY_PROVINCE="BJ" #自定义省份
export KEY_CITY="BeiJing" #自定义城市
export KEY_ORG="Long" #自定义组织机构
export KEY_EMAIL="test@long.com" #自定义邮箱
export KEY_OU="Operation" #自定义单位或部门

生成证书,如果弹出输入,直接回车即可

1
2
3
4
5
6
source ./vars 
./clean-all #清理keys
./build-ca #生成ca.crt和ca.key
./build-key-server server #生成server.crt和server.csr和server.key
./build-dh #生成dh2048.pem
openvpn --genkey --secret keys/ta.key #生成ta.key

服务配置

复制一份默认的服务端配置文件,修改配置文件server.conf

1
cp /usr/share/doc/openvpn-*/sample/sample-config-files/server.conf /etc/openvpn/

修改证书的路径为绝对路径。

1
2
3
4
5
6
cd /etc/openvpn/
sed -i s#ca.crt#/etc/openvpn/easy-rsa/2.0/keys/ca.crt#g server.conf
sed -i s#server.crt#/etc/openvpn/easy-rsa/2.0/keys/server.crt#g server.conf
sed -i s#server.key#/etc/openvpn/easy-rsa/2.0/keys/server.key#g server.conf
sed -i s#dh2048.pem#/etc/openvpn/easy-rsa/2.0/keys/dh2048.pem#g server.conf
sed -i s#ta.key#/etc/openvpn/easy-rsa/2.0/keys/ta.key#g server.conf
路由模式

server.conf主要配置如下,详细配置可以参考注释

  • 端口协议可以自定义
  • dev为tun,路由模式使用tun隧道
  • server字段指定接入客户端使用的虚拟IP地址段,即办公区客户端接入获取的虚拟机IP地址段
  • route为向客户端推送的路由条目,即办公区接入客户端只会将发往服务器区的流量交给OpenVPN服务器进行转发。
1
2
3
4
5
port 1194
proto udp
dev tun
server 192.168.99.0 255.255.0.0
push "route 172.18.0.0 255.255.0.0"

添加iptables条目:

  • 开放对应的协议和端口
  • 使用SNAT,办公区接入客户端获取的虚拟IP地址,通过SNAT转发方式访问服务器区网络172.18.0.0/16,这里需要指定IP地址,因为服务器Carol网卡拥有多个IP地址(IKEv2 VPN获取的办公区IP地址10.30.30.13)
  • 保存iptables条目
1
2
3
iptables -I INPUT 2 -p udp --dport 1194 -j ACCEPT
iptables -A POSTROUTING -s 192.168.99.0/24 -j SNAT --to-source 172.18.31.13
iptables-save > /etc/sysconfig/iptables

启动服务并设置开机启动

1
2
systemctl start openvpn@server
systemctl enable openvpn@server
交换模式

交换模式需要将服务器区的服务器Carol的物理网卡改为桥接模式,一般情况下,可以使用官方推荐的脚本,脚本路径为/usr/share/doc/openvpn-x.x.x/sample/sample-scripts/,使用脚本bridge-start启动桥接网卡,使用脚本bridge-stop关闭桥接网卡。

鉴于这个情况比较复杂,因为办公区接入客户端依赖于服务器通过IKEv2获取的IP地址,网卡拥有多个IP地址,但是官方脚本没有处理这种情况,因此需要手动桥接相关的网卡。

桥接Carol的物理网卡到网桥,这里假设物理网卡为eth0,网桥为br0。桥接后的状态应为如下。

1
2
3
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.003048fd1a58 no eth0

另外,因为重启了网卡,因此IKEv2 VPN依赖的ipsec服务需要重启并重新建立连接。

1
2
ipsec restgart
ipsec up home

桥接Carol的物理网卡到网桥的脚本如下

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
ETH="eth0"
BR="br0"
# ----------------------------------------------------------------------------------------
yum install BRidge-utils -y

cd /etc/sysconfig/network-scripts/

cat <<EOF >> ifcfg-${BR}
TYPE=BRidge
ONBOOT=yes
DEVICE=${BR}
BOOTPROTO=static
EOF
cat ifcfg-${ETH} | grep IPADDR >> ifcfg-${BR}
cat ifcfg-${ETH} | grep PREFIX >> ifcfg-${BR}
cat ifcfg-${ETH} | grep GATEWAY >> ifcfg-${BR}
cat ifcfg-${ETH} | grep DNS >> ifcfg-${BR}

sed -i s/IPADDR/#IPADDR/g ifcfg-${ETH}
sed -i s/PREFIX/#PREFIX/g ifcfg-${ETH}
sed -i s/GATEWAY/#GATEWAY/g ifcfg-${ETH}
sed -i s/DNS/#DNS/g ifcfg-${ETH}
echo "BRIDGE=${BR}" >> ifcfg-${ETH}

systemctl restart network

创建tap网卡,这里修改了官方脚本,首先复制官方脚本到/etc/openvpn目录下

1
cp -r  /usr/share/doc/openvpn-x.x.x/sample/sample-scripts/ /etc/openvpn/scripts

修改后的bridge-start脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
br="br0"
tap="tap0"

for t in $tap; do
openvpn --mktun --dev $t
done

for t in $tap; do
brctl addif $br $t
done

for t in $tap; do
ifconfig $t 0.0.0.0 promisc up
done

执行该脚本后,状态如下,将tap0桥接到网桥br0。tap0桥接到br0之后,方可启动OpenVPN服务!

1
2
3
4
[root@localhost scripts]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.003048fd1a58 no enp5s0
tap0

修改后的bridge-stop脚本如下,用于删除tap网卡

1
2
3
4
5
6
br="br0"
tap="tap0"

for t in $tap; do
openvpn --rmtun --dev $t
done

server.conf主要配置如下,详细配置可以参考注释

  • 端口协议可以自定义
  • dev为tap0,交换模式使用tap0进行通信
  • server-bridge字段指定接入客户端使用的IP地址段,即办公区客户端接入获取的服务器区IP地址段
1
2
3
4
port 1194
proto udp
dev tap0
server-bridge 172.18.0.0 255.255.0.0 172.18.31.100 172.18.31.200

添加iptables条目:

  • 开放对应的协议和端口
  • 保存iptables条目
1
2
iptables -I INPUT 2 -p udp --dport 1194 -j ACCEPT
iptables-save > /etc/sysconfig/iptables

启动服务并设置开机启动

1
2
systemctl start openvpn@server
systemctl enable openvpn@server

Freeradius验证

编译Freeradius插件

1
2
3
4
5
cd ~
wget http://www.nongnu.org/radiusplugin/radiusplugin_v2.1.tar.gz
tar -zxvf radiusplugin_v2.1.tar.gz
cd radiusplugin
make

拷贝到配置文件夹内

1
2
cp radiusplugin.so /etc/openvpn
cp radiusplugin.cnf /etc/openvpn

修改配置文件server.conf,添加Freeradius插件相关选项

1
2
3
echo "client-cert-not-required" >> server.conf
echo "username-as-common-name" >> server.conf
echo "plugin /etc/openvpn/radiusplugin.so /etc/openvpn/radiusplugin.cnf" >> server.conf

修改radiusplugin.cnf中第一个server字段中的选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server
{
# The UDP port for radius accounting.
acctport=1813
# The UDP port for radius authentication.
authport=1812
# The name or ip address of the radius server.
name=10.30.8.8 #这里改成radius服务器地址,这里是本机
# How many times should the plugin send the if there is no response?
retry=1
# How long should the plugin wait for a response?
wait=1
# The shared secret.
sharedsecret=testing123 #这里改成radius的shared secret,radius默认是testing123
}

重新启动openvpn服务

1
systemctl restart openvpn@server

客户端静态IP设置

在某些情况下,需要向某些接入的办公区客户端分配固定的服务器区IP地址。

在配置文件server.conf中的添加client-config-dir ccd字段

在配置文件目录下创建ccd文件夹,例如要向用户user1分配固定的IP地址172.18.31.31 255.255.0.0,则在ccd文件夹下创建文件user1,内容如下

1
ifconfig-push 172.18.31.31 255.255.0.0

客户端之间通信

新的场景如下,私有网络为一个小型网络,放置一些服务器,可以通过NAT方式访问办公区网络。在办公区一般都是通过同时连接办公区私有网络的多网卡Windows服务器访问私有网络

服务器区服务器以及办公区的Bob需要直接访问私有网络的Alice。实现方式为Bob和Alice同时接入Carol的VPN服务,这样Bob和Alice都获取了服务器区的IP地址,逻辑上都在一个局域网中。

PPTP VPN可以实现这种思路,但是因为PPTP未知的不稳定原因,因此这里是使用的为OpenVPN的交换模式

确定配置文件/etc/openvpn/server.confclient-to-client字段启用。

3-1
图3-1 逻辑拓扑

4. 客户端配置

在不同平台下,OpenVPN客户端连接都需要一个配置文件,配置文件后缀为.ovpn,例子如下。更多详细配置,参考官网。

除了配置文件,还需要之前生成的ca.crt、ta.key文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
client
dev tap #路由模式使用tun,交换模式使用tap
proto udp
remote 10.30.30.13 1194 #服务器IP以及端口
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt #CA证书
tls-auth ta.key 1 #加密密钥
auth-user-pass #使用用户名密码验证
cipher AES-256-CBC #加密方式,应该与服务器相同
verb 3

Windows

下载OpenVPN客户端,将配置文件、ca.crt、ta.key放入安装目录下config文件夹中,使用图形界面启动即可,因为设置了帐号密码登录,会弹出输出帐号密码提示

iOS/Android

导入配置文件、ca.crt、ta.key到客户端

MacOS

使用TunnelBlick导入配置,并安装自签名CA证书到系统

Linux

安装openvpn服务

1
yum install -y openvpn

假设配置文件、ca.crt、ta.key都在/etc/openvpn/client目录下,命令行启动openvpn。更多配置参看OpenVPN的help选项。

  • –daemon后台运行
  • –config指定配置文件
  • –log-append指定日志
  • –auth-user-pass指定用户名密码文件。auth文件中第一行存放用户名,第二行存放密码。
1
2
cd /etc/openvpn/client
openvpn --daemon --config test.ovpn --log-append /var/log/openvpn.log --auth-user-pass auth

修订版本信息

修订版本 时间 备注
文档创建 2017/12/11 23:06 文件创建
文档修改1 2017/12/20 9:27 错误修改
文档修改2 2017/12/25 19:30 添加交换模式,更新客户端配置

参考