openvpn

一、OpenVPN

OpenVPN的技术核心是虚拟网卡,它是由一个底层编程技术实现的一个驱动软件,安装之后多出一块网卡。
OpenVPN提供了tun和tap两种工作模式。tap模式是桥接模式,通过软件在系统中模拟一个tap设备,一个二层设备,同时支持链路层协议。 tun模式是路由模式,ip层点对点协议。

1、server端配置文件

  local 10.2.11.237                 #外网口ip地址
  port 1194                         #VPN端口
  proto tcp                         #VPN使用的协议
  dev tun                           #使用的模式
  ca /etc/openvpn/ca.crt
  cert /etc/openvpn/server.crt
  key /etc/openvpn/server.key       # This file should be kept secret
  dh /etc/openvpn/dh.pem            #定义迪菲.赫尔曼 秘钥
  server 172.16.10.0 255.255.255.0  #vpn分配给客户端的网段
  ifconfig-pool-persist ipp.txt     #定义客户端和虚拟IP地址的关系,在openvpn重启时,再次连接的客户端将依然被分配和断开之前的IP地址
  ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 #定义tap桥接模式时,分配给客户端的IP地址段
  push "route 192.168.109.0 255.255.255.0" #推送一个默认路由,使vpn访问内网IP网络通过VPN访问
  keepalive 30 120                  #设定保活参数,每10秒通过ping来确定Client是否存活,当然这个ping的进行是在虚拟通道中而不是在真是外部链路上的,超过120无反馈
  push “redirect-gateway def1 bypass-dhcp”  #可以重定向客户端的网关,进行科学上网时用到
  client-to-client                     # vpn客户端之间可以互相访问
  duplicate-cn                         # 多人使用相同的证书和密钥连接VPN,否则只能一人使用
  tls-auth /etc/openvpn/ta.key 0       # This file is secret
  comp-lzo                          #允许数据压缩
  max-clients 100                   #最大客户端你并发连接数量
  persist-key                       #通过keepalive检测超时后,重新启动VPN,不重新读取keys保留第一次使用的keys
  persist-tun                       #通过keepalive检测超时后,重新启动VPN,一直保持tun或者tap设备是linkupde
  status /var/log/openvpn-status.log  #把openvpn的一些状态信息写到文件中,比如客户端获取的IP地址
  log  /var/log/openvpn.log         #记录日志
  log-append openvpn.log            #记录日志,每次重新启动openvpn后追加原有的log信息
  verb 3                            #设置日志记录冗长级别
  ;mute 20                          #重复日志记录限额

2、client配置文件

  client
  dev tun
  proto tcp
  remote 10.2.11.237 1194           # 此为公网IP,也可以是域名
  ;remote-random                    # 随机选择一个server连接,否则按照顺序从上到下依次连接
  resolv-retry infinite             # 始终重新解析Server的IP地址,保证server IP地址是动态的使用DDNS动态更新DNS后,Client在自动重新连接时重新解析server的IP地址。
  nobind                            #定义本机不绑定任何端口监听incoming数据
  persist-key
  persist-tun
  ca ca.crt
  cert alsvpn.crt                    # 创建的用户证书
  key alsvpn.key                     # 创建的用户秘钥
  remote-cert-tls server
  tls-auth ta.key 1
  comp-lzo
  verb 3

二、OpenVPN认证方式

1、环境前提

在openvpn服务器上配置时间同步

~]# vim /etc/chrony.conf

server time1.aliyun.com iburst

~]# systemctl start chronyd.service

软件安装前提

~]#yum -y install gcc gcc-c++ openssl openssl-devl lzrsz pam-devel cmake

2、编译安装

(1)编译安装lzo 压缩算法

~]# tar xf lzo-2.10.tar.gz

~]# ./configure && make && make install

(2)编译安装openvpn

~]# tar xf openvpn-2.4.6.tar.gz

~]# ./configure --prefix=/usr/local/openvpn

~]# make && make install

~]# mkdir /etc/openvpn/conf.d

~]# vim /etc/profile.d/openvpn.sh

  export PATH=//etc/openvpn/sbin:$PATH

~]# source openvpn.sh

~]# cp sample/sample-config-files/server.conf /etc/openvpn/conf.d/

(3)证书生成

~]# tar xf EasyRSA-unix-v3.0.6.tgz

~]# mv EasyRSA-v3.0.6/ easy-rsa

~]# tree

.
├── easyrsa
├── openssl-easyrsa.cnf
├── vars
├── vars.example
└── x509-types
    ├── ca
    ├── client
    ├── code-signing
    ├── COMMON
    ├── server
    └── serverClient

将不需要的文件删除

~]# cp vars.example vars

~]# vim vars

  set_var EASYRSA_REQ_COUNTRY     "CN"
  set_var EASYRSA_REQ_PROVINCE    "Guangdong"
  set_var EASYRSA_REQ_CITY        "Guangzhou"
  set_var EASYRSA_REQ_ORG         "xingxing"
  set_var EASYRSA_REQ_EMAIL       "473@qq.com"
  set_var EASYRSA_REQ_OU          "Ops"

初始化CA

~]# ./easyrsa init-pki

生成ca证书

~]# ./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:  #输入密码
Re-Enter New CA Key Passphrase:   #再次输入密码
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:ca  输入证书名
Your new CA certificate file for publishing is at:
/etc/openvpn/easy-rsa/pki/ca.crt  #ca证书存放的位置

生成服务端证书

生成证书请求

~]# ./easyrsa gen-req server nopass

对证书进行签证,前一个server指定类型, 后一个为证书名称

~]# ./easyrsa sign-req server server

~]# ./easyrsa gen-dh

~]# openvpn --genkey --secret ta.key

生成客户端证书

~]# mkdir /mnt/easy-rsa

~]# ./easyrsa init-pki

~]# ./easyrsa gen-req client nopass

导入证书文件

~]# ./easyrsa import-req /mnt/easy-rsa/pki/reqs/client.req client

~]# ./easyrsa sign-req client client

方式一:证书认证登录

(1)服务端文件配置

~]# vim server.conf

  port 1194
  proto tcp
  dev tun
  ca ssl/ca.crt
  cert ssl/server.crt
  key ssl/server.key  # This file should be kept secret
  dh ssl/dh.pem
  server 172.16.0.0 255.255.255.0
  ifconfig-pool-persist ipp.txt
  push "route 192.168.0.0 255.255.255.0"
  client-to-client
  duplicate-cn
  keepalive 10 120
  tls-auth ssl/ta.key  # This file is secret
  cipher AES-256-CBC
  comp-lzo
  max-clients 100
  persist-key
  persist-tun
  status openvpn-status.log
  log         openvpn.log
  log-append openvpn.log
  verb 3

(2)客户端文件配置

  client
  dev tun
  proto tcp
  remote 192.168.31.205 1194
  resolv-retry infinite
  nobind
  persist-key
  persist-tun
  <ca>
  -----BEGIN CERTIFICATE-----
  ...
  -----END CERTIFICATE-----
  </ca>
  <cert>
  -----BEGIN CERTIFICATE-----
  ...
  -----END CERTIFICATE-----
  </cert> 
  <key>
  -----BEGIN PRIVATE KEY-----
  ...
  -----END PRIVATE KEY-----
  </key>
  <tls-auth>
  ...
  </tls-auth>
  comp-lzo
  verb 3

(3)修改防火墙规则

~]# iptables -t nat -A POSTROUTING -s 172.18.1.0/24 -o ens37 -j SNAT --to-source 192.168.1.101

此规则的作用是将来自172.18.1.0/24网段的请求伪装成192.168.1.10 通过ens37网卡发出去。
  172.18.1.0/24  是openvpn给客户端分配的IP地址段
  192.168.1.101  是内网通信的网关(简单这么理解)
  ens37 内网网卡

(4)启动服务

~]# openvpn --daemon --config server.conf &

方式二: 密码和证书双重认证

(1)编辑账户认证脚本

~]# vim 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

(2)创建用户名密码文件

~]# vim psw-file

  joah 123456
  test321 123456

(3)在文件末尾追加如下几行

  auth-user-pass-verify /etc/openvpn/conf.d/check.sh via-env
  verify-client-cert
  username-as-common-name
  script-security 3

  说明:
        auth-user-pass-verify /etc/openvpn/conf.d/check.sh via-env #checkpsw.sh脚本文件认证username/password连接客户端
        verify-client-cert  #证书和用户名密码双重认证
        username-as-common-name #使用客户端提供的username作为common name
        script-security 3    保存密码在环境变量中

(4)启动服务

~]# openvpn --daemon --config server.conf &

(5)客户端配置文件

在client.ovpn配置文件追加如下

auth-user-pass   
auth-nocache #可以在短线后防止内存中保存用户名和密码

方式三: MySQL认证

(1)安装pam_mysql

~]# yum install -y mariadb-server mariadb-devel

(2)创建数据库以及表

create databases openvpn default charset utf8;

use openvpn;

  • 创建user表
    #
    CREATE TABLE user (

    username varchar(24) NOT NULL,
    password varchar(128) DEFAULT NULL,
    active int(10) NOT NULL DEFAULT 1,
    creation timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    expired_time timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
    name varchar(24) DEFAULT NULL,
    email char(128) DEFAULT NULL,
    note text,
    quota_cycle int(10) NOT NULL DEFAULT 30,
    quota_bytes bigint(20) NOT NULL DEFAULT '10737418240',
    enabled int(10) NOT NULL DEFAULT 1,
    PRIMARY KEY (username),
    index idx_active (active),
    index idx_enabled (enabled)
    

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  • 创建log表
    #
    CREATE TABLE log (

    username varchar(24) NOT NULL,
    start_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    end_time timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
    trusted_ip varchar(64) DEFAULT NULL,
    trusted_port int(10) DEFAULT NULL,
    protocol varchar(16) DEFAULT NULL,
    remote_ip varchar(64) DEFAULT NULL,
    remote_netmask varchar(64) DEFAULT NULL,
    bytes_received bigint(20) DEFAULT 0,
    bytes_sent bigint(20) DEFAULT 0,
    status int(10) NOT NULL DEFAULT 1,
    index idx_username (username),
    index idx_start_time (start_time),
    index idx_end_time (end_time)
    

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  • 授权

grant all privileges on openvpn.* to 'openvpn'@'%' identified by '123456';

(3)安装pam_mysql

~]# yum install -y mariadb-devel pam-devel

~]# tar xf pam_mysql-0.7RC1.tar.gz

~]# ./configure --with-mysql=/usr --with-openssl=/usr --with-pam=/usr --with-pam-mods-dir=/lib64/security

~]# make && make install

(4)创建openvpn文件

~]# vim /etc/pam.d/openvpn

auth required /lib64/security/pam_mysql.so user=openvpn passwd=123456 host=localhost db=openvpn table=user usercolumn=username passwdcolumn=password where=active=1 sqllog=0 crypt=2
account required /lib64/security/pam_mysql.so user=openvpn passwd=123456 host=localhost db=openvpn table=user usercolumn=username passwdcolumn=password where=active=1 sqllog=0 crypt=2

注意:

  crypt=0 明文加密
  crypt=1 使用crypt()加密
  crypt=2 使用mysql中password()加密
  crypt=3 使用md5加密

(5)修改openvpn服务端配置文件

  proto tcp
  dev tun
  port 1194
  ca ssl/ca.crt
  cert ssl/server.crt
  key ssl/server.key
  dh ssl/dh.pem
  tls-auth ssl/ta.key 0
  server 192.168.6.0 255.255.255.0
  keepalive 20 120
  persist-key
  persist-tun
  comp-lzo
  push "route 192.168.5.0 255.255.255.0"
  status /etc/openvpn/openvpn-status.log
  max-clients 1000

  verify-client-cert
  username-as-common-name
  script-security 3 
  plugin /etc/openvpn/conf.d/openvpn-auth-pam.so openvpn

**注意:使用高版本的认证不成功的,不知道原因,需要下载低版本的进行编译即可**

  ;如果需要设置设置连接和断开脚本,以便统计流量信息
  ;client-connect /etc/openvpn/connect.sh
  ;client-disconnect /etc/openvpn/disconnect.sh

(6)connect.sh脚本

  #!/bin/bash
  #
  DB='openvpn'
  LOGIN='openvpn'
  DBPASSWD='123456'

  mysql -u${LOGIN} -p${DBPASSWD} -h${HOST} -e "INSERT INTO log(username,start_time,trusted_port,protocol,remote_ip,remote_netmask,status,trusted_ip) VALUES('$common_name',now(),$trusted_port,'$proto_1','$ifconfig_pool_remote_ip','$route_netmask_1',1,'${trusted_ip}')" ${DATABASE}

~]# chmod +x connect.sh

(7)disconnect.sh脚本

#!/bin/bash
#
DATABASE='openvpn'
LOGIN='openvpn'
DBPASSWD='123456'
HOST='localhost'

#断开连接时,更新日志
mysql -u${LOGIN} -h${HOST} -p${DBPASSWD} -e "update log set end_time=now(),bytes_received='${bytes_received}',bytes_sent='${bytes_sent}',status=0 where trusted_ip='${trusted_ip}' and trusted_port='${trusted_port}' and remote_ip='${ifconfig_pool_remote_ip}' and username='${common_name}' and status=1" ${DATABASE}

#如果流量超出,则锁定用户
mysql -u$DBADMIN -p$DBPASSWD -e "UPDATE user SET active=0 WHERE user.username IN (SELECT username FROM (SELECT log.username AS username, quota_bytes FROM user, log WHERE log.username=user.username AND log.status=0 AND TO_DAYS(NOW())-TO_DAYS(start_time)< =quota_cycle GROUP BY log.username HAVING SUM(bytes_received)+SUM(bytes_sent)>=quota_bytes) AS u);" $DB

#如果过期时间超出,则锁定用户
mysql -u${LOGIN} -h${HOST} -p${DBPASSWD} -e "update user set active=0 where username='${common_name}' and UNIX_TIMESTAMP(now()) > UNIX_TIMESTAMP(expired_time)" ${DATABASE}

~]# chmod +x disconnect.sh

四、windows客户端配置

  • 1)安装客户端软件省略(默认安装在C:\Program Files\OpenVPN)

  • 2)配置客户端软件

    拷贝vpn服务器上/mnt/clinet/alsvpn目录下的ca.crt alsvpn.crt alsvpn.key ta.key client.opvn到C:\Program Files\OpenVPN\config中

  • 3)以管理员运行

  • 4)右击电脑右下角的图标,点击connect

    输入当时配置客户端证书,填写的密码,此处为clientopenvpn

  • 5)拨号成功后,客户端会获取到ip地址

  • 6)查看客户端是否获取到内网网段的路由

  • 7)测试是否可以ping通内网


  转载请注明: Joah openvpn

 上一篇
rsyslog rsyslog
在日常生活中如果您是一个生活有条理的人,一定会记录一下每天发生的事情,方便自己回看。CentOS系统中也是这样工作的,当我们在某时发生了错误时,这时日志就给我们起到了举足轻重的作用;我们可以查看日志并分析错误产生的原因等等。 一、rsysl
2019-03-11
下一篇 
Glances Glances
一、GlancesGlances是一个由Python编写,使用psutil库来从系统抓取信息的基于curses开发的跨平台命令行监视工具。 1、Glances功能 CPU信息 总内存信息,包括了物理内存,交换空间和空闲内存等 网络链接的上下
2017-12-20