安装 OpenVPN
easy-rsa
可以用来生成Open VPN
服务端需要的证书
yum install -y openvpn easy-rsa
配置服务端配置文件
cp /usr/share/doc/openvpn-2.4.12/sample/sample-config-files/server.conf /etc/openvpn/
########################################################################### # 针对多客户端的OpenVPN 2.0 的服务器端配置文件示例 # # 本文件用于多客户端<->单服务器端的OpenVPN服务器端配置 # # OpenVPN也支持单机<->单机的配置(更多信息请查看网站上的示例页面) # # 该配置支持Windows或者Linux/BSD系统。此外,在Windows上,记得将路径加上双引号, # 并且使用两个反斜杠,例如:"C:\\Program Files\\OpenVPN\\config\\foo.key" # # '#' or ';'开头的均为注释内容 ########################################################################### # OpenVPN应该监听本机的哪些IP地址 # 该命令是可选的,如果不设置,则默认监听本机的所有IP地址 ;local a.b.c.d # OpenVPN 应该监听哪个 TCP/UDP 端口 # 如果你想在同一台计算机上运行多个 OpenVPN 实例,你可以使用不同的端口号来区分它们 # 此外,你需要在防火墙上开放这些端口 port 1194 # OpenVPN 使用 TCP 还是 UDP 协议 ;proto tcp proto udp # 指定 OpenVPN 创建的通信隧道类型 # "dev tun" 将会创建一个路由IP隧道 # "dev tap" 将会创建一个以太网隧道 # 如果你是以太网桥接模式,并且提前创建了一个名为 "tap0" 的与以太网接口进行桥接的虚拟接口,则你可以使用 "dev tap0" # 如果你想控制 VPN 的访问策略,你必须为 TUN/TAP 接口创建防火墙规则 # 在非Windows系统中,你可以给出明确的单位编号(unit number),例如"tun0" # 在 Windows 中,你也可以使用 "dev-node" # 在多数系统中,除非你部分禁用或者完全禁用了 TUN/TAP 接口的防火墙,否则 VPN 将不起作用 ;dev tap dev tun # 如果你想配置多个隧道,你需要用到网络连接面板中 TAP-Win32 适配器的名称(例如 "MyTap" ) # 在 XP SP2 或更高版本的系统中,你可能需要有选择地禁用掉针对 TAP 适配器的防火墙 # 通常情况下,非Windows系统则不需要该指令 ;dev-node MyTap # 设置SSL/TLS根证书(ca)、证书(cert)和私钥(key) # 每个客户端和服务器端都需要它们各自的证书和私钥文件 # 服务器端和所有的客户端都将使用相同的CA证书文件 # 通过 easy-rsa 目录下的一系列脚本可以生成所需的证书和私钥 # 记住,服务器端和每个客户端的证书必须使用唯一的 Common Name # 你也可以使用遵循 X509 标准的任何密钥管理系统来生成证书和私钥。 # OpenVPN 也支持使用一个 PKCS #12 格式的密钥文件(详情查看站点手册页面的 "pkcs12" 指令) ca ca.crt cert server.crt # 该文件应该保密 key server.key # Diffie hellman parameters 算法 # 你可以使用如下名称命令生成你的文件: # openssl dhparam -out dh1024.pem 1024 # 如果你使用的是2048位密钥,使用2048替换其中的1024 dh dh2048.pem # 网络拓扑结构 # 应为子网(通过 IP 寻址),除非必须支持 Windows 客户端 v2.0.9 或更低版本 # (然后是 net30,即每个客户端一个 /30) # 默认值为 net30(不推荐) topology subnet # 设置服务器端模式,并提供一个 VPN 子网,以便于从中为客户端分配 IP 地址 # 在此处的示例中,服务器端自身将占用 10.8.0.1,其他的将提供客户端使用 # 如果你使用的是以太网桥接模式,请注释掉该行。更多信息请查看官方手册页面 server 10.8.0.0 255.255.255.0 # 指定用于记录客户端和虚拟 IP 地址的关联关系的文件 # 当重启 OpenVPN 时,再次连接的客户端将分配到与上一次分配相同的虚拟IP地址 ifconfig-pool-persist ipp.txt # 该指令仅针对以太网桥接模式 # 首先,你必须使用操作系统的桥接能力将以太网网卡接口和TAP接口进行桥接 # 然后,你需要手动设置桥接接口的IP地址、子网掩码;在这里,我们假设为 10.8.0.4 和 255.255.255.0 # 最后,我们必须指定子网的一个IP范围 (例如从 10.8.0.50 开始,到 10.8.0.100 结束),以便于分配给连接的客户端 # 如果你不是以太网桥接模式,直接注释掉这行指令即可 ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 # 该指令仅针对使用 DHCP 代理的以太网桥接模式, # 此时客户端将请求服务器端的 DHCP 服务器,从而获得分配给它的 IP 地址和 DNS 服务器地址 # 在此之前,你也需要先将以太网网卡接口和 TAP 接口进行桥接 # 注意:该指令仅用于 OpenVPN 客户端,并且该客户端的 TAP 适配器需要绑定到一个 DHCP 客户端上 ;server-bridge # 推送路由信息到客户端,以允许客户端能够连接到服务器背后的其他私有子网 # (简而言之,就是允许客户端访问 VPN 服务器自身所在的其他局域网) # 记住,这些私有子网也要将 OpenVPN 客户端的地址池( 10.8.0.0/255.255.255.0 )反馈回 OpenVPN 服务器 ;push "route 192.168.10.0 255.255.255.0" ;push "route 192.168.20.0 255.255.255.0" # 为指定的客户端分配指定的 IP 地址,或者客户端背后也有一个私有子网想要访问 VPN, # 那么你可以针对该客户端的配置文件使用ccd子目录 # (简而言之,就是允许客户端所在的局域网成员也能够访问VPN) # 举个例子:假设有个 Common Name 为 "Thelonious" 的客户端背后也有一个小型子网想要连接到 VPN, # 该子网为 192.168.40.128/255.255.255.248 # 首先,你需要去掉下面两行指令的注释: ;client-config-dir ccd ;route 192.168.40.128 255.255.255.248 # 然后创建一个文件 ccd/Thelonious,该文件的内容为: # iroute 192.168.40.128 255.255.255.248 # 这样客户端所在的局域网就可以访问VPN了 # 注意,这个指令只能在你是基于路由、而不是基于桥接的模式下才能生效 # 比如,你使用了 "dev tun" 和 "server" 指令 # 再举个例子:假设你想给 Thelonious 分配一个固定的IP地址 10.9.0.1 # 首先,你需要去掉下面两行指令的注释: ;client-config-dir ccd ;route 10.9.0.0 255.255.255.252 # 然后在文件 ccd/Thelonious 中添加如下指令: # ifconfig-push 10.9.0.1 10.9.0.2 # 如果你想要为不同群组的客户端启用不同的防火墙访问策略,你可以使用如下两种方法: # (1) 运行多个 OpenVPN 守护进程,每个进程对应一个群组,并为每个进程(群组)启用适当的防火墙规则 # (2) (进阶)创建一个脚本来动态地修改响应于来自不同客户的防火墙规则 # 关于 learn-address 脚本的更多信息请参考官方手册页面 ;learn-address ./script # 如果启用该指令,所有客户端的默认网关都将重定向到VPN,这将导致诸如 web 浏览器、DNS 查询等所有客户端流量都经过VPN # (为确保能正常工作,OpenVPN 服务器所在计算机可能需要在 TUN/TAP 接口与以太网之间使用 NAT 或桥接技术进行连接) ;push "redirect-gateway def1 bypass-dhcp" # 某些具体的 Windows 网络设置可以被推送到客户端,例如 DNS 或 WINS 服务器地址 # 下列地址来自 opendns.com 提供的 Public DNS 服务器 ;push "dhcp-option DNS 208.67.222.222" ;push "dhcp-option DNS 208.67.220.220" ;push "dhcp-option DNS 114.114.114.114" # 去掉该指令的注释将允许不同的客户端之间相互"可见"(允许客户端之间互相访问) # 默认情况下,客户端只能"看见"服务器 # 为了确保客户端只能看见服务器,你还可以在服务器端的 TUN/TAP 接口上设置适当的防火墙规则 ;client-to-client # 如果多个客户端可能使用相同的证书/私钥文件或 Common Name 进行连接,那么你可以取消该指令的注释。 # 建议该指令仅用于测试目的。对于生产使用环境而言,每个客户端都应该拥有自己的证书和私钥。 # 如果你没有为每个客户端分别生成 Common Name 唯一的证书/私钥,你可以取消该行的注释 (但不推荐这样做) ;duplicate-cn # keepalive 指令将导致类似于 ping 命令的消息被来回发送,以便于服务器端和客户端知道对方何时被关闭 # 每 10 秒钟 ping一次,如果 120 秒内都没有收到对方的回复,则表示远程连接已经关闭 keepalive 10 120 # 出于 SSL/TLS 之外更多的安全考虑,创建一个 "HMAC 防火墙" 可以帮助抵御 DoS 攻击和 UDP 端口淹没攻击 # 你可以使用以下命令来生成: # openvpn --genkey --secret ta.key # 服务器和每个客户端都需要拥有该密钥的一个拷贝 # 第二个参数在服务器端应该为'0',在客户端应该为'1' # 该文件应该保密 tls-auth ta.key 0 # 选择一个密码加密算法。 # 该配置项也必须复制到每个客户端配置文件中 # 注意,v2.4 客户端 / 服务器将在 TLS 模式下自动协商 AES-256-GCM # 另请参阅手册页中的 ncp 密码选项 cipher AES-256-CBC # 在 VPN 链接上启用压缩并将该选项推送到客户端(仅限 v2.4+,早期版本请参见下文) ;compress lz4-v2 ;push "compress lz4-v2" # 在VPN连接上启用压缩 # 如果你在此处启用了该指令,那么也应该在每个客户端配置文件中启用它 ;comp-lzo # 客户端最大连接数 max-clients 100 # 在完成初始化工作之后,降低 OpenVPN 守护进程的权限是个不错的主意 # 该指令仅限于非 Windows 系统中使用 ;user nobody ;group nobody # 持久化选项可以尽量避免访问那些在重启之后由于用户权限降低而无法访问的某些资源 persist-key persist-tun # 输出一个简短的状态文件,用于显示当前的连接状态,该文件每分钟都会清空并重写一次 status openvpn-status.log # 默认情况下,日志消息将写入 syslog (在 Windows 系统中,如果以服务方式运行,日志消息将写入 OpenVPN 安装目录的 log 文件夹中) # 你可以使用 log 或者 log-append 来改变这种默认情况 # "log" 方式在每次启动时都会清空之前的日志文件 # "log-append" 这是在之前的日志内容后进行追加 # 你可以使用两种方式之一(但不要同时使用) ;log openvpn.log ;log-append openvpn.log # 为日志文件设置适当的冗余级别 (0~9) # 冗余级别越高,输出的信息越详细 # 0 表示静默运行,只记录致命错误 # 4 表示合理的常规用法 # 5 和 6 可以帮助调试连接错误 # 9 表示极度冗余,输出非常详细的日志信息 verb 3 # 重复信息的沉默度 # 相同类别的信息只有前 20 条会输出到日志文件中 ;mute 20 # 通知客户端,当服务器重新启动时,它可以自动重新连接 [ 这个必须 proto 配置为 udp 才行 ] # 如果不是 udp 模式,会报错 'Options error: --explicit-exit-notify can only be used with --proto udp' explicit-exit-notify 1
根据自己的实际情况,配置好服务端的配置文件
port 31194 proto tcp dev tun ca /etc/openvpn/server/cert/ca.crt # 这里要以自己实际的证书文件名称来命名,以自己的实际场景为准 cert /etc/openvpn/server/cert/chen2ha.crt # 这里要以自己实际的证书文件名称来命名,以自己的实际场景为准 key /etc/openvpn/server/cert/chen2ha.key dh /etc/openvpn/server/cert/dh2048.pem topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "route 10.0.0.0 255.255.252.0" push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 114.114.114.114" keepalive 10 120 cipher AES-256-CBC comp-lzo max-clients 100 persist-key persist-tun status /etc/openvpn/server/logs/openvpn-status.log log-append /etc/openvpn/server/logs/openvpn.log verb 3 mute 20
创建相关的路径
mkdir /etc/openvpn/server/{cert,logs}
生成 CA 证书
复制
easy-rsa
文件
cp -r /usr/share/easy-rsa /etc/openvpn/
复制 easy-rsa
变量配置文件
cp /usr/share/doc/easy-rsa-3.0.8/vars.example /etc/openvpn/easy-rsa/3/vars
配置变量文件
# 所在的国家 set_var EASYRSA_REQ_COUNTRY "CN" # 所在的省份 set_var EASYRSA_REQ_PROVINCE "Shang Hai" # 所在的城市 set_var EASYRSA_REQ_CITY "Shang Hai" # 所属的组织 set_var EASYRSA_REQ_ORG "devops" # 邮件地址 set_var EASYRSA_REQ_EMAIL "chen2ha@devops.com" # 组织单位,部门 set_var EASYRSA_REQ_OU "openvpn" # 密钥长度 set_var EASYRSA_KEY_SIZE 2048 # 算法 set_var EASYRSA_ALGO rsa # ca 有效期,单位为天 set_var EASYRSA_CA_EXPIRE 365000 # 服务端和客户端证书有效期,单位为天 set_var EASYRSA_CERT_EXPIRE 3650
初始化 PKI 相关目录和文件
cd /etc/openvpn/easy-rsa/3 ./easyrsa init-pki
创建 ca 机构
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:
可以随意填写,也可以直接回车
./easyrsa build-ca nopass
完成后,会提示 ca 证书的路径
Your new CA certificate file for publishing is at: /etc/openvpn/easy-rsa/3/pki/ca.crt
复制 ca 证书到配置文件指定的路径下
cp /etc/openvpn/easy-rsa/3/pki/ca.crt /etc/openvpn/server/cert/
创建服务端证书流程
以下的申请文件和颁发,可以归结成一个命令
cd /etc/openvpn/easy-rsa/3 ./easyrsa build-server-full chen2ha nopass
创建服务端证书申请文件
chen2ha
表示生成的 申请文件的名称,生成的文件名称为:chen2ha.req
和chen2ha.key
Common Name (eg: your user, host, or server name) [chen2ha]:
直接回车
cd /etc/openvpn/easy-rsa/3 ./easyrsa gen-req chen2ha nopass
完成后,会提示证书的路径
Keypair and certificate request completed. Your files are: req: /etc/openvpn/easy-rsa/3/pki/reqs/chen2ha.req key: /etc/openvpn/easy-rsa/3/pki/private/chen2ha.key
复制证书到配置文件指定的路径下
cp /etc/openvpn/easy-rsa/3/pki/private/chen2ha.key /etc/openvpn/server/cert/chen2ha.key
颁发服务端证书
server
表示类型
./easyrsa sign server chen2ha
完成后,会提示证书的路径
Certificate created at: /etc/openvpn/easy-rsa/3/pki/issued/chen2ha.crt
复制证书到配置文件指定的路径下
cp /etc/openvpn/easy-rsa/3/pki/issued/chen2ha.crt /etc/openvpn/server/cert/chen2ha.crt
创建 Diffie-Hellman 密钥
注意
-out
参数后面的路径和文件名称要改成和配置文件里面的一致
openssl dhparam -out /etc/openvpn/server/cert/dh2048.pem 2048
服务端开启 ip_forward 功能
查看服务端是否开启了
grep net.ipv4.ip_forward /etc/sysctl.conf
如果返回为空,执行下面的命令
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
如果返回 net.ipv4.ip_forward = 0
,执行下面的命令
sed -i 's/net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
使功能立即生效
sysctl -p
添加 SNAT 规则
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
如果没有其他 iptables
规则,可以执行 iptables save
保存这条规则,如果不确定,可以把这条命令追加到 /etc/rc.d/rc.local
文件内
/etc/rc.d/rc.local
文件必须要有执行权限才能保证开机后会被读取
echo 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE' >> /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local
启动 OpenVPN 服务
实际的 unit 文件名称是
openvpn@.service
systemctl enable --now openvpn@server
验证隧道网卡是否创建成功
ifconfig tun0
创建客户端证书
同样可以总结成一个命令
cd /etc/openvpn/easy-rsa/3 ./easyrsa build-client-full zhangsan nopass
创建客户端证书申请文件
和服务端的操作方式一致,只需要将
zhangsan
替换成自己需要分配的人员名称即可
cd /etc/openvpn/easy-rsa/3 ./easyrsa gen-req zhangsan nopass
颁发客户端证书
./easyrsa sign client zhangsan
配置客户端配置文件
需要以
.ovpn
后缀,配置的解释和server
端的一致
client dev tun proto tcp remote <公网 ip> 1194 # 无限期地尝试解析 OpenVPN 服务器的主机名 ## 对于笔记本电脑等未永久连接到互联网的机器非常有用 resolv-retry infinite # 大多数客户端不需要绑定到特定的本地端口号 nobind persist-key persist-tun ca ca.crt # 用户的证书文件名称 cert <用户名称>.crt key <用户名称>.key remote-cert-tls server verb 3 comp-lzo route <ip> <netmask> vpn_gateway # 客户端路由配置 # route-nopull - OpenVPN 连接后不会添加路由,也就是不会有任何网络请求走 OpenVPN # vpn_gateway - 指定 IP 的网络请求走 OpenVPN # net_gateway - 和 vpn_gateway 相反,表示在默认出去的访问全部走 OpenVPN 时,强行指定部分 IP 访问不通过 OpenVPN 出去 ## max-routes 参数表示可以添加路由的条数,默认只允许添加 100 条路由,如果少于 100 条路由可不加这个参数
打包客户端证书
mkdir /etc/openvpn/client/zhangsan vim /etc/openvpn/client/zhangsan/zhangsan.ovpn
client dev tun proto tcp remote <公网 ip> 31194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert zhangsan.crt key zhangsan.key remote-cert-tls server verb 3 comp-lzo route 10.0.0.0 255.255.252.0 vpn_gateway
汇总证书文件
cp /etc/openvpn/easy-rsa/3/pki/ca.crt /etc/openvpn/client/zhangsan/ for i in crt key;do find /etc/openvpn/easy-rsa/3/pki/ -name "zhangsan.${i}" -exec cp {} /etc/openvpn/client/zhangsan/ \;;done
打包证书和配置文件
cd /etc/openvpn/client/ tar czf zhangsan.tgz zhangsan/*
删除客户端证书
执行完命令后,相关的证书文件都会被删除,如果做了上面的证书汇总的操作,也要记得把汇总的文件删除了,避免后期的管理混乱
cd /etc/openvpn/easy-rsa/3 ./easyrsa revoke zhangsan