记一次阿里云配置 PPTPd,及 IPTables Log 调试

虽然爬墙主用 SS, 但是对于全局或非 TCP 协议的时候,SS 还是显得有些不足。

配置 PPTP 应该是很多 FQer 第一个接触的方法,也是比较古老的方法,由于加密不足以及流量特征被 GFW 捕获,使用率降低。

今天吃多了由于需要全局,就在Aliyun上重现一下配置过程。途中遇到了不少坑,谨作为记录

PPTPd

yum 安装 pptpd 软件包

1
yum install pptpd

编辑配置文件

PPTPd
1
vi /etc/pptpd.conf

在这个文件里主要就是对 localip 以及 remoteip 的配置,去掉注释并修改为希望的地址段,简单了说就是一个地址池,拨入的用户会从 remoteip 段中分配获得一个地址,而 localip 即是本机在 ppp 连接后的地址
QQ20160811-5

Options
1
vi /etc/ppp/options.pptpd

这个文件中需要修改的就是 DNS 地址了,去掉注释并修改 ms-dns 的值,这里为什么修改成这个地址下面会讲,各位按照实际情况修改。
当然是用的协议标准也在这里,MPPE等,如若协议出错可修改。默认标准可不进行修改
QQ20160811-3

Secrets
1
vi /etc/ppp/chap-secrets

由于不需要复杂认证,就在这里填写连接用用户名密码,格式为:用户名 pptpd 密码 ,最后的那个为分配的 IP,指定 IP 的话,可以配合 iptables SNAT 至不同地址,实现多用户不同 IP(理论,未验证)

Sysctl
1
vi /etc/sysctl.conf

此处修改系统规则,修改 net.ipv4.ip_forward 项值为 1,启用 ip 转发?
如若存在 net.ipv4.tcp_syncookies 项目,请注释。
QQ20160811-6
使修改生效 ```bash
sysctl -p

1
2
3
4

#### 启动 pptpd
```bash
systemctl restart pptpd

开机启动

1
systemctl enable pptpd

此时若是关闭 iptables,应该已经是可以连接的状态了,其实本该离成功不远了,但是偏偏在这之后才是噩梦。

IPTables

修改 iptables 配置(这里若使用 CentOS 系列系统,请禁用 firewalld,此篇教程使用 iptables 转发方法),基础配置请移步这篇

方法1
1
vi /etc/sysconfig/iptables

添加如下两行至适当位置:

1
2
-A INPUT -p gre -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 1723 -j ACCEPT

其中第一行是放通 GRE 连接,第二行放通 1723端口 TCP 连接
QQ20160811-7

方法2
1
2
iptables -A INPUT -p gre -j ACCEPT
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT

功能同上,执行完毕若无问题,执行

1
/usr/libexec/iptables/iptables.init save

进行保存,保存后可观察文件3.1.1中的文件变化,调整规则顺序。

此时开启 iptables 应该已经可以连接成功了(不成功请检查 pptpd 服务是否启动,云服务商是否未放通对应安全组),接着就是对内网地址进行 MASQUERADE,简单了说,就是实现最简单的路由转发。

下面三个任选其一,意思相近,

  1. 对 pptp 进来的内网地址并且从 eth0 流出的连接 进行 MASQUERADE;
    1
    iptables -t nat -A POSTROUTING -s 192.168.40.0/24 -o eth0 -j MASQUERADE
  2. 对 pptp 进来的内网地址并且从 172.16.100.1 流出的连接 进行 SNAT(效率较高?);
    1
    iptables -t nat -A POSTROUTING -s 192.168.40.0/24 -j SNAT --to-source 172.16.100.1
  3. 在命令2的基础上,进一步限制从 eth0 流出。
    1
    iptables -t nat -A POSTROUTING -s 192.168.40.0/24 -o eth0 -j SNAT --to-source 172.16.100.1

此处 192.168.40.0/24 对应 2.1 步骤中的 remoteip 段,eth0 为外网网卡,172.16.100.1 则为外网IP,由于我的主机使用的私有网络,因此是一个内网地址,需按照实际情况修改,一般情况下同外网网卡IP。

这里对不同 IP 指定不同出口网卡/出口 IP 应该可以实现多用户不同 IP。

一般教程到此也就结束了,因为已经成功了呀- -,但是我这边则是 client 连接后,无论如何都 ping 不通,于是接着研究

首先,把 iptables 的规则全部清空了,当然这只是临时的,不运行 save 是不会复写到文件内,restart 一下就会重新载入文件内配置

  • 清空:

    1
    2
    iptables -F
    iptables -X
  • 查看:

    1
    2
    3
    iptables -t nat -F
    iptables -t nat -X
    iptables -t nat -nL
  • 载入规则:

    1
    2
    iptables -A INPUT -p gre -j ACCEPT
    iptables -A INPUT -p tcp --dport 1723 -j ACCEPT

再连接试试,嗯,这下能 ping 通了,QQ 也接上了,但还是没法上网。对,就是 DNS 问题了。

问题一个个解决,第一个问题:为什么有规则时候会 ping 不通呢?

通过排查,我们知道应该是原先 iptables 中的规则出错,其默认不设置的时候是放通的,也就是说是原先存在的 DROP or REJECT 操作挡了数据包。
一般来说,一件这种问题无非就是从 log 中排查,不过很遗憾 iptables 默认是不记录 REJECT 记录的,于是研究转变成:如何打开 iptables 的记录功能。

通过 http://linux.die.net/man/8/iptables 这篇文章,我们了解到 iptables 是带 logging 的,只需要在对对应连接做处理前,进行 LOG 操作即可

于是修改 iptables 配置
1
2
-A INPUT -m limit --limit 2/sec --limit-burst 2 -j LOG --log-prefix "IPTABLES REJECTING INPUT: "
-A FORWARD -m limit --limit 2/sec --limit-burst 2 -j LOG --log-prefix "IPTABLES REJECTING FORWARD: "

分别将两条添加在 REJECT 操作之前即可。这里用到了 limit 功能,就是为了日志不爆炸。限制了每秒2条,并发最多2条,并且指定了日志的前缀。

重启 iptables,日志位于 /var/log/messages
1
tail -f /var/log/messages
打开pptp连接,发现端倪

QQ20160811-0

从日志看,是 FORWARD 被 REJECT 了,于是添加
1
2
-A FORWARD -i ppp+ -j ACCEPT
-A FORWARD -i eth0 -o ppp+ -j ACCEPT

意思是:接受来源于 ppp 开头的 interface 的转发,接受来源于 eth0 端口 并且转发到 ppp 开头的interface 的转发。

重启 iptables,问题解决

我的 iptables 配置,仅作参考:
QQ20160811-8

现在剩下第二个问题,为何无法解析域名呢?

无法解析域名,第一个想到的应该就是 DNS 无法访问,由于 DNS 位于53端口,于是 nmap 扫一下,很奇怪,client 这边是可以访问的,而 server 侧则无法解析

CentOS 默认不带 nslookup 工具,需要安装,这里就不展开说。

1
yum install bind-utils
  • Client 侧 DNS:

QQ20160811-9

  • Server 侧 DNS:

QQ20160811-10

至今我还是没有理解为何,不过不碍事,毕竟已经找到问题了,想要解决是不难的。

查看 Server 侧的 DNS,因为本身是可以正常解析的,也就是说客户端使用 Server 的 DNS 应该可以绕过这个问题。
1
cat /etc/resolv.conf

QQ20160811-11

我们将这两个 DNS 地址,写入步骤2.2中的配置文件,重启 pptpd,问题解决。

QQ20160811-2

至此,大致上的问题解决了

补充

已经可以通过 pptp 访问公网,但是速度比较慢,搜索后发现一个比较统一的说法就是修改 MTU 值,但是实测并没有什么…用,不过还是将它放在这里,指不定哪天就想到问题所在了呢?
修改 MTU 为1356:

1
iptables -A FORWARD -p tcp --syn -s 192.168.40.0/24 -j TCPMSS --set-mss 1356