====== OpenVPN的简单配置 ====== VPN是Virtual Private Network(虚拟专用网络)的缩写,是在公共网络上通过隧道和加密技术创建专用(私有)网络的技术。[[http://openvpn.net|OpenVPN]]是基于SSL/TLS标准协议的一种VPN实现方案。 本文以[[..:env:net_simulation|用KVM虚拟机模拟网络环境]]中的网络拓扑结构为例,讲述一个简单的OpenVPN配置过程。 在这个例子中,home网络和away网络是同一个机构下的两个异地网络,为了让两地的内网用户能安全的互访,需要在两者之间搭建一条VPN通道。为此,slk-home-gate除了作为home网络的网关外,同时兼任OpenVPN Server;slk-away-gate网关则作为OpenVPN Client。此外,对于出差的用户,也能在外网通过授权证书作为OpenVPN Client接入到VPN中。 操作系统基于[[http://www.slackware.com|slackware64 14.0]]。 ===== 构建PKI ===== 首先构建我们自己的公钥基础设施PKI(Public Key Infrastructure)。在这里,我们将为OpenVPN Server和每个OpenVPN Client生成一对证书(Certificate,也叫公钥Public Key)和私钥(Private Key);同时生成一对主CA(Master Certificate Authority)用的证书和私钥,用于对OpenVPN Server和Client的证书进行签字。 ==== easy-rsa工具包 ==== OpenVPN提供了一个easy-rsa工具包,方便构建PKI。这里使用2.0版本,首先复制一份: # cd /usr/doc/openvpn-2.2.2/easy-rsa # cp -r 2.0 /root/easy-rsa # cd /root/easy-rsa 接下来的工作都在/root/easy-rsa目录下进行。 ==== vars配置文件 ==== 编辑vars配置文件,进行一些设置。主要的设置地方有: * KEY_CONFIG,指定openssl版本,一般由whichopensslcnf脚本自动判断; * KEY_DIR,生成的密钥存放目录,缺省为当前目录下的keys子目录; * KEY_SIZE,指定密钥长度,缺省为1024,如果用于生产环境,建议提高到2048; * KEY_COUNTRY、KEY_PROVINCE、KEY_CITY等放在证书中的信息。 这里我们仅设置一些信息字段(数据是虚构的): export KEY_COUNTRY="CN" export KEY_PROVINCE="Yunnan" export KEY_CITY="Kunming" export KEY_ORG="Yunnan University" export KEY_EMAIL="admin@copyleft.org" export KEY_NAME="OpenVPN" export KEY_OU="Information School" 不设置KEY_CN(指定Common Name),因为后续操作中这些信息会用到多次,但每次的Common Name都不一样。 应用配置: # . ./vars ==== 清理 ==== 开始生成新的密钥之前,先做一次清理工作: # ./clean-all ==== 生成CA的证书和私钥 ==== 生成主CA的证书和私钥,在Common Name的地方输入slk-home-ca: # ./build-ca 为了方便理解执行过程,这里同时附上输出信息: Generating a 1024 bit RSA private key .....................................++++++ ....++++++ writing new private key to 'ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [CN]: State or Province Name (full name) [Yunnan]: Locality Name (eg, city) [Kunming]: Organization Name (eg, company) [Yunnan University]: Organizational Unit Name (eg, section) [Information School]: Common Name (eg, your name or your server's hostname) [changeme]:slk-home-ca Name [OpenVPN]: Email Address [admin@copyleft.org]: ==== 生成Server的证书和私钥 ==== 生成OpenVPN Server的证书和私钥,Common Name设为slk-home-gate: # ./build-key-server slk-home-gate 输出信息: Generating a 1024 bit RSA private key ........++++++ ...........++++++ writing new private key to 'slk-home-gate.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [CN]: State or Province Name (full name) [Yunnan]: Locality Name (eg, city) [Kunming]: Organization Name (eg, company) [Yunnan University]: Organizational Unit Name (eg, section) [Information School]: Common Name (eg, your name or your server's hostname) [slk-home-gate]: Name [OpenVPN]: Email Address [admin@copyleft.org]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /root/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CN' stateOrProvinceName :PRINTABLE:'Yunnan' localityName :PRINTABLE:'Kunming' organizationName :PRINTABLE:'Yunnan University' organizationalUnitName:PRINTABLE:'Information School' commonName :PRINTABLE:'slk-home-gate' name :PRINTABLE:'OpenVPN' emailAddress :IA5STRING:'admin@copyleft.org' Certificate is to be certified until Nov 11 22:30:55 2022 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated ==== 生成Client的证书和私钥 ==== 生成OpenVPN Client的证书和私钥。首先为slk-away-gate生成,Common Name也设为slk-home-gate: # ./build-key slk-away-gate 输出信息: Generating a 1024 bit RSA private key ..................++++++ .................++++++ writing new private key to 'slk-away-gate.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [CN]: State or Province Name (full name) [Yunnan]: Locality Name (eg, city) [Kunming]: Organization Name (eg, company) [Yunnan University]: Organizational Unit Name (eg, section) [Information School]: Common Name (eg, your name or your server's hostname) [slk-away-gate]: Name [OpenVPN]: Email Address [admin@copyleft.org]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /root/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CN' stateOrProvinceName :PRINTABLE:'Yunnan' localityName :PRINTABLE:'Kunming' organizationName :PRINTABLE:'Yunnan University' organizationalUnitName:PRINTABLE:'Information School' commonName :PRINTABLE:'slk-away-gate' name :PRINTABLE:'OpenVPN' emailAddress :IA5STRING:'admin@copyleft.org' Certificate is to be certified until Nov 11 22:37:11 2022 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated 为其他OpenVPN Client生成证书和私钥,可以有多份: # ./build-key slk-home-client2 # ./build-key slk-home-client3 ... ==== 生成Diffie Hellman参数 ==== 生成Diffie Hellman parameters,在OpenVPN Server上会用到: # ./build-dh ==== 密钥派发 ==== 至此,所有的证书和私钥都生成完毕,后续就可以派发到相应的机器上。PKI所在的机器原理上是独立的,不需要和OpenVPN Server或Client在同一台机器上。 在派发密钥时,私钥(后缀为.key)必须通过一个安全的秘密通道进行,证书(后缀为.crt)和Diffie Hellman参数则不必。 ===== OpenVPN Server配置 ===== ==== 获得密钥 ==== 从PKI获得CA证书、Server证书和私钥、DH参数,并放到相应位置: * ca.crt -> /etc/openvpn/certs/ * slk-home-gate.crt -> /etc/openvpn/certs/ * slk-home-gate.key -> /etc/openvpn/keys/ * dh1024.pem -> /etc/openvpn/ ==== 复制配置文件 ==== 先复制一份OpenVPN提供的配置样例,再做修改: # cd /etc/openvpn/ # cp /usr/doc/openvpn-2.2.2/sample-config-files/server.conf . 接下来编辑server.conf进行设置,我们将配置一个routed模式的OpenVPN。 ==== 设置密钥 ==== 首先设置各个密钥信息: ca certs/ca.crt cert certs/slk-home-gate.crt key keys/slk-home-gate.key # This file should be kept secret dh dh1024.pem ==== 设置虚拟网络地址 ==== 指定VPN将要使用的虚拟网络地址范围: server 10.10.40.0 255.255.255.0 OpenVPN Server将自动使用10.10.40.1这个地址。 至此,就配好了一个最基本的OpenVPN Server,可以与OpenVPN Clients建立点对点的VPN连接了。 当然,这样的功能远远不够,下面继续。 ==== 加入Server端本地网络 ==== 此时的VPN网络只包含OpenVPN Server和各个OpenVPN Clients。要实现我们的目标,首先要将Server端(slk-home-gate)的本地网络(home-work网络)包含进来: push "route 10.10.10.0 255.255.255.0" ==== 加入slk-away-gate的本地网络 ==== 接下来要将作为OpenVPN Client之一的slk-away-gate的本地网络(away-work网络)包含进VPN网络。 首先在/etc/openvpn目录下新建子目录ccd(代表client-config-dir): # mkdir /etc/openvpn/ccd 在ccd目录下创建与每个OpenVPN Client相关的配置文件,文件以OpenVPN Client证书的Common Name命名,这个例子的文件名是slk-away-gate。文件内容: iroute 10.20.10.0 255.255.255.0 然后编辑server.conf,添加: client-config-dir ccd route 10.20.10.0 255.255.255.0 ==== 让OpenVPN Clients可以互访 ==== 虽然都在VPN网络里,但缺省模式下,OpenVPN Clients只能与OpenVPN Server通信,彼此不能通信。要允许这个功能,需要配置: client-to-client ==== 让别的OpenVPN Clients可以与away-work网络互访 ==== 虽然之前已经将away-work网络加入到VPN网络里,但只能与OpenVPN Server端机器互访,因为其他OpenVPN Clients的路由表不知道如何到达away-work网络。为此增加一条路由: push "route 10.20.10.0 255.255.255.0" ==== 降低OpenVPN进程权限 ==== 这是一个安全方面的考虑,在OpenVPN进程启动完成后,将进程权限由超级用户降为普通用户权限: user nobody group nobody 至此,就是实现我们目标的最基本配置。 OpenVPN还有很多功能,更多细节可参考官方的[[http://openvpn.net/howto.html|Howto]]和[[http://openvpn.net/man.html|Manual]]。 ===== OpenVPN Client配置 ===== OpenVPN Clients的配置都是类似的,这里以slk-away-gate为例。 ==== 获得密钥 ==== 从PKI获得CA证书、自己的证书和私钥,并放到相应位置: * ca.crt -> /etc/openvpn/certs/ * slk-away-gate.crt -> /etc/openvpn/certs/ * slk-away-gate.key -> /etc/openvpn/keys/ ==== 复制配置文件 ==== 同样先复制一份OpenVPN提供的Client配置样例,再做修改: # cd /etc/openvpn/ # cp /usr/doc/openvpn-2.2.2/sample-config-files/client.conf . 接下来编辑client.conf进行设置。 ==== 设置密钥 ==== 首先设置各个密钥信息: ca certs/ca.crt cert certs/slk-away-gate.crt key keys/slk-away-gate.key ==== 设置OpenVPN Server的地址 ==== 指定OpenVPN Server的IP地址和端口: remote 172.16.0.10 1194 ==== 降低OpenVPN进程权限 ==== 在OpenVPN进程启动完成后,将进程权限由超级用户降为普通用户权限: user nobody group nobody 配置完毕。 ===== 启动OpenVPN ===== 首先启动OpenVPN Server,在slk-home-gate执行: # cd /etc/openvpn/ # openvpn server.conf 然后启动OpenVPN Clients,与OpenVPN Server连接: # cd /etc/openvpn/ # openvpn client.conf 配置无误的话,VPN网络就搭建起来了。可以先关闭iptables防火墙,进行各种测试,看是否与预期一致。 ===== iptables防火墙设置 ===== 测试通过后,iptables防火墙还得恢复。slk-home-gate和slk-away-gate之前运行的都是网关模板的脚本,详情可参见[[.:iptables|iptables脚本]]。 接下来就看,在引入OpenVPN后,脚本需要做那些调整。 首先,OpenVPN Server缺省监听在1194的UDP端口,所以,Server端需要打开该端口: # 3.4.2 Allow OpenVPN (only for server). # $IPTABLES -A INPUT -i $WAN_IFACE -p udp --dport 1194 -m state \ --state NEW -j ACCEPT 相应的,OpenVPN Client要能连接Server的1194端口: # 3.5.10 Allow OpenVPN(only for client). # $IPTABLES -A OUTPUT -o $WAN_IFACE -d $VPN_SERVER_IP -p udp --dport 1194 \ -m state --state NEW -j ACCEPT OpenVPN启动后,会建立新的网络接口,如tun0(routed模式),相当于在原有网络基础上,又多了一个子网。自然的,需要针对新接口制定一些新规则。 增加新接口的配置信息: # 1.6 VPN configuration. # VPN_IP="10.10.40.1" VPN_IFACE="tun+" VPN_BROADCAST="10.10.40.255" VPN_SERVER_IP="172.16.0.10" 增加内核模块的装载: $MODPROBE tun 在Input链,允许在VPN接口接受ping请求: $IPTABLES -A INPUT -i $VPN_IFACE -p icmp --icmp-type echo-request -j ACCEPT 在Forward链,允许内网与VPN网互访,这也是我们搭建VPN的目的。当然,也可制定更细粒度的规则: # 3.6.5 LAN --> VPN rules. # # 3.6.5.1 Allow full access. # $IPTABLES -A FORWARD -i $LAN_IFACE -o $VPN_IFACE -m state \ --state NEW -j ACCEPT # # 3.6.6 LAN <-- VPN rules. # # 3.6.6.1 Allow full access. # $IPTABLES -A FORWARD -i $VPN_IFACE -o $LAN_IFACE -m state \ --state NEW -j ACCEPT 在[[.:iptables|iptables脚本]]提供了一份融合了上述配置的OpenVPN网关模板,可点击其中的[[.:iptables#脚本类型|脚本类型]]进行下载。 {{tag>OpenVPN iptables}}