由于国内网络被墙的原因,经常访问很多国外技术站点时也会遇到无法打开的情况。刚好手上有AWS一年试用的服务器可用,所以在主机上搭建一个PPTP VPN服务自 用。PPTP VPN本身搭建步骤非常简单,而且直接跨平台使用---windows、linux、MAC、Android、IOS上都可以使用。

一、安装

1、验证内核是否加载了MPPE模块

内核的MPPE模块用于支持Microsoft Point-to-Point Encryption。Windows自带的VPN客户端就是使用这种加密方式,linux内核版本 等于或高于 2.6.15 时,默认 都集成了该功能。可以通过如下命令进行下测试,如果回显OK,则证明已经成功:

1# modprobe ppp-compress-18 && echo MPPE is ok

2、安装软件包

这里以centos为例,默认源里没有该包,可以添加下epel 源。执行如下命令安装:

1# yum -y install ppp pptpd

安装ppp包是增加对ppp协议的支持,提供服务的包是pptpd。另外主机还需要iptable支持,如果主机上没有,还需要安装下iptables。

二、配置

pptpd涉及的配置文件较少,一般我们只修改三个文件pptpd.conf、options.pptpd、chap-secrets

1、pptpd.conf

1# vim /etc/pptpd.conf
2修改如下内容
3option /etc/ppp/options.pptpd
4logwtmp
5localip 192.168.0.1
6remoteip 192.168.0.234-238,192.168.0.245

其中option和logwtmp项默认是开启的,只需增加localip和remoteip即可。VPN可以这样理解,Linux客户端使用一个虚拟网络设备ppp0(Windows客户端也可以理解 成VPN虚拟网卡),连接到服务器的虚拟网络设备ppp0上,这样客户端就加入了服务器端ppp0所在的网络。localip就是可以分配给 服务器端ppp0的IP地址,remoteip则是将要分配给客户端ppp0(或者虚拟网卡)的。 

这两项都可以是多个IP,一般localip设置一个IP就行了,remoteip则视客户端数目,分配一段IP。其中remoteip的IP段需 要和localip的IP段一致。localip和remoteip所处的IP段可以随意些指定,但其范围内不要包含实际网卡的IP地址。

上面的配置示例中,我配置了一个段,外加一个IP。

2、options.pptpd

 1# vim /etc/ppp/options.pptpd
 2name pptpd
 3refuse-pap
 4refuse-chap
 5refuse-mschap
 6require-mschap-v2
 7require-mppe-128
 8ms-dns 8.8.8.8
 9ms-dns 8.8.4.4
10proxyarp
11lock
12nobsdcomp
13novj
14novjccomp
15nologfd

name后面的pptpd是服务名称,可以任意修改成你喜欢的名字,在后面的帐户配置中将对应的pptpd替换为你在这里修改的名字即可。

refuse或者require开头的指令,是配置拒绝和接受的加密方式,这里接受的mschap-v2和mppe-128都是较新的比较安全的加密方式,其中mppe-128需要第一步中验证的内核模块支持。

另外两个比较重要的行就是ms-dns了,它们指定VPN使用的DNS服务器。毕竟VPS位于国外,所以推荐使用上面通用的Google Public DNS,当然也可以修改为你的VPS 所在ISP提供的DNS。

3、chap-secrets

1# vim /etc/ppp/chap-secrets
2# client        server  secret                  IP addresses
3用户名1       pptpd    密码                   *
4用户名2       pptpd    密码                   192.168.0.235

这里需要注意下,server名要和options里配置的name值一样,ip地址如果是*即查用户VPN拨号过来以后可以使用任一地址。如果指定地址的话,VPN拨号过来只能是该地址。

三、开启IP转发和启动服务

1、开启IP转发

可以通过下面的方法开启内核的IP转发功能

1# vim /etc/sysctl.conf
2net.ipv4.ip_forward = 1  -->默认该行为0,修改为1
3# sysctl -p
4上面的方法是重启后依然生效,想要临时生效,重启后还原之前的配置可以通过下面的方法配置:
5# echo '1' > /proc/sys/net/ipv4/ip_forward

2、iptables配置

1iptables -A INPUT -p gre -j ACCEPT
2iptables -A INPUT -p tcp -m tcp --dport 1723 -j ACCEPT
3iptables -A FORWARD -s 192.168.0.0/24 -o eth1 -j ACCEPT
4iptables -A FORWARD -d 192.168.0.0/24 -i eth1 -j ACCEPT
5iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j MASQUERADE
67iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.0/24 -j SNAT --to-source xxx.xxx.xxx.xxx

PPTP使用GRE协议封装PPP数据包,然后封装成IP报文,所以需要允许该协议;1723为pptp服务的端口;使用MASQUERADE这种是IP伪装,使用to-source是nat地址转换,两种任选其一即可,其中后面的IP是主机的公网IP,eth1网卡是公网网卡名。

配置完成后,通过/etc/init.d/iptables save保存当前配置(也可以使用iptables-save > 文件名 保存配置)。

除了上面的配置外,还需特别注意将MTU的值配置为1356,如果不配置会出现VPN可以拨上,而且可以 ping 通外网,但上网速度会 很慢,很多页面打不开的情况,遇到这种情况,可以在iptables里增加如下规则:

1iptables -I FORWARD -p tcp --syn -i ppp0 -j TCPMSS --set-mss 1356
23iptables -A FORWARD -p tcp --syn -s 192.168.0.0/24 -j TCPMSS --set-mss 1356

3、配置服务开机自启动

1# /etc/init.d/pptpd start
2# chkconfig --level 35 pptpd on
3# /etc/init.d/iptables start
4# chkconfig --level 35 iptables on

四、配置VPN连接验证

1、windows主机

这里一台windows7主机为例,打开网络设置---设置新的连接和网络---连接到工作区---使用我的Internet连接(VPN)---并配置VPN服务器上的公网IP

pptpd

这里需要注意的是,如果本身有域名可用,这里是可以配置域名的。配置完成后就是我们熟悉的连接界面了,是不是和pppoe拨号时代的界面很像?本身都是走的ppp协议,当然界面差不多。

vpnpptp

最后连接上后,可以通过www.ip138.com 查看当前主机的IP,如果和AWS主机的公网IP一样,那么恭喜你成功了。

2、Linux主机

在/etc/ppp/peers/下创建pptpserver文件,内容如下:

1pty "pptp 服务端IP  --nolaunchpppd"
2name VPN用户名
3password VPN密码
4remotename PPTP
5require-mppe-128

执行如下命令连接:

1pppd call pptpserver
2连接异常时,可以执行下面的命令开启debug信息
3pppd call pptpserver debug nodetach

注意:1、后面跟的名字pptpserver要与/etc/ppp/peers下的文件名一致;2、Linux客户端进行连接时,单独安装ppp包是不行的,还需要安装pptp包,因为连接时需要用到pptp命令,不安装该包,VPN拨号时会提示找不到该命令。

后记:

该VPN配置好后,一直一个人使用没有任何问题,后来有同事也想使用该VPN,发现只有一个人可以用,另一个可以ping通外网,但无法正常打开网页,后面经查看发现如下问题:

 1ppp0      Link encap:Point-to-Point Protocol
 2          inet addr:192.168.100.1  P-t-P:192.168.100.100  Mask:255.255.255.255
 3          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1396  Metric:1
 4          RX packets:23146 errors:0 dropped:0 overruns:0 frame:0
 5          TX packets:28100 errors:0 dropped:0 overruns:0 carrier:0
 6          collisions:0 txqueuelen:3
 7          RX bytes:4229983 (4.0 MiB)  TX bytes:22048140 (21.0 MiB)
 8ppp1      Link encap:Point-to-Point Protocol
 9          inet addr:192.168.100.2  P-t-P:192.168.100.101  Mask:255.255.255.255
10          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1396  Metric:1
11          RX packets:3103 errors:0 dropped:0 overruns:0 frame:0
12          TX packets:3680 errors:0 dropped:0 overruns:0 carrier:0
13          collisions:0 txqueuelen:3
14          RX bytes:319769 (312.2 KiB)  TX bytes:2388000 (2.2 MiB)

在pptp server端,每新增加一个连接,本地就多一个pppX的接口,而我们iptables上的规则只是针对ppp0的,将iptables规则做了简单的修改后,所有人都可以正 常上网了:

1#-A FORWARD -i ppp0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --set-mss 1356
2-A FORWARD  -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --set-mss 1356
3#-A FORWARD  -p tcp -m tcp --syn -j TCPMSS --clamp-mss-to-pmtu

将注释的行改为第二行,或第三行都OK的。