linux 搭建 OPEN VPN

发布于 2018-02-01  398 次阅读


1.安装前准备

# 关闭 selinux

setenforce 0

sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config
# 安装 openssl 和 lzo,lzo 用于压缩通讯数据加快传输速度

yum -y install openssl openssl-devel

yum -y install lzo
# 安装 epel 源

rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm

sed -i 's/^mirrorlist=https/mirrorlist=http/' /etc/yum.repos.d/epel.repo

2.安装及配置 OpenVPN 和 easy-rsa

# 安装 openvpn 和 easy-rsa

yum -y install openvpn easy-rsa
# 修改 vars 文件

cd /usr/share/easy-rsa/2.0/

vim vars

# 修改注册信息,比如公司地址、公司名称、部门名称等。

export KEY_COUNTRY="CN" # 国家

export KEY_PROVINCE="GD" # 地区

export KEY_CITY="SZ" # 城市

export KEY_ORG="Funs" # 公司名

export KEY_EMAIL=XXX@funs.com # Email

export KEY_OU="IT" # 部门
# 初始化环境变量

source vars

# 清除 keys 目录下所有与证书相关的文件

# 下面步骤生成的证书和密钥都在/usr/share/easy-rsa/2.0/keys 目录里

./clean-all

# 生成根证书 ca.crt 和根密钥 ca.key(一路按回车即可)

./build-ca

# 为服务端生成证书和密钥(一路按回车,直到提示需要输入 y/n 时,输入 y 再按回车,一共两次)

./build-key-server server

# 每一个登陆的 VPN 客户端需要有一个证书,每个证书在同一时刻只能供一个客户端连接。

# 为客户端生成证书和密钥(一路按回车,直到提示需要输入 y/n 时,输入 y 再按回车)

./build-key client1

# 创建迪菲·赫尔曼密钥,会生成 dh2048.pem 文件(生成过程比较慢,在此期间不要去中断它)

./build-dh

# 生成 ta.key 文件(防 DDos 攻击、UDP 淹没等恶意攻击)

openvpn --genkey --secret keys/ta.key

3.创建服务器端配置文件

# 在 openvpn 的配置目录下新建一个 keys 目录

mkdir /etc/openvpn/keys

# 将需要用到的 openvpn 证书和密钥复制一份到刚创建好的 keys 目录中

cp /usr/share/easy-rsa/2.0/keys/{ca.crt,server.{crt,key},dh2048.pem,ta.key} /etc/openvpn/keys/

# 复制一份服务器端配置文件模板 server.conf 到/etc/openvpn/

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

# 查看 server.conf 里的配置参数

grep '^[^#;]' /etc/openvpn/server.conf
# 编辑 server.conf

vim /etc/openvpn/server.conf

port 1194

# 改成 tcp,默认使用 udp,如果使用 HTTP Proxy,必须使用 tcp 协议

proto tcp

dev tun

# 路径前面加 keys,全路径为/etc/openvpn/keys/ca.crt

ca keys/ca.crt

cert keys/server.crt

key keys/server.key

dh keys/dh2048.pem

# 默认虚拟局域网网段,不要和实际的局域网冲突即可

server 10.8.0.0 255.255.255.0

ifconfig-pool-persist ipp.txt

# 10.0.0.0/8 是我这台 VPN 服务器所在的内网的网段,读者应该根据自身实际情况进行修改

push "route 10.0.0.0 255.0.0.0"

# 可以让客户端之间相互访问直接通过 openvpn 程序转发,根据需要设置

push "route 172.18.0.0 255.255.0.0"

# 可以让客户端能访问服务端 172.18.0.0 子网的机器

client-to-client

# 如果客户端都使用相同的证书和密钥连接 VPN,一定要打开这个选项,否则每个证书只允许一个人连接 VPN

duplicate-cn

keepalive 10 120

tls-auth keys/ta.key 0

comp-lzo

persist-key

persist-tun

# OpenVPN 的状态日志,默认为/etc/openvpn/openvpn-status.log

status openvpn-status.log

# OpenVPN 的运行日志,默认为/etc/openvpn/openvpn.log

log-append openvpn.log

# 改成 verb 5 可以多查看一些调试信息

verb 5

push "redirect-gateway def1"

push "dhcp-option DNS 10.8.0.1"

push "dhcp-option DNS 8.8.8.8"

#上面三句为了让客户端连接 VPN 后,所有数据都走 VPN(可选)

4.配置内核和防火墙,启动服务

# 开启路由转发功能

sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf

sysctl -p

在这里要注意一点,执行上面命令,可能会出错。具体的解决方案如下:

问题症状

修改 linux 内核文件

#vi /etc/sysctl.conf 后执行 sysctl -p 报错

error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key

error: "net.bridge.bridge-nf-call-iptables" is an unknown key

error: "net.bridge.bridge-nf-call-arptables" is an unknown key

解决方法如下:

modprobe bridge

lsmod|grep bridge
# 配置防火墙,别忘记保存

iptables -F

iptables -X

iptables -Z

iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A INPUT -p TCP --dport 1194 -j ACCEPT

iptables -t nat -A POSTROUTING -s 10.8.0.0/24  -j MASQUERADE

service iptables save
# 启动 openvpn 并设置为开机启动

service openvpn start

chkconfig openvpn on

5.创建客户端配置文件

# 复制一份 client.conf 模板命名为 client.ovpn

cp /usr/share/doc/openvpn-2.3.2/sample/sample-config-files/client.conf client.ovpn

# 编辑 client.ovpn

vim client.ovpn

client

dev tun

# 改为 tcp

proto tcp

# OpenVPN 服务器的外网 IP 和端口

remote xxx.xxx.xxx.xxx 1194

resolv-retry infinite

nobind

persist-key

persist-tun

ca ca.crt

# client1 的证书

cert client1.crt

# client1 的密钥

key client1.key

ns-cert-type server

# 去掉前面的注释

tls-auth ta.key 1

comp-lzo

verb 3

将 OpenVPN 服务器上的 client.ovpn、ca.crt、client1.crt、client1.key、ta.key 上传到 Windows 客户端安装目录下的 config 文件夹(C:\Program Files\OpenVPN\config)

启动 openvpn,选择“Connect”。

若有必要,路由器需做端口映射

切记,服务器时间需做好网络同步,即服务端时间和客户端时间不能相差太大

用 ntpdate 从时间服务器更新时间

如果你的 linux 系统根本没有 ntpdate 这个命令

yum install ntp

安装完了之后,你不要做什么配置,也不需要,直接测试一下

#ntpdate time.nist.gov

22 Oct 21:11:43 ntpdate[5014]: adjust time server 207.200.81.113 offset -0.018788 sec

如果出去上面的内容说明,同步成功了。

然后在/etc/crontab 里面加上以下内容,使时间同步每隔十分钟同步一次。

*/10 * * * * ntpdate time.pool.aliyun.com

推荐几个时间服务器。

time.nist.gov

time.nuri.net

0.asia.pool.ntp.org

1.asia.pool.ntp.org

2.asia.pool.ntp.org

3.asia.pool.ntp.org

扩展

设置要求输入密码连接 VPN

修改 server.conf:

tls-auth ta.key 0 # This file is secret

auth-user-pass-verify /usr/local/openvpn/config/checkpsw.sh via-env

client-cert-not-required

username-as-common-name

script-security 3

注:如果加上 client-cert-not-required 则代表只使用用户名密码方式验证登录,如果不加,则代表需要证书和用户名密码双重验证登录!

在 cofnig 目录中创建脚本

vi checkpsw.sh

#!/bin/sh

###########################################################

# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>

#

# This script will authenticate OpenVPN users against

# a plain text file. The passfile should simply contain

# one row per user with the username first followed by

# one or more space(s) or tab(s) and then the password.

PASSFILE="/etc/openvpn/psw-file"

LOG_FILE="/var/log/openvpn-password.log"

TIME_STAMP=`date "+%Y-%m-%d %T"`



###########################################################



if [ ! -r "${PASSFILE}" ]; then

echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}

exit 1

fi



CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`



if [ "${CORRECT_PASSWORD}" = "" ]; then

echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}

exit 1

fi



if [ "${password}" = "${CORRECT_PASSWORD}" ]; then

echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}

exit 0

fi



echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}

exit 1
给予权限:chmod +x  checkpsw.sh

编写密码文件:

vi psw-file

client sz1card1

chmod 777 psw-file

chown nobody.nobody psw-file
修改客户端配置文件:client.conf(或者 client.ovpn)

注销掉这两行

#cert client1.crt

#key client1.key

再添加这一行,添加这行,就会提示输入用户名和密码

auth-user-pass

tls-auth ta.key 1