所需软件:lzo-2.10.tar.gzopenvpn-2.4.3.tar.gz
其他版本下载地址:
http://www.oberhumer.com/opensource/lzo/download/
http://build.openvpn.net/downloads/releases/
安装软件:yum install -y gcc gcc-c++ openssl-devel pam-devel
安装lzo:
tarxflzo-2.10.tar.gz cdlzo-2.10 ./configure--prefix=/usr/local make&&makeinstall
安装路径使用/usr/local而不是/usr/local/lzo是为了解决安装openvpn时候找不到 lzo_lib 的问题。
tarxfopenvpn-2.4.3.tar.gz cdopenvpn-2.4.3 ./configure--prefix=/usr/local/openvpn make&&makeinstall
编译访问控制模块:
在当前安装目录中新建文件 minimal_pf.c
/*minimal_pf.c *ultra-minimalOpenVPNplugintoenableinternalpacketfilter*/ #include<stdio.h> #include<stdlib.h> #include"include/openvpn-plugin.h" /*dummycontext,asweneednostate*/ structplugin_context{ intdummy; }; /*Initializationfunction*/ OPENVPN_EXPORTopenvpn_plugin_handle_topenvpn_plugin_open_v1(unsignedint*type_mask,constchar*argv[],constchar*envp[]){ structplugin_context*context; /*Allocateourcontext*/ context=(structplugin_context*)calloc(1,sizeof(structplugin_context)); /*Whichcallbackstointercept.*/ *type_mask=OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_ENABLE_PF); return(openvpn_plugin_handle_t)context; } /*Workerfunction*/ OPENVPN_EXPORTintopenvpn_plugin_func_v2(openvpn_plugin_handle_thandle,constinttype,constchar*envp[],void*per_client_context,structopenvpn_plugin_string_list**return_list){ if(type==OPENVPN_PLUGIN_ENABLE_PF){ returnOPENVPN_PLUGIN_FUNC_SUCCESS; }else{ /*shouldnothappen!*/ returnOPENVPN_PLUGIN_FUNC_ERROR; } } /*Cleanupfunction*/ OPENVPN_EXPORTvoidopenvpn_plugin_close_v1(openvpn_plugin_handle_thandle){ structplugin_context*context=(structplugin_context*)handle; free(context); }
其他版本的openvpn可能需要修改包含头文件(#include "include/openvpn-plugin.h"),2.1.4版本的openvpn-plugin.h是在根目录
编译:
CC_FLAGS="-O2-Wall-g" NAME=minimal_pf gcc$CC_FLAGS-fPIC-c$NAME.c&&gcc$CC_FLAGS-fPIC-shared-Wl,-soname,$NAME.so-o$NAME.so$NAME.o-lc
cp-aminimal_pf.so/usr/local/openvpn/lib/openvpn/plugins/
新版本openvpn好像没有证书管理工具,可以从旧版本中复制过来,只是为了生成一套根证书而已,直接从其他服务器复制几个证书文件过来也可以用。
从旧版本openvpn-2.1.4.tar.gz中复制easy-rsa目录,使用2.0版本工具,修改vars文件中的变量(非必须),加载到当前Shell。
cp-aopenvpn-2.4.3/easy-rsa/usr/local/openvpn/ cd/usr/local/openvpn/easy-rsa/2.0/ sourcevars
清理证书目录
./clean-all
生成CA证书,输入部分可以直接回车,[y/n]部分填y
./build-ca
生成服务器证书,server为任意名字,输入部分可以直接回车,[y/n]部分填y
./build-key-serverserver
./build-dh
建立其他目录
cd/usr/local/openvpn/ mkdirccdconflogspf
openvpn服务器配置:conf/server.conf
port1194 protoudp devtun ca/usr/local/openvpn/easy-rsa/2.0/keys/ca.crt cert/usr/local/openvpn/easy-rsa/2.0/keys/server.crt key/usr/local/openvpn/easy-rsa/2.0/keys/server.key dh/usr/local/openvpn/easy-rsa/2.0/keys/dh1024.pem server10.8.0.0255.255.255.0 ifconfig-pool-persist/usr/local/openvpn/conf/ipp.txt push"route192.168.100.0255.255.255.0" keepalive10120 comp-lzo persist-key persist-tun status/usr/local/openvpn/logs/openvpn-status.log log/usr/local/openvpn/logs/openvpn.log verb3 auth-user-pass-verify/usr/local/openvpn/sbin/checkpsw.shvia-env plugin/usr/local/openvpn/lib/openvpn/plugins/minimal_pf.so client-connect/usr/local/openvpn/sbin/client-connect.sh client-config-dir/usr/local/openvpn/ccd client-to-client client-cert-not-required username-as-common-name script-security3
密码认证脚本/usr/local/openvpn/sbin/checkpsw.sh:
#!/bin/bash PASSFILE="/usr/local/openvpn/conf/psw-file" LOG_FILE="/usr/local/openvpn/logs/openvpn-password.log" TIME_STAMP=`date"+%Y-%m-%d%T"` if[!-r"${PASSFILE}"];then echo"${TIME_STAMP}:Couldnotopenpasswordfile\"${PASSFILE}\"forreading.">>${LOG_FILE} exit1 fi CORRECT_PASSWORD=`awk'!/^;/&&!/^#/&&$1=="'${username}'"{print$2;exit}'${PASSFILE}` if["${CORRECT_PASSWORD}"=""];then echo"${TIME_STAMP}:Userdoesnotexist:username=\"${username}\",password=\"${password}\".">>${LOG_FILE} exit1 fi if["${password}"="${CORRECT_PASSWORD}"];then echo"${TIME_STAMP}:Successfulauthentication:username=\"${username}\".">>${LOG_FILE} exit0 fi echo"${TIME_STAMP}:Incorrectpassword:username=\"${username}\",password=\"${password}\".">>${LOG_FILE} exit1
访问控制脚本 /usr/local/openvpn/sbin/client-connect.sh:
#!/bin/bash template="/usr/local/openvpn/pf/${common_name}.pf" if[-f"$template"]&&[!-z"$pf_file"];then cp--"$template""$pf_file" else exit1 fi
加可执行权限:
chmod+xsbin/checkpsw.shsbin/client-connect.sh
cat/usr/local/openvpn/conf/psw-file user1passd1 user2passd2
cat/usr/local/openvpn/ccd/user1 push"route192.168.101.0255.255.255.0"
增加访问控制文件(必须),缺少访问控制文件则登录失败,防止权限出错:
cat/usr/local/openvpn/pf/user1 [CLIENTSACCEPT] [SUBNETSACCEPT] +192.168.100.0/28 -0.0.0.0/0 [END]
以上配置文件,+是允许,-是拒绝,ACCEPT也可以改为DROP,CLIENTS部分填写用户名,具体用法有待探讨。
开启IP转发和NAT,端口eth0和网段10.8.0.0/24根据实际配置调整:
echo"net.ipv4.ip_forward=1">>/etc/sysctl.conf sysctp-p iptables-tnat-APOSTROUTING-oeth0-s10.8.0.0/24-jMASQUERADE /etc/init.d/iptablessave chkconfigiptableson
启动openvpn服务:
/usr/local/openvpn/sbin/openvpn--config/usr/local/openvpn/conf/server.conf--daemon
查看日志,出现 Initialization Sequence Completed 则启动成功:
tailflogs/openvpn.log ThuSep2814:06:302017MULTI:multi_initcalled,r=256v=256 ThuSep2814:06:302017IFCONFIGPOOL:base=10.8.0.4size=62,ipv6=0 ThuSep2814:06:302017ifconfig_pool_read(),in='ouzy,10.8.0.4',TODO:IPv6 ThuSep2814:06:302017succeeded->ifconfig_pool_set() ThuSep2814:06:302017ifconfig_pool_read(),in='gcc,10.8.0.8',TODO:IPv6 ThuSep2814:06:302017succeeded->ifconfig_pool_set() ThuSep2814:06:302017IFCONFIGPOOLLIST ThuSep2814:06:302017ouzy,10.8.0.4 ThuSep2814:06:302017gcc,10.8.0.8 ThuSep2814:06:302017InitializationSequenceCompleted
Windows客户端从openvpn.net下载安装openvpn-install-*.exe
下载页面:https://openvpn.net/index.php/open-source/downloads.html
把服务器的CA证书 /usr/local/openvpn/easy-rsa/2.0/keys/ca.crt 下载并复制到客户端的openvpn安装目录config下,再在config目录新建一个配置文件client.ovpn ,名字随意,后缀名要一致,把配置文件的x.x.x.x换成openvpn服务器IP:
setenvCLIENT_CERT0 client devtun protoudp remotex.x.x.x1194 resolv-retryinfinite nobind persist-key persist-tun auth-user-pass ns-cert-typeserver comp-lzo verb3 auth-nocache reneg-sec0 caca.crt
打开客户端连接,输入用户名密码即可。