本文已参与「掘力星计划」
各位处在Linux运维潮流中的大佬们,文章不才,在这里特此分享一套VPN服务器搭建的流程及使用分享。
每个公司都或多或少的进行远程办公,有的公司会采用向日葵
orTeamviewer
也或者是ngrok
、灰鸽子
等内网穿透软件,这些软件大都进行收费、限速、无法本地连接公司电脑。为了避免这种情况的发生,合理利用公司的网络带宽、实现远程办公,本地直通公司网络,每个工程师会给公司搭建一套VPN来实现人员的要求。VPN的方式有很多种,像ike、pptp、l2tp等都可以作为选择,这里我给大家分享一下OpenVPN的搭建。
首先,我们需要准备一台自己的服务器,如果使用的人非常多建议将配置提高一下来承载压力,我们先来准备一下运行环境。
openvpn运行环境
系统 | 版本 |
---|---|
centos7 | 7.7.1908 |
OpenVPN | 2.4.8 |
mysql/mariadb-server | 5.5.64 |
easyrsa | 3.0.6 |
有了前提准备,还要继续了解到OpenVPN并不在CentOS-Base源中,而是在扩展源epel
中,有了这些信息那我们接下来开始正式安装,let's go!
- 安装 epel、openvpn、mariadb-server 数据库软件
[root@vpnserver ~]# yum -y install epel-release
[root@vpnserver ~]# yum -y install openvpn mariadb-server
在执行完上述操作后,整个系统就已经完成了30%了,要让它正常工作还需要对它进行一下设置。在使用OpenVPN的原因就是他可以保证每个客户端使用自己的证书和服务器来建立连接(非强制)、还可以控制客户端之间能否进行通信、使用隧道模式or桥接模式、dh加密等。客户端和服务器之间的第一道安全就是证书,如果加上dh加密
,那更加安全。下面我们来生成证书。
easyrsa
是一个封装的openssl
工具,通过几个简单命令就可以生成证书,简化了openssl
的操作复杂性,这个程序可以在github上下载下来也可以使用epel
源中的,这里我使用的是github
上的,首先下载 easyrsa 生成证书,这里用的是3.0.6
的版。
[root@vpnserver ~]# wget https://github.com/OpenVPN/easy-rsa/archive/v3.0.6.tar.gz -o easyrsa-v3.0.6.tar.gz
[root@vpnserver ~]# tar xf easyrsa-v3.0.6.tar.gz
创建 CA 根证书
- 创建证书需要将公司的信息写到配置文件里面,easyrsa默认会读取vars中的内容并利用这些内容生成CA证书
[root@vpnserver ~]# cd easy-rsa-3.0.6/easyrsa3/
[root@vpnserver easyrsa3]# cp vars.sample vars
[root@vpnserver easyrsa3]# grep -Ev "^$|^#" vars
if [ -z "$EASYRSA_CALLER" ]; then
echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2
echo "This is no longer necessary and is disallowed. See the section called" >&2
echo "'How to use this file' near the top comments for more details." >&2
return 1
fi
set_var EASYRSA "${0%/*}"
set_var EASYRSA_OPENSSL "openssl"
set_var EASYRSA_PKI "$PWD/pki"
set_var EASYRSA_DN "cn_only"
set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "BeiJing"
set_var EASYRSA_REQ_CITY "BeiJing"
set_var EASYRSA_REQ_ORG "北京爱数智慧科技有限公司"
set_var EASYRSA_REQ_EMAIL "qiyongxiao@magicdatatech.com"
set_var EASYRSA_REQ_OU "北京爱数智慧科技有限公司"
set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_ALGO rsa
set_var EASYRSA_CA_EXPIRE 7300
set_var EASYRSA_CERT_EXPIRE 7300
set_var EASYRSA_CERT_RENEW 30
set_var EASYRSA_CRL_DAYS 180
set_var EASYRSA_NS_SUPPORT "no"
set_var EASYRSA_NS_COMMENT "Magicdata Certificate"
set_var EASYRSA_TEMP_FILE "$EASYRSA_PKI/extensions.temp"
set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-easyrsa.cnf"
set_var EASYRSA_DIGEST "sha256"
- 接下来需要对工作目录进行初始化,正式创建证书(瞪大眼睛,千万不要走神)
[root@vpnserver easyrsa3]# ./easyrsa init-pki
[root@vpnserver easyrsa3]# ./easyrsa build-ca
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
Enter New CA Key Passphrase: magicdata(ca 密码)
Re-Enter New CA Key Passphrase: magicdata(ca 密码)
Generating RSA private key, 2048 bit long moduluse
..........................................................................................................+++.......+++ is 65537 (0x10001)
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:Magicdata
- 创建服务器端证书(证书无密码)
[root@vpnserver easyrsa3]# ./easyrsa gen-req server nopass
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
Generating a 2048 bit RSA private key
...............................+++
.......+++
writing new private key to '/root/easy-rsa-3.0.6/easyrsa3/pki/private/server.key.kh1xRAY7ZI'
-----
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.
-----
Common Name (eg: your user, host, or server name) [server]:vpnserver
- 使用CA对服务器端的证书进行签名
[root@vpnserver easyrsa3]# ./easyrsa sign server server
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a server certificate for 7300 days:
subject=
commonName = vpnserver
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from /root/easy-rsa-3.0.6/easyrsa3/pki/safessl-easyrsa.cnf
Enter pass phrase for /root/easy-rsa-3.0.6/easyrsa3/pki/private/ca.key: magicdata(输入ca 证书的密码)
Check that the request matches the signature
Signature verification problems....
140517964466064:error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm:a_verify.c:206:
Certificate created at: /root/easy-rsa-3.0.6/easyrsa3/pki/issued/server.crt
- 创建 dh 秘钥(耗时稍微长一些)
[root@vpnserver easyrsa3]# ./easyrsa gen-dh
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
DH parameters of size 2048 created at /root/easy-rsa-3.0.6/easyrsa3/pki/dh.pem
准备好证书后就可以生成我们的配置文件,由于服务器端的证书没有添加密码,所以不需要添加额外配置。准备好的配置文件如下:
[root@vpnserver ~]# cp /usr/share/doc/openvpn-2.4.8/sample/sample-config-files/server.conf /etc/openvpn/server/
[root@vpnserver ~]# cp /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so /etc/openvpn/server/
[root@vpnserver ~]# grep -Ev '^#|^$|^;' /etc/openvpn/server/server.conf
local 192.168.4.228 #指定监听地址,可以是0.0.0.0
port 1194 #指定端口
proto udp #指定协议,可选 tcp 或 udp
dev tun #隧道类型,可选 tun 或 tap
#tap模式也就是桥接模式,通过软件在系统中模拟出一个tap设备,该设备是一个二层设备,同时支持链路层协议。
#tun模式也就是路由模式,通过软件在系统中模拟出一个tun路由,tun是ip层的点对点协议。
verify-client-cert none #不验证客户端证书
username-as-common-name #将用户名作为 common name
ca server/ca.crt
cert server/server.crt
key server/server.key # This file should be kept secret
dh server/dh.pem
;tls-auth /etc/openvpn/server/ta.key 0 # 如果添加这个配置,每个客户端都需要携带
topology subnet
server 10.8.0.0 255.255.255.0 #拨号后客户端地址范围
ifconfig-pool-persist ipp.txt #服务器自动给客户端分配IP后,客户端下次连接时,仍然采用上次的IP地址(第一次分配的IP保存在ipp.txt中,下一次分配其中保存的IP,实际效果并不好)
push "route 192.168.9.0 255.255.255.0" #添加内网网段
push "route 172.16.100.0 255.255.255.0"
push "route 192.168.3.0 255.255.255.0"
push "route 192.168.7.0 255.255.255.0"
push "route 192.168.4.0 255.255.255.0"
push "dhcp-option DNS 114.114.114.114" #如果有内网DNS,需要填写一个
push "dhcp-option DNS 202.106.0.20"
#client-to-client #允许客户端与客户端相连
keepalive 10 120
cipher AES-256-CBC
compress lz4-v2
push "compress lz4-v2"
max-clients 300 #最大客户端
user root #可以看下不用root能不能监听端口,不建议使用root用户
group root
;duplicate-cn #多个客户端使用同一个证书进行连接时,需要开启
- 准备好配置文件就可以启动这个服务了,但在启动之前还需要将服务器的内核转发功能打开,这个功能如果不打开,VPN流量是无法到达目标服务器,拨VPN之后只能和VPN服务器进行通信;OpenVPN还依赖
firewalld
来实现地址路由,由于开启了防火墙在对外提供服务的时候需要允许openvpn的流量进入
[root@vpnserver ~]# cat <<EOF> /etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward = 1
EOF
[root@vpnserver ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled' /etc/selinux/config
[root@vpnserver ~]# sysctl -p && setenforce 0
[root@vpnserver ~]# firewall-cmd --zone=public --add-masquerade
[root@vpnserver ~]# firewall-cmd --add-port=1194/udp --zone=public
[root@vpnserver ~]# firewall-cmd --add-service=openvpn --zone=public
[root@vpnserver ~]# firewall-cmd --add-service=ssh --zone=public
添加了这些规则我们来看一下配置是否正确,需不需要再添加额外的规则
[root@vpnserver ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens192
sources:
services: docker-registry git gre ipsec openvpn ssh telnet
ports: 4500/udp 500/udp 1701/udp 1194/udp
protocols: ah esp icmp
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
- 将证书文件放在openvpn配置目录中
[root@vpnserver easyrsa3]# pwd
/root/easy-rsa-3.0.6/easyrsa3
[root@vpnserver easyrsa3]# cp pki/ca.crt pki/issued/server.crt pki/private/server.key pki/dh.pem /etc/openvpn/server/
- 启动我们的VPN服务
[root@vpnserver ~]# systemctl start openvpn-server@server
[root@vpnserver ~]# netstat -ntlpu|grep 1194
udp 0 0 192.168.4.228:1194 0.0.0.0:* 30749/openvpn
使用 mysql 数据库做用户名密码认证
- 直接安装下面这个软件
[root@vpnserver ~]# rpm -Uvh http://repo.iotti.biz/CentOS/7/x86_64/pam_mysql-0.8.1-0.22.el7.lux.x86_64.rpm
- 准备PAM认证文件
[root@vpnserver ~]# cat <<EOF>/etc/pam.d/openvpn
#crypt=0:明文密码
#crypt=1: 使用crpyt()函数(对应SQL数据里的encrypt(),encrypt()随机产生salt)
#crypt=2: 使用MYSQL中的password()函数加密。
#crypt=3: md5
#根据mysql内创建用户时配合使用 ipad 用户使用password函数加密,这里我使用的 crypt 加密
auth required pam_mysql.so db=openvpn table=t_user user=root passwd=magicdata host=localhost usercolumn=username passwdcolumn=password crypt=1 where=active=1
account required pam_mysql.so db=openvpn table=t_user user=root passwd=magicdata host=localhost usercolumn=username passwdcolumn=password crypt=1 where=active=1
EOF
- 创建数据库、表、添加用户
[root@vpnserver easyrsa3]# mysql -u root -pmagicdata
mysql> CREATE DATABASE openvpn DEFAULT CHARACTER SET utf8;
mysql> CREATE TABLE openvpn.t_user (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
password varchar(255) DEFAULT NULL,
active int(11) DEFAULT 1,
PRIMARY KEY (id),
UNIQUE KEY username (username) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ;
mysql> insert into openvpn.t_user(username,password) values('qiyongxiao',encrypt('123456'));
mysql> exit;
- 测试认证是否通过
[root@vpnserver ~]# systemctl restart saslauthd
[root@vpnserver ~]# testsaslauthd -u qiyongxiao -p 123456 -s openvpn
0: OK "Success."
0: [root@vpnserver ~]# testsaslauthd -u qiqisa -p 123456 -s openvpn
0: OK "Success."
客户端配置
- 生成客户端证书
[root@vpnserver easyrsa3]# ./easyrsa gen-req qiyongxiao #记住这个密码和Common Name 1521Qyx4$:qiyongxiao
[root@vpnserver easyrsa3]# ./easyrsa gen-req qiyongxiao nopass #不填添加证书密码,去掉nopass会添加证书密码
- 用CA证书对客户端证书进行签名,只有签名证书客户端才能使用证书登录 vpn
[root@vpnserver easyrsa3]# ./easyrsa sign client qiyongxiao
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 7300 days:
subject=
commonName = qiyongxiao
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes(输入密码)
Using configuration from /root/easy-rsa-3.0.6/easyrsa3/pki/safessl-easyrsa.cnf
Enter pass phrase for /root/easy-rsa-3.0.6/easyrsa3/pki/private/ca.key: magicdata(输入 ca 证书密码)
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'qiyongxiao'
Certificate is to be certified until Jan 27 04:13:56 2040 GMT (7300 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /root/easy-rsa-3.0.6/easyrsa3/pki/issued/qiyongxiao.crt
- 准备配置文件
[root@vpnserver openvpn_client]# grep -Ev "^$|^#" client.conf
client
dev tun
proto udp
link-mtu 1500
remote 123.123.8.5 11193 #这里使用公网ip+端口号
;remote my-server-2 1194
;remote-random
resolv-retry infinite
nobind
;user nobody
;group nobody
persist-key
persist-tun
auth-user-pass
;auth-nocache
ca ca.crt #服务端 ca
cert qiyongxiao.crt #客户端证书
key qiyongxiao.key #客户端私钥
remote-cert-tls server
tls-auth ta.key 1 #服务器如果启用 ta.key,客户端必须有
cipher AES-256-CBC
verb 3
#所有流量通过openvpn网卡走
#redirect-gateway def1
#部分网段通过openvpn网卡走
route-nopull
route 192.168.4.0 255.255.255.0 vpn_gateway
通过以上的步骤和操作,相信你已经可以使用了。如果还是不行,千万不要放弃,文章中已经把该详细说的关键的全部标注出来了,请认真阅读一下。有任何问题可以进行评论留言。
参考文档: www.dockeryun.cn/linux/2019/… my.oschina.net/u/3021599/b… blog.51cto.com/qiangsh/197…