openvpn客户端在和服务端建立连接时,一般建立ssl通信,流量都需要经过加密。正常建立ssl连接的时候,流程是很复杂的,需要握手信息,需要验证证书,需要协商和交换对称加密密钥。这个对称加密密钥是用来做什么的呢?其实ssl在建立连接前期的协商步骤中使用非对称加密算法(一般为RSA算法),是为了交换某些生成后续对称加密密钥所必须的信息,避免在网络中明文传输对称加密的密钥。一旦协商完成,对称密钥也就交换完成,后续的通信,都是使用对称加密来通信。为什么不能全程都使用非对称加密来加解密数据?因为非对称加密的效率比较低,所以在对称加密密钥协商完成后,后续通信都用这个对称加密密钥进行对称加密。这里说的比较笼统,感兴趣的可以自行去谷歌ssl连接建立的过程。
oponvpn支持配置静态密钥,也就是说不用协商密钥,默认通信的双方都知道是用哪个对称加密密钥来加解密。这在某些场景下还是很有用的,每种技术都有它特定的应用场景。当然,用静态密钥本身安全性就不高,一旦别人拿到这个静态密钥,那整个通信过程就相当于明文通信了。正是因为不安全,所以openvpn官方强烈不推荐使用,可能在某些新版本中都禁用了这个功能。使用静态密钥还有一个局限性,就是只能有一个服务端,一个客户端,不能多个客户端端同时连接openvpn服务器。
openvpn使用静态密钥也有一个优点,就是配置会特别简单,不需要ca证书,服务端客户端证书,私钥这些,只需要一个对称加密密钥。
静态密钥生成
在linux下,使用openvpn的命令生成静态密钥:
openvpn –genkey –secret static.key
生成的static.key,服务端和客户端共用
服务端配置(centos)
如果还不懂openvpn怎么搭建的,可以参考我前面的文章:openvpn组网技术原理及配置过程(centos服务器/安卓客户端/linux客户端)-CSDN博客
服务端配置文件server.conf如下:
################################################
# Sample OpenVPN 2.0 config file for #
# multi-client server. #
# #
# This file is for the server side #
# of a many-clients <-> one-server #
# OpenVPN configuration. #
# #
# OpenVPN also supports #
# single-machine <-> single-machine #
# configurations (See the Examples page #
# on the web site for more info). #
# #
# This config should work on Windows #
# or Linux/BSD systems. Remember on #
# Windows to quote pathnames and use #
# double backslashes, e.g.: #
# "C:\\Program Files\\OpenVPN\\config\\foo.key" #
# #
# Comments are preceded with '#' or ';' #
#################################################
dev tun
port 7379
proto udp
# 此处不能配置server的子网范围,只能用ifconfig配置两个ip,一个是服务端ip,一个是客户端ip
#server 10.9.0.0 255.255.255.0
ifconfig 10.9.0.1 10.9.0.2
# 配置静态密钥
secret static.key
#ifconfig-pool-persist ipp.txt
#The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun
# 将客户端的所有流量都重定向到服务端
push "redirect-gateway def1 bypass-dhcp"
# 向客户端推送DNS地址,也可以是用其他可用的DNS,可以取服务端本机的DNS地址
push "dhcp-option DNS 100.100.2.136"
push "dhcp-option DNS 100.100.2.138"
# 这个是保活的检测间隔
keepalive 10 120
# 加密算法,服务端和客户端要一致
cipher AES-256-CBC
#compress lz4-v2
#push "compress lz4-v2"
# 设置压缩
comp-lzo
# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
#
# You can uncomment this out on
# non-Windows systems.
# openvpn运行的用户和用户组
user root
group root
#comp-lzo
#log-append openvpn-static.log
# 日志保存
log openvpn.log
# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
# 日志等级
verb 3
客户端配置(centos)
可以先使用linux的openvpn客户端尝试连接,方便解决问题,linux客户端配置如下,静态密钥我们也用内联的方式:
##############################################
# Sample client-side OpenVPN 2.0 config file #
# for connecting to multi-client server. #
# #
# This configuration can be used by multiple #
# clients, however each client should have #
# its own cert and key files. #
# #
# On Windows, you might want to rename this #
# file so it has a .ovpn extension #
##############################################
# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
;client
# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
# 此处跟服务端一致
;dev tap
dev tun
# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel
# if you have more than one. On XP SP2,
# you may need to disable the firewall
# for the TAP adapter.
;dev-node MyTap
# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
;proto tcp
# 此处跟服务端一致
proto udp
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
# 这里填服务端的ip端口
remote 1.1.1.1 7379
#remote my-server-2 1194
这里要跟服务端的配置一致
ifconfig 10.9.0.2 10.9.0.1
# Choose a random host from the remote
# list for load-balancing. Otherwise
# try hosts in the order specified.
;remote-random
# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
# 使用默认配置
resolv-retry infinite
# Most clients don't need to bind to
# a specific local port number.
# 使用默认配置,随机分配端口
nobind
# Downgrade privileges after initialization (non-Windows only)
;user nobody
;group nobody
# Try to preserve some state across restarts.
# 尝试在重新启动时保留一些状态
persist-key
persist-tun
# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here. See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]
# Wireless networks often produce a lot
# of duplicate packets. Set this flag
# to silence duplicate packet warnings.
;mute-replay-warnings
# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
#ca ca.crt
#cert client.crt
#key client.key
# Verify server certificate by checking that the
# certicate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
#
# To use this feature, you will need to generate
# your server certificates with the keyUsage set to
# digitalSignature, keyEncipherment
# and the extendedKeyUsage to
# serverAuth
# EasyRSA can do this for you.
#remote-cert-tls server
# If a tls-auth key is used on the server
# then every client must also have the key.
#tls-auth ta.key 1
# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
# Note that v2.4 client/server will automatically
# negotiate AES-256-GCM in TLS mode.
# See also the ncp-cipher option in the manpage
# 这里是加密算法,跟服务端一致
cipher AES-256-CBC
# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
#comp-lzo
# Set log file verbosity.
verb 3
# Silence repeating messages
;mute 20
# 服务端已经配置,这里不需要重新配置
#redirect-gateway autolocal
# 允许压缩
comp-lzo
# 这里我是想在客户端连接好服务器端后就更改本地的DNS,但是发现没成功,还是需要手动编辑/etc/resolv.conf文件进行修改
dhcp-option DNS 100.100.2.136
dhcp-option DNS 100.100.2.138
#下面是静态密钥的内容
<secret>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END OpenVPN Static key V1-----
</secret>
如果连接上后DNS解析不正常,可以手动修改DNS,直接编辑/etc/resolv.com,比如将DNS修改为8.8.8.8
安卓客户端配置
由于openvpn官方不推荐使用静态密钥,似乎已经弃用了这个功能,用OpenVPN Connect导入只有静态密钥的配置文件,连接的时候会直接报错要求导入ca证书。找了一阵没办法解决,于是尝试用OpenVPN For Android这个客户端,连接的时候也报错,提示静态密钥强烈不建议使用,但是提示了一下可以使用--allow-deprecated-insecure-static-crypto来强行使用静态密钥。后来发现这个应该是在使用命令行的时候传入的参数,安卓客户端启动哪有命令行?尝试直接在自定义选项中加“--allow-deprecated-insecure-static-crypto”,会报识别不了该配置。参考了一下其他配置,这个配置在配置文件应该直接使用字符串"allow-deprecated-insecure-static-crypto yes",果然能通过了。后面又根据报错日志新增了两个自定义配置,才成功建立连接。
完整的配置过程如下:
0、先决条件:安装OpenVPN For Android,版本0.7.51,或者以上。我尝试使用0.7.39版本,发现会报错无法识别allow-deprecated-insecure-static-crypto选项,因此应该是高版本才支持这个选项
1、将上面centos客户端的配置的配置复制一份,然后在后面添加这三条配置
allow-compression yes
allow-deprecated-insecure-static-crypto yes
cipher AES-256-CBC
2、然后将上一步修改好的配置文件发送到安卓手机,导入这个配置,然后执行连接
或者你先导入centos客户端配置导入OpenVPN For Android,然后再在这个配置的基础上添加那三条自定义选项,也是可以的。自定义选项配置是点击PROFILES右边的编辑按钮,然后ADVANCED下面的Custom Options
如果显示已经连接成功,但是还是无法访问到外网或者无法访问到openvpn服务端主机,你需要检查一下PROFLE的ROUTING下的Use default Route选项是否勾选,如果没有勾选要勾选上才可以,可能有的系统导入配置文件后,默认是没有勾选的,就导致流量数据没有发往openvpn服务端。