Total Pageviews

Tuesday, 4 July 2017

openvpn的一个一键安装脚本“openvpn-install”让openvpn重放光彩,又可用openvpn翻墙了

openVPN隧道协议

OpenVPN是一个基于SSL加密的纯应用层VPN协议,是SSL VPN的一种,支持UDP与TCP两种方式。UDP和TCP是2种通讯协议,这里通常UDP的效率会比较高,速度也相对较快。所以尽量使用UDP连接方式,实在UDP没法使用的时候,再使用TCP连接方式。
由于其运行在纯应用层,避免了PPTP和L2TP在某些NAT设备后面不被支持的情况,并且可以绕过一些网络的封锁.通俗点讲,基本上能上网的地方就能用OpenVPN.
OpenVPN客户端软件可以很方便地配合路由表,实现不同线路(如国内和国外)的路由选择,实现一部分IP走VPN,另一部分IP走原网络。
OpenVPN 是一个高级的开源 VPN 解决方案,由 “OpenVPN technologies” 支持,并且已经成为开源网络领域里的事实标准。OpenVPN 使用成熟的 SSL/TLS 加密协议
OpenVPN 使用 OpenSSL 库来提供加密。OpenSSL 支持好几种不同的加密算法,如:3DES,AES 等。
OpenVPN 不包含在任何操作系统中,需要安装客户端软件,但安装也是相当简单,基本上 5 分钟可以完成。
OpenVPN 可以很容易的配置为使用任何端口运行,也可以使用 UDP 或 TCP 协议。为了顺利穿越限制性的防火墙,可以将 OpenVPN 配置成使用 TCP 443 端口,因为这样就无法和标准的 HTTPS 无法区分,从而极难被封锁。
无论是无线网络、蜂窝网络,还是丢包和拥塞经常发生的不可靠网络,OpenVPN 都非常稳定、快速。对于那些相当不可以的连接,OpenVPN 有一个 TCP 模式可以使用,但是要牺牲一点速度,因为将 TCP 封装在 TCP 时,效率不高。
OpenVPN 也没有明显漏洞,当和安全加密算法如 AES 一起使用时,也被认为是相当安全的。

脚本在此:https://github.com/Nyr/openvpn-install,其实我以前介绍过它:
http://briteming.blogspot.com/2016/08/openvpn.html ,只是当时未在linux vps上安装它。今天安装后, 发现又可用openvpn翻墙了。

安装方法如下:
登录linux vps.
wget https://github.com/Nyr/openvpn-install/raw/master/openvpn-install.sh
bash  openvpn-install.sh

运行此条命令bash  openvpn-install.sh,最后显示:
...
Generating a 2048 bit RSA private key
................+++
.............................+++
writing new private key to '/etc/openvpn/easy-rsa/pki/private/server.key.bMvlQu5Gie'
-----
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :PRINTABLE:'server'
Certificate is to be certified until Jul  2 04:22:38 2027 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated
Generating a 2048 bit RSA private key
...........+++
..........................................+++
writing new private key to '/etc/openvpn/easy-rsa/pki/private/client2.key.7nwUyrULSK'
-----
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :PRINTABLE:'client2'
Certificate is to be certified until Jul  2 04:22:39 2027 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.cnf

An updated CRL has been created.
CRL file: /etc/openvpn/easy-rsa/pki/crl.pem

 * Stopping virtual private network daemon(s)...                                 *   No VPN is running.
 * Starting virtual private network daemon(s)...                                 *   Autostarting VPN 'server'                                                 
Finished!

Your client configuration is available at /root/client2.ovpn
If you want to add more clients, you simply need to run this script again!
root@localhost:~#
root@localhost:~# ps aux|grep openvpn
nobody    7875  0.0  0.1  28492  1048 ?        Ss   05:22   0:00 /usr/sbin/openvpn --config server.conf --daemon
root      7926  0.0  0.0  11740   904 pts/6    S+   05:27   0:00 grep openvpn
root@localhost:~#

(服务器端的配置文件的完整路径:/etc/openvpn/server/server.conf

服务器端的配置文件内容如下:
root@localhost:~# cat /etc/openvpn/server/server.conf
port 1278
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-crypt tc.key
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
crl-verify crl.pem
root@localhost:~#

下载的客户端的配置文件client2.ovpn的内容:
client
dev tun
proto udp
sndbuf 0
rcvbuf 0
remote my-vps-ip 1278
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
comp-lzo
setenv opt block-outside-dns
key-direction 1
verb 3
<ca>
....
</ca>
<cert>
.....
</cert>
<key>
....
</key>
<tls-crypt>
....
</tls-crypt> 

可见2边的配置文件里都有cipher AES-256-CBC 这行代码,而众所周知AES-256-CBC 是用来加密的,就像shadowsocks的4个参数之一:加密方式,我们常用的是aes-256-cfb.估计就是
cipher AES-256-CBC这行代码给openvpn的链接加了一层密:加密连接,从而使得gfw无法侦测openvpn的流量特征,无法封锁openvpn,于是又可用openvpn翻墙了。

注:proto的值建议选择udp, udp协议比tcp协议更抗干扰。vps类型则建议选择openvz之外的类型,比如kvm/xen.如果你一定要用openvz vps,建议你使用bandwagonhost.com提供的openvz vps,这家的openvz vps默认开启了tun/tap如果使用其他vps供应商(比如alpharacks.com)的openvz vps,最好发ticket给其客服,要求enable tun/tap.(在其vps control panel里,用户自行enable tun/tap的话,其实并未真正的生效),然后运行:
openvpn  --config /etc/openvpn/server/server.conf

如果你运行openvpn  --config /etc/openvpn/server/server.conf ,遇到如下错误:
Options error: --dh fails with 'dh.pem': No such file or directory
Options error: --ca fails with 'ca.crt': No such file or directory
Options error: --cert fails with 'server.crt': No such file or directory
Options error: --key fails with 'server.key': No such file or directory
Options error: --crl-verify fails with 'crl.pem': No such file or directory
Options error: --tls-crypt fails with 'tc.key': No such file or directory
Options error: Please correct these errors.
Use --help for more information.

解决办法就是:把ca.crt,server.crt,server.key,dh.pem,ta.key,crl.pem那些文件写成完整路径
port 1278
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
auth SHA512
tls-crypt /etc/openvpn/server/tc.key
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
crl-verify /etc/openvpn/server/crl.pem

先运行openvpn  --config /etc/openvpn/server/server.conf ,看看是否正常:
如果屏幕的最下一行为initialization sequence completed,则说明openvpn运行正常。
如果正常,才带“--daemon”运行:
openvpn  --config /etc/openvpn/server/server.conf --daemon

然后设置OpenVPN访问外网:
echo 1 > /proc/sys/net/ipv4/ip_forward
(或者:sysctl -w net.ipv4.ip_forward=1)
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE (注意:如果你的vps是xen/kvm平台,则需把venet0改为eth0) 
至此,服务器端的设置完毕。注意:如果你的vps重启了,一定要记得重新运行上面的这2条命令。当然这条命令:openvpn  --config /etc/openvpn/server/server.conf --daemon也不能忘了运行。

在运行openvpn client app后,服务器端的配置文件/etc/openvpn/server/server.conf里的这2行内容:
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
会被推送到客户机器上,也即:客户机器的本地dns server地址会被强行改为:
8.8.8.8
8.8.4.4

但是客户机器不一定能连上8.8.8.8或8.8.4.4,所以我们可以修改服务器端的配置文件/etc/openvpn/server/server.conf里的这2行内容:
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
为:
push "dhcp-option DNS 127.0.0.1"

因为修改了openvpn服务器端的配置文件,所以需要重启openvpn:
killall openvpn
openvpn  --config /etc/openvpn/server/server.conf --daemon

在运行openvpn client app后,服务器端的配置文件/etc/openvpn/server/server.conf里的这1行内容:
push "dhcp-option DNS 127.0.0.1"
会被推送到客户机器上,也即:客户机器的本地dns server地址会被强行自动改为:
127.0.0.1
这样就无需手动去修改客户机器的本地dns server地址为127.0.0.1了。

如果你的本地机器是mac,请下载/安装mac上面的openvpn客户端程序tunnelblick.然后在mac的finder里面,进入“下载”文件夹,双击下载到“下载”文件夹中的客户端配置文件(.ovpn文件),即可导入该配置文件到tunnelblick,然后就可用tunnelblick翻墙了:
首先运行openvpn client,然后客户机器的本地dns server地址会被强行自动改为:
127.0.0.1,
然后运行一个dns proxy程序,比如:dns-over-tls-forwarder,dns-over-tls-forwarder的用法见https://briteming.blogspot.com/2020/01/unbounddns-over-tls.html

如果你使用一段时间翻不了墙了,重启openvpn客户端即可。如果还是不行,请重启系统,再运行客户端。

 使用10来天后,觉得在openvz vps上搭建的openvpn不易连上,因此强烈建议在kvm vps/xen vps上搭建openvpn!!!
如果不易连上vps上搭建的openvpn,简单的解决办法-在vps上,重装openvpn:运行bash openvpn-install.sh
来卸载openvpn,然后运行bash openvpn-install.sh ,重装openvpn,然后下载生成的配置文件(ovpn文件),导入此配置文件到openvpn客户端程序,你就又可以翻墙了。

在ios device上,切换app store到香港区,搜索openvpn connect,进行安装。( 在
app store的中国区,openvpn connect已经下架)
然后把下载的客户端的配置文件client2.ovpn作为附件发到自己的邮箱,登录邮箱,点击附件client2.ovpn,会显示‘在openvpn中打开‘的链接,点击该链接,再点击弹出的页面中的“+”号,即可把客户端的配置文件client2.ovpn导入到客户端程序openvpn connect中,然后在openvpn connect中启用连接,稍等片刻,ios device的右上角就会出现VPN字样,ios device即可翻墙。

 如果你在服务器上运行了此3条命令:
 openvpn  --config /etc/openvpn/server.conf --daemon
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE


相关帖子:
http://briteming.blogspot.com/2016/05/openvpn-connectiosopenvpn-client.html
https://itunes.apple.com/app/openvpn-connect/id590379981

http://briteming.blogspot.com/2016/08/openvpn.html

本帖即是用此法翻墙后发布的。
-----------------------

https://github.com/Angristan做出的改进版:https://github.com/Angristan/OpenVPN-install

Usage

You have to enable the TUN module otherwise OpenVPN won't work. Ask your host if you don't know how to do it. If the TUN module is not enabled, the script will warn you and exit.
You can get a cheap VPS to run this script for $2.50/month worldwide at Vultr or 3€/month for unlimited bandwidth in France at PulseHeberg.
First, get the script and make it executable :
wget https://raw.githubusercontent.com/Angristan/OpenVPN-install/master/openvpn-install.sh
chmod +x openvpn-install.sh
Then run it :
./openvpn-install.sh
The first time you run it, you'll have to follow the assistant and answer a few questions to setup your VPN server.
When OpenVPN is installed, you can run the script again, and you will get the choice to :
  • Add a client
  • Remove a client
  • Uninstall OpenVPN

Why make a fork ?

This script is based on the great work of Nyr and its contributors.
I made it because I wanted to have a more secured OpenVPN out-of-the-box. It works like the original script, but is more focused on privacy and espicially better encryption. Nyr's original script uses mainly default parameters regarding encryption, and some of them are unsecure. See #encryption.
Also, Nyr and myself clearly have not the same point of view regarding this script, that's why it's a fork.
The only drawback is that you need to use a recent version of OpenVPN, because some parameters that requires TLS 1.2 are only availble since OpenVPN 2.3.3. Therefore I restrain the compatibility of this script to a few but widely used GNU/Linux distributions, to get a recent version of OpenVPN from trusted third-party repositories, if needed. That is not a complete drawback tough, because it means that you can have the latest version with all the new features and security fixes. See compatibilty.
On the client-side, it's less problematic, but if you want to use an OpenVPN server installed with this script with an old client (<2.3.3), it won't work. However I don't see why you would use an outdated client.
TL;DR, this script is relatively secure, and you can just press enter in the setup.

Compatibility

The script is made to work on these OS and architectures :
  • Debian 7 (i386, amd64)
  • Debian 8 (i386, amd64)
  • Debian 9 (i386, amd64, armhf, arm64)
  • Ubuntu 12.04 LTS (i386, amd64)
  • Ubuntu 14.04 LTS (i386, amd64)
  • Ubuntu 16.04 LTS (i386, amd64)
  • Ubuntu 16.10 (i386, amd64, armhf, arm64)
  • Ubuntu 17.04 (i386, amd64, armhf, arm64)
  • CentOS 6 (i386, amd64)
  • CentOS 7 (i386, amd64, arm64)
  • Arch Linux (i686, amd64)
(It should also work on Debian unstable/testing and Ubuntu beta).
If your're using an Ubuntu version that is not supported by the script, be aware that it's not supported by Ubuntu either, thus it's insecure.

Features

This fork includes the following features :

DNS

The script will ask you which DNS resolvers you want to use when connected to the VPN.
Here are the possibilities :
  • Current system resolvers, those that are in /etc/resolv.conf
  • FDN's DNS Servers, recommended if you're in western europe (France)
  • DNS.WATCH DNS Servers, recommended if you're in western europe (Germany)
  • OpenDNS, not recommened but fast wordlwide (Anycast servers)
  • Google Public DNS, not recommended, but fast worldwide (Anycast servers)
  • Yandex Basic DNS, not recommended, but fast in Russia
  • Soon : local resolver :D
Any other fast, trustable and neutral servers proposition is welcome.

Encryption

The main reason why I made this fork is to improve the encryption. Indeed, OpenVPN's default parameters are weak (and that's what Nyr's script uses).
I want to justify all my choices regarding the encryption settings I have chosen, to prove that I'm not some random noob as some may think. 😉
However I'm far from a crypto expert, so don't hesitate to doubt what I say (I put links to my sources anyway), and to open an issue to correct me.
OpenVPN 2.4 will be a great update on the encryption part, because we'll be able to use elliptic curves, so ECDSA and ECDH (as well for the control channel), and AES GCM. They are faster and more secure. I will, of course, update the script when it will be available.
Note: With OpenVPN's default parameters, you have a relatively weak encryption. Nonetheless, your trafic is still encrypted, so unless you're under surveillance, probably no one will try to decrypt it. Yet it's not a reason to use old and weak algorithm when there are much better ones available. 😉

TLS version

OpenVPN uses TLS 1.0 by default, which is nearly 20 years old.
With tls-version-min 1.2 we use at least TLS 1.2, which the best protocol available currently. I could have used tls-version-min highest but this does not ensure we use TLS 1.2 which is the only secure protocol available.
OpenVPN documentation for tls-version-min
TLS 1.2 is only supported since OpenVPN 2.3.3. This is one of the reasons of the script uses third-party repositories, because some distributions have an older version of OpenVPN.

Certificate

Key

OpenVPN uses an RSA certificate with a 2048 bits key by default.
2048 bits is OK, but both NSA and ANSSI recommend at least a 3072 bits for a future-proof key. As the size of the key will have an impact on speed, I leave the choice to use 2048, 3072 or 4096 bits RSA key. 4096 bits is what's most used and recommened today, but 3072 bits is still good.
In OpenVPN 2.4, we will be able to use an ECDSA certificate. This algorithm uses elliptic curves instead of prime numbers' factorization for a reduced key size and calculation time, thus it's faster and more secure.

Signature hash

OpenVPN uses SHA-256 by default.
It also supports SHA1 and MD5, which are unsafe, and all the SHA2 family. I didn't find any reason to use something other than SHA-256 in the SHA2 group, so the script still uses the default hash algorithm.

Data channel's cipher

By default, OpenVPN uses BF-CBC as the data channel cipher. Blowfish is an old (1993) an weak alogorithm. What's funny is that even the official OpenVPN documentation admits it.
The default is BF-CBC, an abbreviation for Blowfish in Cipher Block Chaining mode. Using BF-CBC is no longer recommended, because of its 64-bit block size. This small block size allows attacks based on collisions, as demonstrated by SWEET32. See https://community.openvpn.net/openvpn/wiki/SWEET32 for details.
Source
Security researchers at INRIA published an attack on 64-bit block ciphers, such as 3DES and Blowfish. They show that they are able to recover plaintext when the same data is sent often enough, and show how they can use cross-site scripting vulnerabilities to send data of interest often enough. This works over HTTPS, but also works for HTTP-over-OpenVPN. See ​https://sweet32.info/ for a much better and more elaborate explanation. OpenVPN's default cipher, BF-CBC, is affected by this attack.
Source
Blowfish's use of a 64-bit block size (as opposed to e.g. AES's 128-bit block size) makes it vulnerable to birthday attacks, particularly in contexts like HTTPS. In 2016, the SWEET32 attack demonstrated how to leverage birthday attacks to perform plaintext recovery (i.e. decrypting ciphertext) against ciphers with a 64-bit block size such as Blowfish.[9]
A reduced-round variant of Blowfish is known to be susceptible to known-plaintext attacks on reflectively weak keys. Blowfish implementations use 16 rounds of encryption, and are not susceptible to this attack. Blowfish users are encouraged by Bruce Schneier, Blowfish's creator, to use the more modern and computationally efficient alternative Twofish. He is quoted in 2007 as saying:
"At this point, though, I'm amazed it's still being used. If people ask, I recommend Twofish instead."
Source
Convinced ?
The SWEET32 vulnerability page from OpenVPN's documentation says :
The following ciphers are affected, and should no longer be used:
  • BF-*
  • DES* (including 3DES variants)
  • RC2-*
The following ciphers are not affected:
  • AES-*
  • CAMELLIA-*
  • SEED-*
Indeed, AES is today's standard. It's the fastest and more secure cipher available today. SEED and Camellia are not vulnerable to date but are slower than AES and relatively less trusted.
As they have not any proven vulnerabilities, I decided to give the user the choice to use them, though I don't see any particular reason to this day to use it. Maybe someday if AES happens to be broken. Here is an exemple about why Camellia is good, but AES is better and should be used.
Currently AES is only available in its CBC mode, which is weaker than GCM.
To quote the OpenVPN documentation :
Of the currently supported ciphers, OpenVPN currently recommends using AES-256-CBC or AES-128-CBC. OpenVPN 2.4 and newer will also support GCM. For 2.4+, we recommend using AES-256-GCM or AES-128-GCM.
Of course I will update the script to add AES-GCM mode (as well as ECDH and ECDSA) as soon as OpenVPN 2.4 is released.
For now, these cipher are available in the setup :
  • AES-128-CBC
  • AES-192-CBC
  • AES-256-CBC
  • CAMELLIA-128-CBC
  • CAMELLIA-192-CBC
  • CAMELLIA-256-CBC
  • SEED-CBC
AES-256 is 40% slower than AES-128, and there isn't any real reason to use a 256 bits key over a 128 bits key with AES. (Source : [1],[2]).
Moreover, AES-256 is more vulnerable to Timing attacks.
Thus, the best data channel cipher currently available in OpenVPN is AES-128-CBC.

Control channel's cipher

According to the Hardening page of the OpenVPN wiki, TLS 1.2 is not supported by OpenVPN <2.3.3, so it uses a TLS 1.0 cipher by default, which is unsecure.
The following are TLSv1.2 DHE + RSA choices, requiring a compatible peer running at least OpenVPN 2.3.3:
  • TLS-DHE-RSA-WITH-AES-256-GCM-SHA384
  • TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
  • TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
  • TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
AES GCM is more secure than AES CBC, and AES 128 is secure enough today. I didn't find any security difference between SHA-256 and SHA-384 so we're going to use SHA-256.
Thus, I have chosen TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 as the control channel cipher.

Diffie-Hellman key

OpenVPN uses a 2048 bits DH key by default.
2048 bits is OK, but both NSA and ANSSI recommend at least a 3072 bits for a future-proof key. Like RSA, the size of the key will have an impact on speed, I leave the choice to use a 2048, 3072 or 4096 bits key. 4096 bits is what's most used and recommened today, but 3072 bits is still good.
In OpenVPN 2.4, we will be able to use ECDH key. It uses elliptic curves instead of prime numbers' factorization for a reduced key size and calculation time, thus it's faster and more secure.

HMAC authentication algorithm

To quote the OpenVPN wiki :
Authenticate packets with HMAC using message digest algorithm alg. (The default is SHA1 ). HMAC is a commonly used message authentication algorithm (MAC) that uses a data string, a secure hash algorithm, and a key, to produce a digital signature. OpenVPN's usage of HMAC is to first encrypt a packet, then HMAC the resulting ciphertext.
SHA-1 is not safe anymore, so I use SHA-256 which is safe and widely used.

TLS-crypt

The --tls-crypt option uses a static pre-shared key (PSK) that must be generated in advance and shared among all peers. This features adds "extra protection" to the TLS channel by requiring that incoming packets have a valid signature generated using the PSK key. If this key is ever changed, it must be changed on all peers at the same time (there is no support for rollover.)
The primary benefit is that an unauthenticated client cannot cause the same CPU/crypto load against a server as the junk traffic can be dropped much sooner. This can aid in mitigating denial-of-service attempts.
This feature by itself does not improve the TLS auth in any way, although it offers a 2nd line of defense if a future flaw is discovered in a particular TLS cipher-suite or implementation (such as CVE-2014-0160, Heartbleed, where the tls-crypt key provided protection against attackers who did not have a copy). However, it offers no protection at all in the event of a complete cryptographic break that can allow decryption of a cipher-suite's traffic.
Source
TLS-crypt is not enabled by default by OpenVPN, but it is in this script。

from  https://github.com/Angristan/OpenVPN-install
---------

安装OpenVPN

安装OpenVPN和easy-rsa
注意 以下命令均需要sudo权限
将easy-rsa拷贝到OpenVPN目录下
之后进入目录
之后我们会用到一些环境变量, 修改”vars”里面对应数据, 以下为一个示例
接下来拷贝openssl配置
加载环境变量
生成密钥的最后一步准备工作是清空旧的证书和密钥,以及生成新密钥的序列号和索引文件。
生成证书
生成服务器密钥
生成Diffie-Hellman密钥, 此过程请耐心等待
生成用于TLS验证的密钥
移动所有生成的文件到最后的位置中

服务端配置文件(server.conf)

  • 编辑位于/etc/openvpn/server.conf, 以下附上我的配置文件的一部分并加以解释

备注0

  • proto可选的有TCP/TCP6/UDP/UDP6 其中IPv6版本向下兼容IPv4, 这里我们显然需要使用IPv6. 请注意,请尽量不要在普通IPv4环境下使用OpenVPN, 因为防火墙能准确识别OpenVPN.

备注1

  • OpenVPN工作在三层, 因此网络流量是否走VPN隧道完全由路由表控制.
  • 此处的redirect-gateway是将默认路由改为走VPN隧道
  • def1是可选参数, 此处是一个OpenVPN的feature(真feature!不是Bug!), 当没有此参数时, 连接VPN时给客户端推的路由为”0.0.0.0/0″, 此时, 系统中可能存在两条0.0.0.0的路由(一条是本来的默认网关, 根据不同系统情况可能有所不同), 而如果有def1参数, 向客户端推得路由表为0.0.0.0/1和128.0.0.0/1这两条, 根据最长匹配原则, 数据就一定会通过VPN隧道走了!

备注2

  • push “route address netmask vpn_gateway/net_gateway”这是向客户端推送一条通过VPN隧道走或通过本来的网关走的路由表, 如果细心的话, 会发现166.111.204.120就是net.tsinghua.edu.cn的地址…这样我就能把它给劫持了.
  • 至于其他的校内IP地址, 你可以在bgp.he.net上找到或找我要一份…

备注3

  • 向客户端interface推DNS地址

备注4

  • auth-user-pass-verify 表示通过用户名密码方式验证
  • xxx 是你的自定义验证脚本, 每次有用户连接时, OpenVPN会自动运行一次此脚本, 返回值为0表示认证成功, 为1表示认证失败
  • via-env 表示用户名密码通过环境变量传递
  • 更多信息请查阅官方文档

备注5

  • 这两处是自定义的连接和断开连接时运行的脚本. 劫持的net.tsinghua页面的用户名对应就是在连接时处理的, 流量统计是在断开连接时处理的.
  • 更多信息请查阅官方文档
至此OpenVPN服务端配置已完成

开启转发

不开启转发的话,VPN将不能转发你的数据包
编辑/etc/sysctl.conf
将net.ipv4.ip_forward = 0改成net.ipv4.ip_forward = 1
让更改生效

iptables配置

Xen和KVM用户
OpenVZ用户

保存iptables配置

编辑/etc/network/interfaces文件,在最后插入一行:

服务端基本配置完成

客户端配置文件

完成

劫持net.tsinghua 只需将net.tsinghua的路由表改为到VPN, 再在服务器上将net.tsinghua DNAT到本地, 服务器Nginx监听net.tsinghua.edu.cn即可
更多关于OpenVPN的信息请参考官方文档
---------------------------------

OpenVPN服务部署

1 服务端部署(Ubuntu)

1.1 安装OpenVPN 所需插件






















1
2
3
4
$ sudo apt-get install openssl
$ sudo apt-get install libssl-dev
$ sudo apt-get install libpam0g-dev
$ sudo apt-get install liblzo2-dev

1.2 安装OpenVPN

注:以下安装方式任选一种,推荐apt-get方式安装

1.2.1 apt-get安装OpenVPN






















1
2
3
$apt-get install openvpn
$cd /etc/openvpn
$mkdir conf log

1.2.2 源码安装OpenVPN(建议使用2.2.2版本)






















1
2
3
4
5
$ wget http://swupdate.openvpn.org/community/releases/openvpn-2.2.2.tar.gz
$ tar -zxvf openvpn-2.2.2.tar.gz
$ mkdir /data/openvpn && cd openvpn-2.2.2
$ ./configure --enable-password-save --prefix=/etc/openvpn
$ make && sudo make install

注:–enable-password-save该选项是避免手工输入客户端密码;–prefix选项是真正的安装路径

1.3 开启内核转发并配置源地址路由






















1
2
$ echo "1" > /proc/sys/net/ipv4/ip_forward
$ iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

1.4 服务端配置

1.4.1 生成密钥






















1
2
3
4
5
6
7
8
9
$ cd openvpn-2.2.2/easy-rsa/2.0
$ source ./vars # 在此之前,可以修改vars文件对国家省份等修改;配置dh的位数(默认是1024,可以改成export KEY_SIZE=2048)和下文生成的dh2048.pem相对应
$ ./clean-all
$ ./build-ca
$ ./build-key-server server # 产生服务器证书,此处的server是文件名参数,可以任意修改。
$ ./build-key-pass client1 # 生成客户端key,pass表示需要输入一个密码作为客户端启动时的凭证; ./build-key则不需要输入密码
$ ./build-dh # 产生Diffie Hellman参数
至此一个客户端所需的证书已经完毕,都在easy-rsa/2.0/keys文件夹下面,其中ca.crt server.crt server.csr server.key dh1024.pem是服务端所需证书文件,ca.crt ca.key client1.crt client1.csr client1.key是客户端所需证书文件。
注:可以继续使用./build-key产生更多客户端证书,一个客户端证书只能同时用于一个客户端连接。

1.4.2 服务端配目录及文件






















1
2
3
$ cd openvpn && mkdir conf # openvpn就是第2步中openvpn的安装目录
$ cp openvpn-2.2.2/sample-config-files/server.conf conf/
$ cp openvpn-2.2.2/easy-rsa/2.0/keys/{ca.crt,server.crt,server.csr,server.key,dh1024.pem} conf/ # 拷贝openvpn-2.2.2/easy-rsa/2.0/keys/下的相关证书文件到openvpn/conf/目录下,注意:2048位的key则是dh2048.pem; 1024位的key则是dh1024.pem

1.4.3 服务端配置文件参数指定






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ vim conf/server.conf
dev tap
proto tcp
port 1194
ca /path/to/openvpn/conf/ca.crt
cert /path/to/openvpn/conf/server.crt
key /path/to/openvpn/conf/server.key
dh /path/to/openvpn/conf/dh1024.pem
user nobody
group nogroup
server 10.8.0.0 255.255.255.0 # 分配给clinet的ip段
second time period
keepalive 10 120 # 每10秒ping一次,120秒内客户端没有动作就断开连接
persist-key
persist-tun
verb 4
log-append /path/to/openvpn/log/openvpn.log
status /path/to/openvpn/log/openvpn-status.log
cipher AES-256-CBC
client-to-client
crl-verify /path/to/openvpn/conf/crl.pem # 客户端证书连接限制
comp-lzo

1.5 启动OpenVPN服务端






















1
sudo /path/to/openvpn/sbin/openvpn --config /path/to/openvpn/conf/server.conf --daemon

1.6 检查验证






















1
2
$ ifconfig|grep inet|grep 10.8.0.1
inet 10.8.0.1 netmask 0xffffff00 broadcast 10.8.0.255

注:得到IP为:10.8.0.1 则说明VPN服务端配置成功 

1.7 设置OpenVPN服务端开机启动






















1
2
3
$ vim /etc/rc.local
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
/path/to/openvpn/sbin/openvpn --config /path/to/openvpn/conf/server.conf --daemon

2 OpenVPN 客户端部署(MAC系统)

2.1 安装OpenVPN 所需插件






















1
$ sudo brew install openssl

2.2 安装OpenVPN

注:以下安装方式任选一种,推荐Brew方式安装

2.2.1 Brew 安装






















1
2
3
4
5
直接brew安装(推荐)
$brew install openvpn
$cd /usr/local/Cellar/openvpn/2.3.11_1
$mkdir conf log
$ln -s /usr/local/Cellar/openvpn/2.3.11_1/sbin/openvpn /usr/local/bin/openvpn

2.2.2 源码安装(建议使用2.2.2版本)






















1
2
3
4
5
$ wget http://swupdate.openvpn.org/community/releases/openvpn-2.2.2.tar.gz
$ tar -zxvf openvpn-2.2.2.tar.gz
$ mkdir /data/openvpn && cd openvpn-2.2.2
$ ./configure --enable-password-save --prefix=/etc/openvpn
$ make && sudo make install

注:–enable-password-save该选项是避免手工输入客户端密码;–prefix选项是真正的安装路径

2.3 服务端生成客户端所需密钥(客户端部署可忽略此步骤)

2.3.1 服务端连接






















1
2
3
4
服务端所在机器:xxx.xxx.xxx.xxx
$ssh root@xxx.xxx.xxx.xxx #连接方式
$cd /media/openvpn/ 服务端所在路径
$cd /media/openvpn-2.2.2/easy-rsa/2.0 生成密钥所需路径

2.3.2 生成密钥






















1
2
$ source ./vars
$ ./build-key-pass client-A #此处设置密码为:openvpn123

注:生成客户端key,pass表示需要输入一个密码作为客户端启动时的凭证; ./build-key则不需要输入密码





















1
$ ./build-dh

2.3.3设置客户端密钥验证信息






















1
2
$ vim /media/openvpn/conf/ccd/client-A
ifconfig-push 10.8.0.119 255.255.255.0

注:此处的验证信息文件名需要和生成密钥时输入的名字保持一致;
10.8.0.119 指客户端被虚拟出来的IP 

2.4 客户端配置

2.4.1 拷贝密钥到客户端






















1
2
$scp root@xxx.xxx.xxx.xxx:/media/openvpn-2.2.2/easy-rsa/2.0/keys/{ca.crt,ca.key,client-A.crt,client-A.csr,client-A.key} /usr/local/Cellar/openvpn/2.3.11_1/conf/
注:密钥可以由维护人员发放,联系刘东;

2.4.2 配置客户端密码文件






















1
2
$ vim /usr/local/Cellar/openvpn/2.3.11_1/conf/password.txt
openvpn123

注:客户端密码文件和服务端生成密钥时输入的密码一致

2.4.3 客户端配置文件






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ vim /usr/local/Cellar/openvpn/2.3.11_1/conf/client.conf
client
dev tap
proto tcp
remote xxx.xxx.xxx.xxx 1194 #指定服务端外网IP及端口
nobind
user nobody
group nogroup
ca /usr/local/Cellar/openvpn/2.3.11_1/conf/ca.crt
cert /usr/local/Cellar/openvpn/2.3.11_1/conf/client-A.crt
key /usr/local/Cellar/openvpn/2.3.11_1/conf/client-A.key
ping 15
ping-restart 45
ping-timer-rem
persist-key
persist-tun
ns-cert-type server
comp-lzo
verb 4
log-append /usr/local/Cellar/openvpn/2.3.11_1/log/openvpn.log
status /usr/local/Cellar/openvpn/2.3.11_1/log/openvpn-status.log 
cipher AES-256-CBC
tcp-queue-limit 4096 # 256
bcast-buffers 4096

2.5 启动客户端

2.5.1 命令行启动OpenVPN






















1
$ sudo /usr/local/bin/openvpn --config /usr/local/Cellar/openvpn/2.3.11_1/conf/client.conf --askpass /usr/local/Cellar/openvpn/2.3.11_1/conf/password.txt --daemon

2.5.2 GUI启动OpenVPN

2.6 检查验证






















1
2
$ ifconfig|grep inet|grep 10.8.0.119
inet 10.8.0.119 netmask 0xffffff00 broadcast 10.8.0.255

注:得到IP为:10.8.0.x 则说明VPN客户端配置成功





















1
$ ping 10.8.0.1 #检查是否能ping通内网等机器

2.7 服务加入开机自启动






















1
2
vim /etc/rc.local
/usr/local/bin/openvpn --config /usr/local/Cellar/openvpn/2.3.11_1/conf/client.conf --askpass /usr/local/Cellar/openvpn/2.3.11_1/conf/password.txt --daemon

3 OpenVPN 客户端部署(Ubuntu系统)

3.1 安装OpenVPN 所需插件






















1
2
3
4
$ sudo apt-get install openssl
$ sudo apt-get install libssl-dev
$ sudo apt-get install libpam0g-dev
$ sudo apt-get install liblzo2-dev

3.2 安装OpenVPN

注:以下安装方式任选一种,推荐apt-get方式安装

3.2.1 apt-get安装OpenVPN






















1
2
3
$apt-get install openvpn
$cd /etc/openvpn
$mkdir conf log

3.2.2 源码安装OpenVPN(建议使用2.2.2版本)






















1
2
3
4
5
$ wget http://swupdate.openvpn.org/community/releases/openvpn-2.2.2.tar.gz
$ tar -zxvf openvpn-2.2.2.tar.gz
$ mkdir /data/openvpn && cd openvpn-2.2.2
$ ./configure --enable-password-save --prefix=/etc/openvpn
$ make && sudo make install

注:–enable-password-save该选项是避免手工输入客户端密码;–prefix选项是真正的安装路径

3.3 服务端生成客户端所需密钥(客户端部署可忽略此步骤)

3.3.1 服务端连接






















1
2
3
4
服务端所在机器:xxx.xxx.xxx.xxx
$ssh root@xxx.xxx.xxx.xxx #连接方式
$cd /media/openvpn/ 服务端所在路径
$cd /media/openvpn-2.2.2/easy-rsa/2.0 生成密钥所需路径

3.3.2 生成密钥






















1
2
$ source ./vars
$ ./build-key-pass client-B #此处设置密码为:openvpn123

注:生成客户端key,pass表示需要输入一个密码作为客户端启动时的凭证; ./build-key则不需要输入密码





















1
$ ./build-dh

3.3.3设置客户端密钥验证信息






















1
2
$ vim /media/openvpn/conf/ccd/client-B
ifconfig-push 10.8.0.120 255.255.255.0

注:此处的验证信息文件名需要和生成密钥时输入的名字保持一致;
10.8.0.120 指客户端被虚拟出来的IP 

3.4 客户端配置

3.4.1 拷贝密钥到客户端






















1
2
$scp root@xxx.xxx.xxx.xxx:/media/openvpn-2.2.2/easy-rsa/2.0/keys/{ca.crt,ca.key,client-B.crt,client-B.csr,client-B.key} /etc/openvpn/conf
注:密钥可以由维护人员发放,联系刘东;

3.4.2 配置客户端密码文件






















1
2
$ vim /etc/openvpn/conf/password.txt
openvpn123

注:客户端密码文件和服务端生成密钥时输入的密码一致

3.4.3 客户端配置文件






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ vim /etc/openvpn/conf/client.conf
client
dev tap
proto tcp
remote xxx.xxx.xxx.xxx 1194 #指定服务端外网IP及端口
nobind
user nobody
group nogroup
ca /etc/openvpn/conf/ca.crt
cert /etc/openvpn/conf/client-B.crt
key /etc/openvpn/conf/client-B.key
ping 15
ping-restart 45
ping-timer-rem
persist-key
persist-tun
ns-cert-type server
comp-lzo
verb 4
log-append /etc/openvpn/log/openvpn.log
status /etc/openvpn/log/openvpn-status.log 
cipher AES-256-CBC
tcp-queue-limit 4096 # 256
bcast-buffers 4096

3.5 启动客户端






















1
$ sudo openvpn --config /etc/openvpn/conf/client.conf --askpass /etc/openvpn/conf/password.txt --daemon

3.6 检查验证






















1
2
$ ifconfig|grep inet|grep 10.8.0.120
inet 10.8.0.120 netmask 0xffffff00 broadcast 10.8.0.255

注:得到IP为:10.8.0.x 则说明VPN客户端配置成功





















1
$ ping 10.8.0.1 #检查是否能ping通内网等机器

3.7 服务加入开机自启动






















1
2
vim /etc/rc.local
openvpn --config /etc/openvpn/conf/client.conf --askpass /etc/openvpn/conf/password.txt --daemon
---------------------------------

OPENVPN使用PAM及MYSQL进行用户认证

1.使用PAM模块
PAM简介:
Pluggable Authentication Module (PAM) 是行业标准验证框架。
PAM 为系统管理员提供了选择系统上可用的任何验证服务来执行验证的灵活性。使用 PAM 框架还可以插入新的验证服务模块,并且无需修改应用程序即可使用,
包含帐户管理,用户验证,口令管理,会话管理四个模块.指定如何处理同一个 service-name 和 module-type 的多个定义的关键字。它为下列值之一
required模块测试必须成功。
optional模块测试可以失败。
sufficient如果测试成功,则不执行进一步的测试。
1>OPENVPN服务器端配置:
plugin /usr/sharelib/openvpn-auth-pam.so login //指定模块的位置,该动态链接库在OPENVPN发生包里需要编译
client-cert-not-required //客户端数字证书无需指定
username-as-common-name //用户名作为common name
2>OPENVPN客户端配置:
auth-user-pass
3>服务器设置:
需要增加相应的用户名及密码,使用useradd password命令
重新启动OPENVPN,则在客户端登录OPENVPN的时候会提示输入用户名及密码
2.使用PAM-MYSQL
1>安装MYSQL,添加用户名vpn 密码设置为vpn,用户表为库openvpn中的user
2>安装pam_mysql ,下载位置http://internap.dl.sourceforge.net/sourceforge/pam-mysql/pam_mysql-0.5.tar.gz
3>配置pam配置文件,在/etc/pam.d中新建openvpn内容如下
auth    required        pam_mysql.so          user=vpn passwd=vpn host=192.168.1.11 db=openvpn table=user usercolumn=username passwdcolumn=password
account required        pam_mysql.so                   user=vpn passwd=vpn host=192.168.1.11 db=openvpn   table=user usercolumn=username   passwdcolumn=password
注意:将pam_mysql.so文件拷入 /lib/security/位置;并且保证系统中有libmysqlclient.so文件,如果连接远程MYSQL数据库无需此文件
4>OPENVPN服务器配置
plugin /usr/sharelib/openvpn-auth-pam.so openvpn 其余配置与上同//加载/etc/pam.d/openvpn配置文件
5>客户端配置与上同.
-------------------------------

How to install a OpenVPN System Based On User/Password Authentication with mysql



Source Page: http://sysadmin.compxtreme.ro/how-to-install-a-openvpn-system-based-on-userpassword-authentication-with-mysql-day-control-libpam-mysql/

here comes the article:
This document describes how to install a OpenVPN server with User/Password authentication with mysql and day control using libpam-mysql. This will be a brief, but a very practical document.
Install mysql server
apt-get install mysql-server
Create a mysql user and a database to be used later
Create user
mysql -u root -p
CREATE DATABASE openvpn;
USE openvpn;
create database
CREATE USER 'openvpn'@'localhost' IDENTIFIED BY 'lNPg5TAIy82zFpEn';
GRANT ALL PRIVILEGES ON `openvpn`.* TO 'openvpn'@'localhost';
FLUSH PRIVILEGES;
Create user table
CREATE TABLE IF NOT EXISTS `user` (
    `user_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
    `user_pass` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '1234',
    `user_mail` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
    `user_phone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
    `user_start_date` date NOT NULL,
    `user_end_date` date NOT NULL,
    `user_online` enum('yes','no') NOT NULL DEFAULT 'no',
    `user_enable` enum('yes','no') NOT NULL DEFAULT 'yes',
PRIMARY KEY (`user_id`),
KEY `user_pass` (`user_pass`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Create log table
CREATE TABLE IF NOT EXISTS `log` (
    `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `user_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
    `log_trusted_ip` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_trusted_port` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_remote_ip` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_remote_port` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `log_end_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
    `log_received` float NOT NULL DEFAULT '0',
    `log_send` float NOT NULL DEFAULT '0',
PRIMARY KEY (`log_id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Install OpenVPN
apt-get install openvpn
Generate keys
apt-get install openssl
Copy certificate generate file from example
cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn/.
cd /etc/openvpn/easy-rsa/2.0/
Replace some options (I have no idea why author want to do this)
sed -i -e 's/--interact //g' build-key
search and replace the following values in /etc/openvpn/easy-keys/2.0/vars
vim vars
export KEY_SIZE=2048

export KEY_COUNTRY="SE"
export KEY_PROVINCE="SE"
export KEY_CITY="STOCKHOLM"
export KEY_ORG="Company Name"
export KEY_EMAIL="email@example.org"
export KEY_CN=vpn.example.org
export KEY_NAME=operations
export KEY_OU=operations
export PKCS11_MODULE_PATH=changeme
export PKCS11_PIN=1234
save and exit
Disable unqiue subject
sed -i -e 's/unique_subject = yes/unique_subject = no/g' /etc/openvpn/easy-rsa/2.0/keys/index.txt.attr
Start to bulid certificates
source ./vars
./clean-all
./build-ca
./build-key-server vpn.example.org
./build-dh
cp -a keys /etc/openvpn/.
Install libpam-mysql and setup pam authentication based on it
apt-get install libpam-mysql
Add a new file inside pam
touch /etc/pam.d/openvpn
Paste the following content into the file we just created
auth sufficient pam_mysql.so user=openvpn passwd=lNPg5TAIy82zFpEn host=localhost db=openvpn [table=user] usercolumn=user.user_id passwdcolumn=user.user_pass [where=user.user_enable=1 AND user.user_start_date!=user.user_end_date AND TO_DAYS(now()) >= TO_DAYS(user.user_start_date) AND (TO_DAYS(now()) <= TO_DAYS(user.user_end_date) OR user.user_end_date='0000-00-00')] sqllog=0 crypt=0
account required pam_mysql.so user=openvpn passwd=lNPg5TAIy82zFpEn host=localhost db=openvpn [table=user] usercolumn=user.user_id passwdcolumn=user.user_pass [where=user.user_enable=1 AND user.user_start_date!=user.user_end_date AND TO_DAYS(now()) >= TO_DAYS(user.user_start_date) AND (TO_DAYS(now()) <= TO_DAYS(user.user_end_date) OR user.user_end_date='0000-00-00')] sqllog=0 crypt=0
Create scripts to log OpenVPN access activity
mkdir /etc/openvpn/scripts/ && cd $_
Create the following file
vim /etc/openvpn/scripts/config.sh
#!/bin/bash
##Dababase Server
HOST='127.0.0.1'
#Default port = 3306
PORT='3306'
#Username
USER='openvpn'
#Password
PASS='lNPg5TAIy82zFpEn'
#database name
DB='openvpn'
vim /etc/openvpn/scripts/connect.sh
#!/bin/bash
. /etc/openvpn/scripts/config.sh
##insert data connection to table log
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "INSERT INTO log (log_id,user_id,log_trusted_ip,log_trusted_port,log_remote_ip,log_remote_port,log_start_time,log_end_time,log_received,log_send) VALUES(NULL,'$common_name','$trusted_ip','$trusted_port','$ifconfig_pool_remote_ip','$remote_port_1',now(),'0000-00-00 00:00:00','$bytes_received','$bytes_sent')"
##set status online to user connected
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE user SET user_online='yes' WHERE user_id='$common_name'"
vim /etc/openvpn/scripts/disconnect.sh
#!/bin/bash
. /etc/openvpn/scripts/config.sh
##set status offline to user disconnected
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE user SET user_online='no' WHERE user_id='$common_name'"
##insert data disconnected to table log
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE log SET log_end_time=now(),log_received='$bytes_received',log_send='$bytes_sent' WHERE log_trusted_ip='$trusted_ip' AND log_trusted_port='$trusted_port' AND user_id='$common_name' AND log_end_time='0000-00-00 00:00:00'"
Change the permission of the files we just created
chmod 755 /etc/openvpn/scripts/*.sh
Create the password file for accessing OpenVPN management interface via telnet
echo "wYYoFlaQa8nGQoO8" > /etc/openvpn/pw-management-file
chmod 600 /etc/openvpn/pw-management-file
Configure OpenVPN
vim /etc/openvpn/vpn.example.org.conf
##general settings
port 1194
proto udp
dev tun

##keys
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/vpn.example.org.crt
key /etc/openvpn/keys/vpn.example.org.key
dh /etc/openvpn/keys/dh2048.pem

##FIXME: ip for the clients
server 10.0.1.0 255.255.255.0
ifconfig-pool-persist ipp.txt
##FIXME: routes pushed to the client
push "route 172.16.1.0 255.255.255.0"
push "route 10.0.0.0 255.0.0.0"
push "route 195.248.229.19 255.255.255.255"

##Auth
comp-lzo
user nobody
#group nogroup
client-to-client
#client-cert-not-required
username-as-common-name

##user/pass auth from mysql
plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn

##script connect-disconnect
script-security 3 system
client-connect /etc/openvpn/scripts/connect.sh
client-disconnect /etc/openvpn/scripts/disconnect.sh

##management
management localhost 1194 pw-management-file

keepalive 10 120
persist-key
persist-tun
status status.log
verb 3
Start OpenVPN
/etc/init.d/openvpn start
----------------------------------


openvpn是一种搭建非常简单,并且穿透能力极强的SSLVPN,使用TLS作为会话握手机制,握手成功之后会建立非常安全的SSL隧道,并且有TCP和UDP两种模式可选,没有IPSECVPN等同IP穿透和连接数等烦恼的限制,同一个IP最大可连接数量可达512个,正因为OPENVPN使用起来如此方便并且广泛的原因,所以在国内也受到了相当强大的干扰。

那么,有没有稳定使用它的方法呢?虽然现在有更稳定的shadowsocks等代理方式,但是shadowsocks可没有和VPN一样的组建局域网的功能呀。

有,现在呢我就分享一下我稳定使用openvpn的方式。

一.在windows桌面系统的方案。

1.可以使用openvpn over shadowsocks的方式来解决,不过这也要求openvpn需要使用tcp模式才可以,方法很简单,导入openvpn配置文件之后,用管理员程序运行客户端,然后再打开shadowsocks客户端,设置好shadowsocks。

再然后,在任务栏鼠标右击,选择settings,找到弹出窗口中的proxy选择,选择自定义proxy,类型为socks,端口就是shadowsocks本地代理那里填写的1080,填写好,保存确定,保持shadowsocks客户端开启,此时就可以连接openvpn了,感受下,是不是不会被阻断呢?

2.忽略RST。
如果你的电脑是在linux下,在linux下连接openvpn的话,完全可以使用iptables忽略RST的方式进行连接,只不过需要你的服务器是自己的可以操作。(因为需要双方都忽略)。


3.手机端可以用的方式
同上,把iptables规则写成一个.sh结尾的脚本放到手机里,用RE管理器打开执行就好。(需要ROOT,并且每次重启需要连接openvpn的时候都需要执行一次)(双方忽略RST)

双方忽略之后就可以成功连上了,再也不会有任何ERROR。

此外,openwrt等路由器有ssh权限的话也可以通过双方忽略RST包的方式来连接OPENVPN,起码不会被干扰。(要是因为电信等QOS原因的话我也没办法,你需要选择合适的线路才可以达到夜夜满速)
--------------------------
网络优化配置

OpenVPN官方有一篇优化文章,但是针对LAN。另外还有一篇优化文章
(http://web.archive.org/web/20130424012150/http://www.lostriver.net/efficiency-problem-on-win32-openvpn/)
比较有用。总结而言,就是在server.conf中加上(根据ipv4v4或ipv6自选):
#Tweak for ipv4
mssfix 1472
#Tweak for ipv6
#mssfix 1432
客户端配置文件加上:
#Tweak
rcvbuf 65536
 (这样修改过2边的配置文件后,客户端连上openvpn server的速度果然是大大提升)
常见问题1:无法链接OpenVPN服务器,确认是系统iptables挡住了。
编辑/etc/sysconfig/iptables
在适当位置加上:
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
常见问题2:如果确认OpenVPN已经正常运行且正常连接情况下,如果无法连接外网,但可以连接内网,则可能是iptables问题。
停止OpenVPN:
/etc/init.d/openvpn stop
编辑/etc/sysconfig/iptables
在适当位置加上:
-A INPUT -i tun+ -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
-A FORWARD -i tun+ -o eth0 -j ACCEPT
重启iptables:service iptables restart
启动openvpn:
/etc/init.d/openvpn start
----------------

https://www.linode.com/docs/networking/vpn/secure-communications-with-openvpn-on-ubuntu-10-04-lucid/
 https://www.linode.com/docs/networking/vpn/secure-communications-with-openvpn-on-ubuntu-10-04-lucid/#sph_installing-openvpn

----------------

安装openvpn

If you want more than just pre-shared keys OpenVPN makes it easy to setup and use a Public Key Infrastructure (PKI) to use SSL/TLS certificates for authentication and key exchange between the VPN server and clients. OpenVPN can be used in a routed or bridged VPN mode and can be configured to use either UDP or TCP. The port number can be configured as well, but port 1194 is the official one. And it is only using that single port for all communication. VPN client implementations are available for almost anything including all Linux distributions, OS X, Windows and OpenWRT based WLAN routers.

Server Installation

To install openvpn in a terminal enter:
sudo apt-get install openvpn

Public Key Infrastructure Setup

The first step in building an OpenVPN configuration is to establish a PKI (public key infrastructure). The PKI consists of:
  • a separate certificate (also known as a public key) and private key for the server and each client, and
  • a master Certificate Authority (CA) certificate and key which is used to sign each of the server and client certificates.
OpenVPN supports bidirectional authentication based on certificates, meaning that the client must authenticate the server certificate and the server must authenticate the client certificate before mutual trust is established.
Both server and client will authenticate the other by first verifying that the presented certificate was signed by the master certificate authority (CA), and then by testing information in the now-authenticated certificate header, such as the certificate common name or certificate type (client or server).

Certificate Authority Setup

To setup your own Certificate Authority (CA) and generating certificates and keys for an OpenVPN server and multiple clients first copy the easy-rsa directory to /etc/openvpn. This will ensure that any changes to the scripts will not be lost when the package is updated. From a terminal change to user root and:
mkdir /etc/openvpn/easy-rsa/
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
Next, edit /etc/openvpn/easy-rsa/vars adjusting the following to your environment:
export KEY_COUNTRY="US"
export KEY_PROVINCE="NC"
export KEY_CITY="Winston-Salem"
export KEY_ORG="Example Company"
export KEY_EMAIL="steve@example.com"
Enter the following to generate the master Certificate Authority (CA) certificate and key:
cd /etc/openvpn/easy-rsa/
source vars
./clean-all
./build-ca

Server Certificates

Next, we will generate a certificate and private key for the server:
./build-key-server myservername
As in the previous step, most parameters can be defaulted. Two other queries require positive responses, “Sign the certificate? [y/n]” and “1 out of 1 certificate requests certified, commit? [y/n]“.
Diffie Hellman parameters must be generated for the OpenVPN server:
./build-dh
All certificates and keys have been generated in the subdirectory keys/. Common practice is to copy them to /etc/openvpn/:
cd keys/
cp myservername.crt myservername.key ca.crt dh1024.pem /etc/openvpn/

Client Certificates

The VPN client will also need a certificate to authenticate itself to the server. Usually you create a different certificate for each client. To create the certificate, enter the following in a terminal while being user root:
cd /etc/openvpn/easy-rsa/
source vars
./build-key client1
Copy the following files to the client using a secure method:
  • /etc/openvpn/ca.crt
  • /etc/openvpn/easy-rsa/keys/client1.crt
  • /etc/openvpn/easy-rsa/keys/client1.key
As the client certificates and keys are only required on the client machine, you should remove them from the server.

Simple Server Configuration

Along with your OpenVPN installation you got these sample config files (and many more if if you check):
root@server:/# ls -l /usr/share/doc/openvpn/examples/sample-config-files/
total 68
-rw-r--r-- 1 root root 3427 2011-07-04 15:09 client.conf
-rw-r--r-- 1 root root 4141 2011-07-04 15:09 server.conf.gz
Start with copying and unpacking server.conf.gz to /etc/openvpn/server.conf.
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
Edit /etc/openvpn/server.conf to make sure the following lines are pointing to the certificates and keys you created in the section above.
ca ca.crt
cert myservername.crt
key myservername.key
dh dh1024.pem
That is the minimum you have to configure to get a working OpenVPN server. You can use all the default settings in the sample server.conf file. Now start the server. You will find logging and error messages in your syslog.
root@server:/etc/openvpn# /etc/init.d/openvpn start
 * Starting virtual private network daemon(s)...
   *   Autostarting VPN 'server'                     [ OK ]
Now check if OpenVPN created a tun0 interface:
root@server:/etc/openvpn# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
[...]

Simple Client Configuration

There are various different OpenVPN client implementations with and without GUIs. You can read more about clients in a later section. For now we use the OpenVPN client for Ubuntu which is the same executable as the server. So you have to install the openvpn package again on the client machine:
sudo apt-get install openvpn
This time copy the client.conf sample config file to /etc/openvpn/.
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/
Copy the client keys and the certificate of the CA you created in the section above to e.g. /etc/openvpn/ and edit /etc/openvpn/client.conf to make sure the following lines are pointing to those files. If you have the files in /etc/openvpn/ you can omit the path.
ca ca.crt
cert client1.crt
key client1.key
And you have to at least specify the OpenVPN server name or address. Make sure the keyword client is in the config. That’s what enables client mode.
client
remote vpnserver.example.com 1194
Now start the OpenVPN client:
root@client:/etc/openvpn# /etc/init.d/openvpn start
 * Starting virtual private network daemon(s)...
   *   Autostarting VPN 'client'                          [ OK ]
Check if it created a tun0 interface:
root@client:/etc/openvpn# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.8.0.6  P-t-P:10.8.0.5  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
Check if you can ping the OpenVPN server:
root@client:/etc/openvpn# ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_req=1 ttl=64 time=0.920 ms
The OpenVPN server always uses the first usable IP address in the client network and only that IP is pingable. E.g. if you configured a /24 for the client network mask, the .1 address will be used. The P-t-P address you see in the ifconfig output above is usually not answering ping requests.
Check out your routes:
root@client:/etc/openvpn# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.8.0.5        0.0.0.0         255.255.255.255 UH        0 0          0 tun0
10.8.0.1        10.8.0.5        255.255.255.255 UGH       0 0          0 tun0
192.168.42.0    0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0         192.168.42.1    0.0.0.0         UG        0 0          0 eth0

First trouble shooting

If the above didn’t work for you, check this:
  • Check your syslog, e.g. grep -i vpn /var/log/syslog
  • Can the client connect to the server machine? Maybe a firewall is blocking access? Check syslog on server.
  • Client and server must use same protocol and port, e.g. UDP port 1194, see port and proto config option
  • Client and server must use same config regarding compression, see comp-lzo config option
  • Client and server must use same config regarding bridged vs routed mode, see server vs server-bridge config option

Advanved configuration

Advanced routed VPN configuration on server

The above is a very simple working VPN. The client can access services on the VPN server machine through an encrypted tunnel. If you want to reach more servers or anything in other networks, push some routes to the clients. E.g. if your company’s network can be summarized to the network 192.168.0.0/16, you could push this route to the clients. But you will also have to change the routing for the way back – your servers need to know a route to the VPN client-network.
Or you might push a default gateway to all the clients to send all their internet traffic to the VPN gateway first and from there via the company firewall into the internet. This section shows you some possible options.
Push routes to the client to allow it to reach other private subnets behind the server. Remember that these private subnets will also need to know to route the OpenVPN client address pool (10.8.0.0/24) back to the OpenVPN server.
push "route 10.0.0.0 255.0.0.0"
If enabled, this directive will configure all clients to redirect their default network gateway through the VPN, causing all IP traffic such as web browsing and and DNS lookups to go through the VPN (the OpenVPN server machine or your central firewall may need to NAT the TUN/TAP interface to the internet in order for this to work properly).
push "redirect-gateway def1 bypass-dhcp"
Configure server mode and supply a VPN subnet for OpenVPN to draw client addresses from. The server will take 10.8.0.1 for itself, the rest will be made available to clients. Each client will be able to reach the server on 10.8.0.1. Comment this line out if you are ethernet bridging.
server 10.8.0.0 255.255.255.0
Maintain a record of client to virtual IP address associations in this file. If OpenVPN goes down or is restarted, reconnecting clients can be assigned the same virtual IP address from the pool that was previously assigned.
ifconfig-pool-persist ipp.txt
Push DNS servers to the client.
push "dhcp-option DNS 10.0.0.2"
push "dhcp-option DNS 10.1.0.2"
Allow client to client communication.
client-to-client
Enable compression on the VPN link.
comp-lzo
The keepalive directive causes ping-like messages to be sent back and forth over the link so that each side knows when the other side has gone down. Ping every 1 second, assume that remote peer is down if no ping received during a 3 second time period.
keepalive 1 3
It’s a good idea to reduce the OpenVPN daemon’s privileges after initialization.
user nobody
group nogroup
OpenVPN 2.0 includes a feature that allows the OpenVPN server to securely obtain a username and password from a connecting client, and to use that information as a basis for authenticating the client. To use this authentication method, first add the auth-user-pass directive to the client configuration. It will direct the OpenVPN client to query the user for a username/password, passing it on to the server over the secure TLS channel.
# client config!
auth-user-pass
This will tell the OpenVPN server to validate the username/password entered by clients using the login PAM module. Useful if you have centralized authentication with e.g. Kerberos.
plugin /usr/lib/openvpn/openvpn-auth-pam.so login
Please read the OpenVPN hardening security guide for further security advice.

Advanced bridged VPN configuration on server

OpenVPN can be setup for either a routed or a bridged VPN mode. Sometimes this is also referred to as OSI layer-2 versus layer-3 VPN. In a bridged VPN all layer-2 frames – e.g. all ethernet frames – are sent to the VPN partners and in a routed VPN only layer-3 packets are sent to VPN partners. In bridged mode all traffic including traffic which was traditionally LAN-local like local network broadcasts, DHCP requests, ARP requests etc. are sent to VPN partners whereas in routed mode this would be filtered.

Prepare interface config for bridging on server

Make sure you have the bridge-utils package installed:
sudo apt-get install bridge-utils
Before you setup OpenVPN in bridged mode you need to change your interface configuration. Let’s assume your server has an interface eth0 connected to the internet and an interface eth1 connected to the LAN you want to bridge. Your /etc/network/interfaces would like this:
auto eth0
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.248
  default 1.2.3.1

auto eth1
iface eth1 inet static
  address 10.0.0.4
  netmask 255.255.255.0
This straight forward interface config needs to be changed into a bridged mode like where the config of interface eth1 moves to the new br0 interface. Plus we configure that br0 should bridge interface eth1. We also need to make sure that interface eth1 is always in promiscuous mode – this tells the interface to forward all ethernet frames to the IP stack.
auto eth0
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.248
  default 1.2.3.1

auto eth1
iface eth1 inet manual
  up ip link set $IFACE up promisc on

auto br0
iface br0 inet static
  address 10.0.0.4
  netmask 255.255.255.0
  bridge_ports eth1
At this point you need to restart networking. Be prepared that this might not work as expected and that you will lose remote connectivity. Make sure you can solve problems having local access.
sudo /etc/init.d/network restart

Prepare server config for bridging

Edit /etc/openvpn/server.conf changing the following options to:
;dev tun
dev tap
up "/etc/openvpn/up.sh br0 eth1"
;server 10.8.0.0 255.255.255.0
server-bridge 10.0.0.4 255.255.255.0 10.0.0.128 10.0.0.254
Next, create a helper script to add the tap interface to the bridge and to ensure that eth1 is promiscuous mode. Create /etc/openvpn/up.sh:
#!/bin/sh

BR=$1
ETHDEV=$2
TAPDEV=$3

/sbin/ip link set "$TAPDEV" up
/sbin/ip link set "$ETHDEV" promisc on
/sbin/brctl addif $BR $TAPDEV
Then make it executable:
sudo chmod 755 /etc/openvpn/up.sh
After configuring the server, restart openvpn by entering:
sudo /etc/init.d/openvpn restart

Client Configuration

First, install openvpn on the client:
sudo apt-get install openvpn
Then with the server configured and the client certificates copied to the /etc/openvpn/ directory, create a client configuration file by copying the example. In a terminal on the client machine enter:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn
Now edit /etc/openvpn/client.conf changing the following options:
dev tap
;dev tun
Finally, restart openvpn:
sudo /etc/init.d/openvpn restart
You should now be able to connect to the remote LAN through the VPN.

Client software implementations

Linux Network-Manager GUI for OpenVPN

Many Linux distributions including Ubuntu desktop variants come with Network Manager, a nice GUI to configure your network settings. It also can manage your VPN connections. Make sure you have package network-manager-openvpn installed. Here you see that the installation installs all other required packages as well:
root@client:~# apt-get install network-manager-openvpn
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  liblzo2-2 libpkcs11-helper1 network-manager-openvpn-gnome openvpn
Suggested packages:
  resolvconf
The following NEW packages will be installed:
  liblzo2-2 libpkcs11-helper1 network-manager-openvpn
  network-manager-openvpn-gnome openvpn
0 upgraded, 5 newly installed, 0 to remove and 631 not upgraded.
Need to get 700 kB of archives.
After this operation, 3,031 kB of additional disk space will be used.
Do you want to continue [Y/n]?
To inform network-manager about the new installed packages you will have to restart it:
root@client:~# restart network-manager
network-manager start/running, process 3078
Open the Network Manager GUI, select the VPN tab and then the ‘Add’ button. Select OpenVPN as the VPN type in the opening requester and press ‘Create’. In the next window add the OpenVPN’s server name as the ‘Gateway’, set ‘Type’ to ‘Certificates (TLS)’, point ‘User Certificate’ to your user certificate, ‘CA Certificate’ to your CA certificate and ‘Private Key’ to your private key file. Use the advanced button to enable compression or other special settings you set on the server. Now try to establish your VPN.

OpenVPN with GUI for Mac OS X: Tunnelblick

Tunnelblick is an excellent free, open source implementation of a GUI for OpenVPN for OS X. The project’s homepage is at http://code.google.com/p/tunnelblick/. Download the latest OS X installer from there and install it. Then put your client.ovpn config file together with the certificates and keys in /Users/username/Library/Application Support/Tunnelblick/Configurations/ and lauch Tunnelblick from your Application folder.
# sample client.ovpn for Tunnelblick
client
remote blue.example.com
port 1194
proto udp
dev tun
dev-type tun
ns-cert-type server
reneg-sec 86400
auth-user-pass
auth-nocache
auth-retry interact
comp-lzo yes
verb 3
ca ca.crt
cert client.crt
key client.key

OpenVPN with GUI for Win 7

First download and install the latest OpenVPN Windows Installer. OpenVPN 2.2.1 was the latest when this was written. Additionally download an alternative Open VPN Windows GUI. The OpenVPN MI GUI from http://openvpn-mi-gui.inside-security.de seems to be a nice one for Windows 7. Download the latest version. 20110624 was the latest version when this was written.
You need to start the OpenVPN service. Goto Start > Computer > Manage > Services and Applications > Services. Find the OpenVPN service and start it. Set it’s startup type to automatic. When you start the OpenVPN MI GUI the first time you need to run it as an administrator. You have to right click on it and you will see that option.
You will have to write your OpenVPN config in a textfile and place it in C:\Program Files\OpenVPN\config\client.ovpn along with the CA certificate. You could put the user certificate in the user’s home directory like in the follwing example.
# C:\Program Files\OpenVPN\config\client.ovpn
client
remote server.example.com
port 1194
proto udp
dev tun
dev-type tun
ns-cert-type server
reneg-sec 86400
auth-user-pass
auth-retry interact
comp-lzo yes
verb 3
ca ca.crt
cert "C:\\Users\\username\\My Documents\\openvpn\\client.crt"
key "C:\\Users\\username\\My Documents\\openvpn\\client.key"
management 127.0.0.1 1194
management-hold
management-query-passwords
auth-retry interact

OpenVPN for OpenWRT

OpenWRT is described as a Linux distribution for embedded devices like WLAN router. There are certain types of WLAN routers who can be flashed to run OpenWRT. Depending on the available memory on your OpenWRT router you can run software like OpenVPN and you could for example build a small inexpensive branch office router with VPN connectivity to the central office. More info on OpenVPN on OpenWRT is here. And here is the OpenWRT project’s homepage: http://openwrt.org
Log into your OpenWRT router and install OpenVPN:
opkg update
opkg install openvpn
Check out /etc/config/openvpn and put you client config in there. Copy certificated and keys to /etc/openvpn/
config openvpn client1
        option enable 1
        option client 1
#       option dev tap
        option dev tun
        option proto udp
        option ca /etc/openvpn/ca.crt
        option cert /etc/openvpn/client.crt
        option key /etc/openvpn/client.key
        option comp_lzo 1
Restart OpenVPN:
/etc/init.d/openvpn restart
You will have to see if you need to adjust your router’s routing and firewall rules.

References

------------
http://colekcolek.com/2011/07/21/how-to-install-openvpn-in-ubuntu-11-04/ ,这个仅供参考。
http://archive.is/wP8J7
------------

https://github.com/dustinmhorvath/EasyOpenVPN
-------------

openvpn实现用户名/密码登陆

0x00 openvpn安装

网上教程一堆,这里采用懒人傻瓜式安装方式,感谢大佬的脚本:https://github.com/Nyr/openvpn-install.
bash openvpn-install.sh
然后一路回车不到一分钟即可搭建好一个openVPN服务器。。。

0x01 服务端配置

在server.conf中添加如下内容
vim /etc/openvpn/server.conf







1
2
3
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
username-as-common-name
script-security 3 execve
在/etc/openvpn目录下添加文件checkpsw.sh:
vim /etc/openvpn/checkpsw.sh







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/sh
###########################################################
#checkpsw.sh (C) 2004 Mathias Sundman 
#
# 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="/etc/openvpn/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 755 /etc/openvpn/checkpsw.sh
在/etc/openvpn目录下添加用户名密码文件psw-file:
vim /etc/openvpn/psw-file







1
2
user1 pass1 # 用户名 密码以空格隔开
user2 pass2
安全起见设成只读:
chmod 400 /etc/openvpn/psw-file
重启服务:
service openvpn restart

0x02 客户端配置

在服务器安装openvpn时生成的client.ovpn末尾加入一行:







1
auth-user-pass
重新导入openvpn GUI即可使用用户名密码登陆.

0x03 坑点

使用openvpn-install.sh安装时,选择TCP(默认)方式无法使用用户名密码登陆,选择UDP则没有问题。
-------


一个基于openvpn的vpn程序:diy-vpn

Install

Clone the repo, cd into it, and sudo bash install.sh.
This will download and install OpenVPN and easy-rsa. Then it will build the public-key infrastructure (PKI), create a certificate authority (CA), generate a key and sign a certificate for the VPN server. You'll be prompted for CA and server passwords during this process. Finally, it will enable IP forwarding and NAT routing on the host.

Usage

Configure

If clients will be using client.conf, you'll need to replace  (L42) with the hostname or address of your VPN server. You can modify other configuration options in client.conf and server.conf if you feel so inclined.

Add a client

To generate credentials for a client, cd into the project directory on the host and run the following command:
$ sudo bash add-client.sh 
This creates a directory with client.conf, the CA certificate, a private key and certificate for the client. Then it zips and encrypts the directory with a password you provide.
The client will need to get the encrypted zip file clients/.zip. If you have SSH access to the VPN host, sftp should work.
Once the file's on the client device, run the following commands:
$ unzip -d ~ .zip
$ rm .zip
Now you can find the client files at ~/openvpn.

Start the VPN server

We can run diy-vpn as a systemd service:
$ sudo systemctl start diy-vpn
$ sudo systemctl stop diy-vpn
$ sudo systemctl restart diy-vpn

Remove a client

Run the following command:
$ sudo bash remove-client.sh 
This removes the .zip file from the clients directory and revokes the client certificate so it can no longer authenticate with the VPN server.

Connect the client

Make sure you've added the client first!

On macOS

Download and install Tunnelblick if you haven't already.
Then drag-and-drop the client.conf file into "Configurations" on the left side of the app window. Tunnelblick should ask you a few questions and install the client configuration.

On Ubuntu

First, you'll want to install the Network Manager for OpenVPN.
$ sudo apt install network-manager-openvpn-gnome
  1. Open "Settings" and click on "Network"
  2. Add (+) a VPN and select the "OpenVPN" option
  3. Name the VPN whatever you want
  4. Under "General", enter the address/hostname of the VPN server for "Gateway"
  5. Under "Authentication", choose the "CA certificate" ~/openvpn/ca.crt
  6. Choose the "User certificate" ~/openvpn/client.crt
  7. Choose the "User private key" ~/openvpn/private/client.key
  8. You can save your "User key password" or click the (?) on the right and select another option (e.g. "Ask for this password every time")
  9. Click "Advanced" and then "TLS Authentication"
  10. Under "Additional TLS authentication or encryption", select "TLS-crypt" for "Mode"
  11. Choose ~/openvpn/private/ta.key for "Key file"
  12. Select 1 for "Key Direction" and click OK!

You should be able to connect to your VPN now!
from https://github.com/zbo14/diy-vpn
--------------------------------

OpenVPN设置条件代理的方法

route命令第一参数为IP地址,第二地址为网子掩码,位与得到网段。
下面我们以SHUVPN为例:

如何设置条件代理

  • 假设我们在vpn.shu.edu.cn下载了一个ovpn文件,并且修改ovpn文件添加如下一行:
route-nopull
​ 命令解释:不从服务端拉取代理配置。

  • 如果我们修改ovpn文件添加如下一行:
route 202.120.127.0 255.255.255.0 vpn_gateway
​ 命令解释:将202.120.127.*设置为使用OpenVPN代理。

如何设置代理例外

  • 如果我们修改ovpn文件添加如下第二行:
route 202.120.127.0 255.255.255.0 vpn_gateway
route 202.120.127.105 255.255.255.255 net_gateway
​ 命令解释:将202.120.127.*设置为OpenVPN代理,但202.120.127.105走本地网络(202.120.127.105是我们VPN连接的目标服务器的IP地址,应该加入例外)。

一个SHUVPN的条件代理demo






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
client
dev tun
proto tcp

remote 202.120.127.105 80

comp-lzo
resolv-retry infinite
nobind
persist-key
persist-tun
setenv CLIENT_CERT 0
auth-user-pass
remote-cert-tls server
verb 3

sndbuf 0
rcvbuf 0
cipher none

route-nopull
route 10.95.192.1 255.255.255.255 vpn_gateway
route 9.9.9.2  255.255.255.255 vpn_gateway
route 10.105.3.129 255.255.255.255 vpn_gateway
route 172.16.255.253 255.255.255.255 vpn_gateway
#route 172.31.0.0 255.255.0.0 vpn_gateway
route 202.120.0.0 255.255.0.0 vpn_gateway
route 202.121.0.0 255.255.0.0 vpn_gateway
route 202.120.127.105 255.255.255.255 net_gateway


-----BEGIN CERTIFICATE-----
MIIEoTCCA4mgAwIBAgIJAMW52H83M9JAMA0GCSqGSIb3DQEBCwUAMIGRMQswCQYD
VQQGEwJDTjELMAkGA1UECBMCU0gxETAPBgNVBAcTCFNoYW5nSGFpMQwwCgYDVQQK
EwNTSFUxDDAKBgNVBAsTA1NIVTEPMA0GA1UEAxMGU0hVIENBMRAwDgYDVQQpEwdF
YXN5UlNBMSMwIQYJKoZIhvcNAQkBFhRyb2RkeTE5ODZAc2h1LmVkdS5jbjAeFw0x
NzA2MjEwOTQwMjlaFw0yNzA2MTkwOTQwMjlaMIGRMQswCQYDVQQGEwJDTjELMAkG
A1UECBMCU0gxETAPBgNVBAcTCFNoYW5nSGFpMQwwCgYDVQQKEwNTSFUxDDAKBgNV
BAsTA1NIVTEPMA0GA1UEAxMGU0hVIENBMRAwDgYDVQQpEwdFYXN5UlNBMSMwIQYJ
KoZIhvcNAQkBFhRyb2RkeTE5ODZAc2h1LmVkdS5jbjCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAJ17qOLBJgX7DKsBxVhqpfYkZcPwy8DggDiwRHNLLP3h
aEWRcS5NViqGthWh4mWvVkD9RypYlUywbYewoSkuLyllsFuw+iZUR93cWGMjccq/
9ZdhVPpYCGRJrtkTNeVtU9XTXEjZ3vWEwAMpOcVdhLQz6kxCVTt2qrB4ClhIAdPh
jaz5tusNlwVGzaM7EMIr3O08Y8gYlAe78tkD+18uCMYIyKPORs9H31UHbreLcONv
4Lc3dOz/g4KOQTkuwqcRnTJN1AVVfpjFUQeabyxFV/u4BkSvU33HWxLzYiyDGZkU
W8PLr1mouNEXWGHxfhooZb9wozk+jfuLYk3KhKh9+ZMCAwEAAaOB+TCB9jAdBgNV
HQ4EFgQU2sjeWJZf5o/1eL1Ke5PyE7K1nw4wgcYGA1UdIwSBvjCBu4AU2sjeWJZf
5o/1eL1Ke5PyE7K1nw6hgZekgZQwgZExCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJT
SDERMA8GA1UEBxMIU2hhbmdIYWkxDDAKBgNVBAoTA1NIVTEMMAoGA1UECxMDU0hV
MQ8wDQYDVQQDEwZTSFUgQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExIzAhBgkqhkiG9w0B
CQEWFHJvZGR5MTk4NkBzaHUuZWR1LmNuggkAxbnYfzcz0kAwDAYDVR0TBAUwAwEB
/zANBgkqhkiG9w0BAQsFAAOCAQEATqu24naX9L6jyzXt+mBJAS5IWr7gfh5Ymi7X
Tl+uSXS+H0w7VYqSGsrQsd17U9RfcAxglhGx2FtYvuYVWHQ4InaUjbrzxDrFO+ZG
rN471ASybovHR97rHfPOnqigAbDaKLynb8JoFYkzAxRAclPh/jZFXpG06KC+fkW/
ox+1WKF/6d5gXOZOTf0GuJi4JHRojDzb5p/Z6/8gxE9krVsQmfiR3HnaegyTVMle
KzpCQRuEx5rn/uDvV6joYCwy4q0BkQTKGBeUofR2ETlTeC7t6l+GKRPwCQ8BeBvL
e0+RSP6QWl/+flS0qdmtSswuZF98OqAuu6wW2PHXB3auUn77nw==
-----END CERTIFICATE-----

思路:linux下挂上全局OpenVPN,使用traceroute命令访问被教育网墙掉的几个网站,记录经过的几个IP地址,逐一添加到条件代理中去。经查询,202.120.112~202.120.127段与202.121.192~202.121.199是SHU的公网段。由于202.120.127.105是目标服务器IP地址,因此加入例外,否则OpenVPN将无法正常工作。

Linux下添加开机自启






1
sudo openvpn --daemon --config ~/shu.ovpn --auth-user-pass ~/pass.txt
使用上述命令可以启动OpenVPN的守护进程,其中pass.txt文件保存了连接所需的账号密码,第一行为账号,第二行为密码,两处文件路径均需完整路径。
linux版本不同方法也不同,有的linux版本自启时没有su权限,使用sudo会无法进入图形界面(好像是Fedora),下面仅以deepin为例(debian系):
使用systemd执行rc.local
在使用了systemd作为启动器的系统(如较新版的deepin)中,默认不包含rc.local文件。此时请在/etc目录下以管理员权限创建一个名为rc.local的纯文本文件,并写入如下内容:





1
2
3
4
5
6
7
> #!/bin/bash
> # rc.local config file created by use
>
> 把你需要执行的命令写在这里 
>
> exit 0
>
保存后,赋予该文件可执行权限:sudo chmod +x /etc/rc.local。下次重启时,systemd就会自动执行rc.local里面的命令了
因此我们如法炮制,把sudo openvpn --daemon --config ~/shu.ovpn --auth-user-pass ~/pass.txt写入即可(deepin自启有su权限,故可以加sudo)。
Shell中敲入reboot回车,一切明朗
------------------

OpenVPN笔记-01


最近有使用OpenVPN的场景,就研究了下OpenVPN的运行原理和部署方案,这里稍做记录,当作一个备用方案。

安装与配置OpenVPN服务端

服务端为Debian 10,其他发行版如Ubuntu 20.04和CentOS 7,也都一键就可以安装OpenVPN,版本都为2.4.xx。这里使用tap模式,用户名密码认证,且使用临时文件验证

安装后创建配置文件 /etc/openvpn/server/tap0.conf,内容如下:

# 监听443端口
port 443
# 使用TCP作为传输方式,客户端会在一个TCP连接上承载所有流量
proto tcp
# 使用TAP模式
dev tap
# 设置MTU为1500
tun-mtu 1500
# 设置拓扑结构为子网
topology subnet
# 设置VPN网段,转换为CIDR格式对应10.100.0.0/24
server 10.100.0.0 255.255.255.0
# 客户端配置文件,若需要为客户端分配固定IP可以在此设置,按用户名(或CN)存放文件
# client-config-dir /etc/openvpn/ccd
# 自签名的根证书
ca /etc/openvpn/server/ca.crt
# 自签名的服务端证书
cert /etc/openvpn/server/server.crt
# 自签名的服务端密钥
key /etc/openvpn/server/server.key
# dh交换参数
dh /etc/openvpn/server/dh2048.pem
tls-server
tls-version-min 1.2
# 认证方式设置
verify-client-cert none
# 使用用户名作为CN
username-as-common-name
# 设置脚本安全等级,等级2允许通过文件传递认证信息
script-security 2
# 使用临时文件验证,用户名和密码保存在临时文件中,作为参数传给可执行文件
auth-user-pass-verify /etc/openvpn/server/verify via-file
# others
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
# 状态文件,在此文件中可查看已连接的客户端信息
status /var/log/openvpn/openvpn-status.log
# 日志文件
log-append  /var/log/openvpn/openvpn.log
verb 3

使用openssl生成随机的账号密码和配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
username=$(openssl rand -hex 16)
password=$(openssl rand -hex 16)
filename=$(echo -n $uaername|md5sum|awk '{print $1}')
mkdir -p /etc/openvpn/server/verify-ccd
cat << EOF > /etc/openvpn/server/verify-ccd/$filename
$password
EOF
echo "username $username"
echo "password $password"
echo "file $filename"

启动服务:

1
systemctl enable --now openvpn-server@tap0

检查网卡与日志:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
➜  ip addr show tap0
64: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UNKNOWN group default qlen 100
    link/ether 5e:17:fa:5a:82:3a brd ff:ff:ff:ff:ff:ff
    inet 10.100.0.1/24 brd 10.100.0.255 scope global tap0
       valid_lft forever preferred_lft forever
    inet6 fe80::5c17:faff:fe5a:823a/64 scope link
       valid_lft forever preferred_lft forever
➜  ~ tail /var/log/openvpn/openvpn.log
/sbin/ip addr add dev tap0 10.100.0.1/24 broadcast 10.100.0.255
Could not determine IPv4/IPv6 protocol. Using AF_INET
Socket Buffers: R=[87380->87380] S=[65536->65536]
Listening for incoming TCP connection on [AF_INET][undef]:443
TCPv4_SERVER link local (bound): [AF_INET][undef]:443
TCPv4_SERVER link remote: [AF_UNSPEC]
MULTI: multi_init called, r=256 v=256
IFCONFIG POOL: base=10.100.0.2 size=253, ipv6=0
MULTI: TCP INIT maxclients=1024 maxevents=1028
Initialization Sequence Completed

3. 安装与配置OpenVPN客户端

tap模式仅支持Linux和安装了tap插件的Windows系统,这里使用Linux演示,客户端也使用Debian 10,安装好openvpn后,创建配置文件 /etc/openvpn/client/tap0.conf,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
client
dev tap
nobind
proto tcp
tun-mtu 1500
remote 服务器IP 服务器端口
cipher AES-256-CBC
# 认证文件,第一行为用户名,第二行为密码
auth-user-pass /etc/openvpn/client/auth.txt
ca /etc/openvpn/client/ca.crt
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append  /var/log/openvpn/openvpn.log

启动服务:

1
systemctl enable --now openvpn-client@tap0

检查网卡与日志:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
➜  ~ ip addr show tap0
66: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UNKNOWN group default qlen 100
    link/ether 8a:2b:21:61:ab:db brd ff:ff:ff:ff:ff:ff
    inet 10.100.0.2/24 brd 10.100.0.255 scope global tap0
       valid_lft forever preferred_lft forever
    inet6 fe80::882b:21ff:fe61:abdb/64 scope link
       valid_lft forever preferred_lft forever
➜  ~ tail /var/log/openvpn/openvpn.log
Attempting to establish TCP connection with [AF_INET]xxx.xxx.xxx.xxx:xxx [nonblock]
TCP connection established with [AF_INET]xxx.xxx.xxx.xxx:xxx
TCP_CLIENT link local: (not bound)
TCP_CLIENT link remote: [AF_INET]xxx.xxx.xxx.xxx:xxx
WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
[Test-Server] Peer Connection Initiated with [AF_INET]xxx.xxx.xxx.xxx:xxx
TUN/TAP device tap0 opened
/sbin/ip link set dev tap0 up mtu 1500
/sbin/ip addr add dev tap0 10.100.0.2/24 broadcast 10.100.0.255
Initialization Sequence Completed

可以看到分配了10.100.0.2的内网IP,测试一下联通性:

1
2
3
4
5
6
➜  ~ ping 10.100.0.1
PING 10.100.0.1 (10.100.0.1) 56(84) bytes of data.
64 bytes from 10.100.0.1: icmp_seq=1 ttl=64 time=391 ms
64 bytes from 10.100.0.1: icmp_seq=2 ttl=64 time=180 ms
64 bytes from 10.100.0.1: icmp_seq=3 ttl=64 time=183 ms
64 bytes from 10.100.0.1: icmp_seq=4 ttl=64 time=181 ms

10.100.0.0/24段的流量默认路由到了tap0,如果需要全局代理,设置默认路由即可.

4. 公网IP绑定与内网服务暴露

上述的配置中,笔者只将VPN作为一个打通内网的工具来使用,如果需要为内网设备绑定外网IP或暴露内网服务到公网时,需要使用iptables设置转发规则。

回到server,查看所有网卡,如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
➜  ~ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 02:00:13:53:00:01 brd ff:ff:ff:ff:ff:ff
    inet 200.59.100.2/24 brd 156.59.100.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 200.59.100.3/24 brd 156.59.100.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet 200.59.100.4/24 brd 156.59.100.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet 200.59.100.5/24 brd 156.59.100.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet 200.59.100.6/24 brd 156.59.100.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
64: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UNKNOWN group default qlen 100
    link/ether 5e:17:fa:5a:82:3a brd ff:ff:ff:ff:ff:ff
    inet 10.100.0.1/24 brd 10.100.0.255 scope global tap0
       valid_lft forever preferred_lft forever
    inet6 fe80::5c17:faff:fe5a:823a/64 scope link
       valid_lft forever preferred_lft forever

假设我们在eth0上绑定了200.59.100.2~200.59.100.6的IP,现在需要将这些IP一对一绑定到10.100.0.2~10.100.0.6的内网设置,且每个设备需要暴露80端口,则执行以下iptables命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 添加1条POSTROUTING上的SNAT规则,让10.100.0.0/24段流量走tap0设备
iptables -t nat -A POSTROUTING -d 10.100.0.0/24 -o tap0 -j SNAT --to-source 10.100.0.1
# 添加5条POSTROUTING上的SNAT规则,一对一绑定出站流量
iptables -t nat -A POSTROUTING -s 10.100.0.2/32 ! -d 10.100.0.0/24 -j SNAT --to-source 200.59.100.2
iptables -t nat -A POSTROUTING -s 10.100.0.3/32 ! -d 10.100.0.0/24 -j SNAT --to-source 200.59.100.3
iptables -t nat -A POSTROUTING -s 10.100.0.4/32 ! -d 10.100.0.0/24 -j SNAT --to-source 200.59.100.4
iptables -t nat -A POSTROUTING -s 10.100.0.5/32 ! -d 10.100.0.0/24 -j SNAT --to-source 200.59.100.5
iptables -t nat -A POSTROUTING -s 10.100.0.6/32 ! -d 10.100.0.0/24 -j SNAT --to-source 200.59.100.6
# 添加5条PREROUTING上的DNAT规则,允许80端口的进站流量
iptables -t nat -A PREROUTING -d 200.59.100.2/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.100.0.2:80
iptables -t nat -A PREROUTING -d 200.59.100.3/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.100.0.3:80
iptables -t nat -A PREROUTING -d 200.59.100.4/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.100.0.4:80
iptables -t nat -A PREROUTING -d 200.59.100.5/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.100.0.5:80
iptables -t nat -A PREROUTING -d 200.59.100.6/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.100.0.6:80

在配置完成后,以 10.100.0.2 设备为例:

  • 访问内网IP:10.100.0.2 -> 10.100.0.1 -> 10.00.0.3
  • 访问外网IP:10.100.0.2 -> 10.100.0.1 -> 200.59.100.2 -> 8.8.8.8
  • 外网访问80端口:8.8.8.8 -> 200.59.100.2:80 -> 10.100.0.1 -> 10.100.0.2:80

OpenVPN笔记-02

1. 前言

最近有时间又研究了下OpenVPN,发现这个老牌VPN还是有许多闪光点,例如:

  • 在用户空间运行,几乎适配所有操作系统
  • 使用OpenSSL加密库的SSL/TLS,能受益于这些标准组件的升级和优化
  • 支持TCP/UDP的方式创建隧道承载上层流量,UDP丢包率高的环境下可以切换TCP,并绕过一些防火墙限制,例如只允许443端口的进出站的环境
  • 支持配置SOCKS代理,能嵌套其他代理工具组合使用

除了配置复杂外(配置是在占了太多),剩下的都是优点,上一篇中讨论了TAP模式的配置,但除了Linux外,其他系统对TAP都不太友好,这里就对比下TAP与TUN,并记录下TUN模式部署方法

2. TAP vs TUN

OpenVPN的维基中已经详细论述了TAP与TUN的区别:BridgingAndRouting

什么情况下需要TAP:

  • 需要桥接
  • 需要在OpenVPN 2.2或更早版本传输非IP流量或IPv6流量
  • 需要LAN和VPN客户端位于同一个广播域中
  • 需要LAN的DHCP服务器为VPN客户端提供DHCP地址
  • 需要访问Windows服务器,并且需要网络邻居发现才能通过VPN工作

TAP看上去似乎比TUN更简洁,但是也带来很多隐藏的问题,下面是两者的优缺点比较:

TAP的优点:

  • 表现得像一个真实的网络适配器
  • 可以传输任何网络协议(IPv4、IPv6、Nettalk、IPX 等)
  • 工作在第2层,以太网帧可通过VPN隧道传递
  • 可用于桥接

TAP的缺点:

  • 在VPN隧道上有更多的广播开销
  • 在VPN隧道传输的所有数据包都会添加以太网数据帧头部造成额外开销
  • 不能用于Android或iOS设备
  • 扩展性差

TUN的优点:

  • 较低的流量开销,仅传输发往VPN客户端的流量
  • 仅传输第3层的IP数据包

TUN 缺点:

  • 无法传输广播流量
  • 只能传输 IPv4(OpenVPN 2.3 增加了 IPv6)
  • 不能用于桥接

综上所述:

  • 只需要使用VPN的代理功能或客户端设备受限于安卓/iOS/macOS等时,可以选择TUN模式
  • 需要更复杂的网络配置时,使用TAP模式,例如UDP广播、公网IP绑定、虚拟机接入VPN等等

3. 安装与配置OpenVPN服务端

安装内容不再赘述,安装后创建配置文件 /etc/openvpn/server/tun0.conf,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 监听443端口
port 443
# 使用TCP作为传输方式,客户端会在一个TCP连接上承载所有流量
proto tcp
# 使用TAP模式
dev tun
# 设置MTU为1500
tun-mtu 1500
# 设置拓扑结构为子网
topology subnet
# 设置VPN网段,转换为CIDR格式对应10.100.0.0/24
server 10.100.0.0 255.255.255.0
# 客户端配置文件,若需要为客户端分配固定IP可以在此设置,按用户名(或CN)存放文件
# client-config-dir /etc/openvpn/ccd
# 自签名的根证书
ca /etc/openvpn/server/ca.crt
# 自签名的服务端证书
cert /etc/openvpn/server/server.crt
# 自签名的服务端密钥
key /etc/openvpn/server/server.key
# dh交换参数
dh /etc/openvpn/server/dh2048.pem
tls-server
tls-version-min 1.2
# 认证方式设置
verify-client-cert none
# 使用用户名作为CN
username-as-common-name
# 设置脚本安全等级,等级2允许通过文件传递认证信息
script-security 2
# 使用临时文件验证,用户名和密码保存在临时文件中,作为参数传给可执行文件
auth-user-pass-verify /etc/openvpn/server/verify via-file
# others
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
# 状态文件,在此文件中可查看已连接的客户端信息
status /var/log/openvpn/openvpn-status.log
# 日志文件
log-append  /var/log/openvpn/openvpn.log
verb 3

启动服务:

1
systemctl enable --now openvpn-server@tun0

检查网卡与日志:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
➜  ip addr show tun0
68: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq state UNKNOWN group default qlen 100
    link/none
    inet 10.100.0.1/24 brd 10.100.0.255 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::741a:7b72:a4d5:74ba/64 scope link flags 800
       valid_lft forever preferred_lft forever
➜  ~ tail /var/log/openvpn/openvpn.log
/sbin/ip addr add dev tun0 10.100.0.1/24 broadcast 10.100.0.255
Could not determine IPv4/IPv6 protocol. Using AF_INET
Socket Buffers: R=[87380->87380] S=[65536->65536]
Listening for incoming TCP connection on [AF_INET][undef]:443
TCPv4_SERVER link local (bound): [AF_INET][undef]:443
TCPv4_SERVER link remote: [AF_UNSPEC]
MULTI: multi_init called, r=256 v=256
IFCONFIG POOL: base=10.100.0.2 size=252, ipv6=0
MULTI: TCP INIT maxclients=1024 maxevents=1028
Initialization Sequence Completed

4. 安装与配置OpenVPN客户端

客户端使用macOS,通过homebrew安装openvpn-connect:

1
brew install --cask openvpn-connect

编写openvpn.opvn配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
client
dev tun
nobind
proto tcp
tun-mtu 1500
remote xxx.xxx.xxx.xxx 443
cipher AES-256-CBC
# 包含账号密码的txt文件位置
auth-user-pass $HOME/auth.txt
persist-key
persist-tun
# 内嵌根证书
<ca>
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
</ca>

将openvpn.ovpn与auth.txt文件放在同一个目录下,然后打开OpenVPN导入配置.

------

OpenVPN是VPN商家防止被墙的主力,OpenVPN防墙有verify-x509-name验证,TLS Crypt v2验证,XOR-Patched VPN混淆等方式。

https://github.com/angristan/openvpn-install 搭建脚本,默认启用verify-x509-name验证

https://github.com/alinhayati/openvpn-install 搭建脚本,添加TLS Crypt v2支持.

openvpn-xor混淆可以参考:

https://blog.tmthecoder.dev

https://github.com/x0r2d2/openvpn-xor

https://github.com/xeon2650/openvpn-xor

支持的xor混淆的客户端:

Windows: https://github.com/lawtancool/openvpn-windows-xor

macOS:https://tunnelblick.net/cOpenvpn_xorpatch.html
Android: https://github.com/lawtancool/ics-openvpn-xor
iOS: https://apps.apple.com/us/app/passepartout-vpn-client/id1433648537

国外主流VPN商家对待封锁都采取了不同的策略,比如VyprVPN基于openvpn修改的Chameleon协议,expressvpn基于WireGuard修改的Lightway协议,不过效果都不算很好。

------------

相关帖子:

https://briteming.blogspot.com/2017/08/openvpncipher.html