> Linux服务器 > VPN >

CentOS 7下面OpenVPN和OpenSSL的问题总结

今天遇到个实际的需求,最后决定把某个远程内网的虚拟机上的测试服务器给映射到公网上来,想到多年前就用过OpenVPN来做这个事情,所以翻看了一下http://flashing.iteye.com/blog/575402 以前的文章,按说照做即可,结果很悲桑的发现...things changed~

其实主要原因是Centos 7移除了Openssl的MD5支持(听了一年关于centos7的各种吐槽,但是自己没实际用,这马上就掉到坑里了),但是windows/ubuntu(使用14.04LTS测试),openssl仍然默认以md5作为散列算法并且可以正确识别md5散列算法,所以就悲剧了,只有cenots7不好用。关键是这个错误是大错误被小错误还掩盖了一下,所以很难被发现。

错误关键词:

A: VERIFY ERROR: depth=1, error=certificate is not yet valid

or error 9 at 1 depth lookup:certificate is not yet valid

B: VERIFY ERROR: depth=0, error=certificate signature failure
C: error 7 at 0 depth lookup:certificate signature failure

 

先把这些给装上:

sudo yum update
sudo yum install -y wget ntp ntpdate openvpn easy-rsa bridge-utils


解决A:

首先错误A是因为centos7默认安装(没有桌面)的情况下timezone没设置对并且时间没有校对,导致服务器时间还没到证书的签名时间,所以需要从新设置一下timezone并校对时间:

sudo timedatectl set-timezone Asia/Shanghai

sudo ntpdate time.windows.com&

sudo systemctl enable ntpd

sudo systemctl start ntpd
sudo timedatectl set-ntp true
然后执行date命令看看时间是否正确,执行timedatectl看看设置的时区等信息是否正确,ntp是否开启。

 

Html代码  收藏代码
  1.       Local time: Thu 2015-10-15 12:37:25 CST  
  2.   Universal time: Thu 2015-10-15 04:37:25 UTC  
  3.         Timezone: Asia/Shanghai (CST, +0800)  
  4.      NTP enabled: yes  
  5. NTP synchronized: no  
  6.  RTC in local TZ: no  
  7.       DST active: n/a  

 

对于B和C,有两个问题需要解决。

第一是生成证书时候的Common Name其实是不能重复的,ca的,server的以及每个client的common都必须是唯一的,虽然校验与否是openssl的事情,大多数情况可能重复了也没问题,但是仍然建议不要重复。

from: http://stackoverflow.com/questions/19726138/openssl-error-18-at-0-depth-lookupself-signed-certificate

Java代码  
  1. Whatever method you use to generate the certificate and key files, the Common Name value used for the server and client certificates/keys must each differ from the Common Name value used for the CA certificate. Otherwise, the certificate and key files will not work for servers compiled using OpenSSL.  

 第二是最终问题,也就是centos7下面的openssl不支持md5,校验可以通过下面的命令:

openssl verify -CAfile ca.crt -purpose sslclient weblogic.crt

或者直接
openssl verify -CAfile ca.crt weblogic.crt

 服务器当然就是

openssl verify -CAfile ca.crt -purpose sslserver server.crt
可以看到windows/ubuntu下都可以成功显示OK,centos 7则报告错误,这是openvpn报告:

error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm:a_verify.c:179: 错误的根源。

 

仍然有两种方法来解决,第一是通过环境变量打开centos7下的openssl对md5的支持:

from http://software-engineer.gatsbylee.com/centos7openvpn-verify-error-depth0-errorcertificate-signature-failure/

然而我这么做并未成功,主要是如果是在shell里面,su添加环境变量之后,

sudo openvpn --config /etc/openvpn/client.ovpn

是可以成功的,原因是这都是root的变量,但是centos7(7.1)的服务模式,按照原文添加在NetworkManager里面,并未生效,原因未知。

考虑到这种情况主要是之前已经有了多个证书的情况才需要仔细考虑兼容,我的情况是从新发布证书,所以果断放弃研究这个分支,不再使用md5,改用其他散列算法从新生成证书。

因为我对openssl不熟悉,也不知道在哪里设置md算法easy-rsa才可以识别,碰巧搜到github的一个patch的diff,才明白原来是在openssl.cnf里面设置。

cenots在/usr/share/easy-rsa/2.0/下面,windows就在openvpn目录里面,把windows里面openssl-1.0.0.cnf内容当中的

default_md    = md5            # use public key default MD

改为

default_md    = sha256            # use public key default MD

看了一下centos的easy-rsa默认设置,也是sha256,这把放心了。

然后从新生成了所有的证书,放入centos下面经过测试之后好用了。成功拨号之后ifconfig可以看到有tap0设备。

 

附1:几个安装的参考网址,有的有用有的没用(其实按照easy-rsa下面的readme.txt操作即可并不麻烦,当然需要改一下vars的变量设置):

http://flashing.iteye.com/blog/575402

http://www.cnblogs.com/szzchristy/p/3491757.html

https://www.digitalocean.com/community/tutorials/how-to-setup-and-configure-an-openvpn-server-on-centos-7

http://www.server-world.info/en/note?os=CentOS_6&p=openvpn

 

附2:centos 7 linux下面启动openvpn

拷贝client.ovpn(或者server.opvn,我这里是linux做客户端,所以是起名client.ovpn),ca.crt, 客户端证书crt文件和key文件到/etc/openvpn

sudo openvpn --config /etc/openvpn/client.ovpn

可以直接连接用作测试,如果成功,可以安装为服务

先把/etc/openvpn/client.ovpn复制为/etc/openvpn/client.conf

sudo systemctl enable openvpn@client.service
sudo systemctl start openvpn@client.service

这里@是指/etc/openvpn下面对应的conf文件名

当然停止和注销服务就是

sudo systemctl stop openvpn@client.service

sudo systemctl disable openvpn@client.service
查看服务状态是

sudo systemctl status openvpn@client.service

 

 

 




(责任编辑:IT)