ss-redir透明代理+pptpd+xl2tpd折腾日记

前言

我采用的是shadowsocks+frp 作为内网主机突破防火墙的工具。后面为了方便使用,我增加了HTTP代理和PPTP + L2TP + L2TP/IPSec PSK 三种类型的VPN,应该说是相当方便了。

在这里我不得不吐槽一下L2TP/IPSec PSK的配置方案,网上写方案的人贼不负责,乱写一通。好在我查libreswan文档解决了我的问题。

在VPN配置好以后,就是防火墙的配置了。我才疏学浅,又不知天高地厚,被iptables折磨的死去活来,最终磨出来一些简单的规则。

安装顺序:shadowsocks > frp > pptpd > xl2tpd


目录

(一)Shadowsocks安装配置
(二)frp内网穿透工具配置
(三)socks5 转HTTP代理
(四)pptpd VPN服务器搭建
(五)xl2tpd + IPSec 搭建VPN


(一)Shadowsocks安装配置

为了得到最新版本的shadowsocks 我采用的是源码安装。其实也挺简单的,只是相比于直接使用版本管理工具安装也要稍微费事一些。


主机配置清单:
– 阿里云 ECS主机
– Centos7 x86_64
– 树莓派3代(现在3代B+型出来了,好想买啊!!!)
– python3.7


网络环境:

内网: 树莓派 192.168.1.104

外网:服务器主机。vpn.aaron.mobi


1、pip安装shadowsocks

python版本shadowsocks使用pip安装最方便,不过版本相对来说会比较老。

pip install shadowsocks

如果没要求,也可以将就着用。

2、 python版shadowsocks源码安装(安装在树莓派上面)

我当然是用最新版本啦,直接从源码安装。

yum install python-setuptools && easy_install pip

其实我是从源码安装的Python3.7 ,安装的时候回自带安装python-setuptools . 所以上面这一步被我直接省略掉了。

获取最新版本shadowsocks

wget https://github.com/shadowsocks/shadowsocks/archive/2.9.1.tar.gz

解压

tar -xvzf 2.9.1.tar.gz

其实我一直不明白这几个解压参数究竟是什么意思,所以我写的时候顺手查了一下。

tar 命令参数详解:

# 这五个命令是独立命令,压缩或解压只能用到其中一个。
-c : 建立压缩档案
-x : 解压
-t : 查看内容
-r : 向压缩文件末尾追加文件
-u : 更新原压缩包中的文件

# 压缩解压可选命令
-z : 有gzip属性,(文件名.gz)
-j : 有bz2属性的 (文件名.bz2)
-Z : 有compress属性的
-v : 显示压缩或解全部过车鞥
-O : 将文件解开到标准输出
-f : 档案名(这个参数必须填写)

下载解压之后,进入文件夹 cd shadowsocks-2.9.1

编译和安装

python setup.py build

python setup.py install

然后就大功告成了。

3、shadowsocks配置清单

服务器端:
# /etc/shadowsocks.json
{
"server":"",     ##填写服务器外网ip地址
"server_port":8000,  ##代理端口
"local_address":"127.0.0.1",
"local_port":1080, ##本地监听端口
"password":"",   ##连接密码
"timeout":300,
"method":"aes-256-cfb", ##加密方式,我用的rc4-md5
"dast_open":false
}

客户端基本类似。对更对细节有兴趣的朋友可以查看这儿

命令行启动和关闭ssserver
ssserver -c /etc/shadowsocks.json -d start # 后台启动
ssserver -c /etc/shadowsocks.json -d stop  # 后台关闭

这里是在后台启动,据我遇到的坑有,不能用这种方法同时启动ssserver和sslocal。所以,还可以用Linux知道的nohup后台启动程序。

(二)frp内网穿透工具配置


1、下载

frp工具在github上面开源。可以直接去github搜索frp,然后下载你想要的版本。

wget https://github.com/fatedier/frp/releases/download/v0.17.0/frp_0.17.0_linux_amd64.tar.gz

# 解压
tar -xzvf frp_0.17.0_linux_amd64.tar.gz

2、配置清单

先分析一下网络情况。

首先,我的树莓派在内网,并且是联网的。其次,我的阿里云主机在外网,有独立的IP地址。因此,内网主机(树莓派)可以访问内网的服务,比如图书馆数据库资源;而树莓派同时又可以访问阿里云主机。云主机有独立IP,可以被任意联网设备访问。

frp的作用就是在树莓派和云主机之间建立一个转发连接, 所有发往云主机的流量都被转到树莓派,然后再依次将数据返回给客户端。

shadowsocks建立连接和DNS查询会用到UDP协议, 因此frp要同时转发udp的数据包

服务器端配置文件
# 服务器端配置文件
# /etc/frp/frps.ini
[common]
bind_port = 7000

[shadowsocks-tcp]
type = tcp
local_ip = 127.0.0.1
local_port = 8388
remote_ip = 8388

[shadowsocks-udp]
type = udp
local_ip = 127.0.0.1
local_port = 8388
remote_port = 8388
客户端配置文件
# frpc.ini
[common]
server_addr = vpn.aaron.mobi
auth_token = ********

[shadowsocks-tcp]
type = tcp
local_ip = 127.0.0.1
local_port = 8388
remote_port = 8388

[shadowsocks-udp]
type = udp
local_ip = 127.0.0.1
local_port = 8388
remote_port = 8388

后台运行frp

服务器端

nohup /root/software/frp/frps -c /root/software/frp/frps.ini > /home/nicolana/log/frp.log 2>&1 & 

客户端

nohup /home/pi/soft/frp/frpc -c /home/pi/soft/frp/frpc.ini > /home/pi/soft/log/frp.log 2>&1 &
特别说明

frpc在未联网的情况下连接服务器会自己中断,因此在设置开机启动的时候,建议自己写个脚本维护frpc这个进程。这里贴上我用Go写的脚本。

package main
# protect_frp.go
# 最好不要在你的程序名中加frpc,会影响程序运行
import (
    "fmt"
    "os/exec"
    "strings"
    "time"
)

func main() {
    for{
        frp_pid_cmd := "ps -A | grep frpc"
        frp_pid := StartCommand(frp_pid_cmd)
        // fmt.Println(frp_pid)
        if !strings.Contains(frp_pid, "frpc"){
            fmt.Println("There have no frpc")
        //fmt.Println(frp_pid)
            startFrp()
        }
        time.Sleep(1000 * time.Millisecond * 60 )
    }

}

func startFrp(){
    cmd := exec.Command("/bin/bash","-c","nohup /home/pi/soft/frp/frpc -c /home/pi/soft/frp/frpc.ini > /home/pi/soft/log/frp.log 2>&1 &")
    out, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(out))
}

func StartCommand(cmda string)string{
    cmd := exec.Command("bash", "-c", cmda)
    out, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Println(err)
    }
    return string(out)
}

到这里,你只需要在防火墙上面打开 7000、8388 两个端口的tcp、udp允许就可以使用了。 然而我用的主机使用的是安全组,所以我直接去阿里云官网修改主机安全组配置就好了。

(三)socks5 转HTTP代理

据说网上有很多相关代理,这里我使用的是 privoxy 该软件官方地址


1、安装

Centos

yum install privoxy

Raspbian

sudo apt-get install privoxy

安装完成后自动启动。

2、启动和关闭、以及开机启动
# 启动
systemctl start privoxy

# 关闭
systemctl stop privoxy

# 开机启动
systemctl enable privoxy
3、配置Privoxy

默认配置文件地址是: /etc/privoxy/config

特别提醒,vim跳转783行命令 :783

编辑第 783行,修改http监听地址

listen-address  127.0.0.1:1081
listen-address  [::1]:1081

编辑1337行,取消socks转发注释,并设置socks网络地址和端口。

forward-socks5t  /            127.0.0.1:1080 .

手打的同学请注意, 后面有个小数点。

4、配置socks

socks配置略。可以用ss-local 或者 sslocal 作为客户端。然后开放相应端口即可。

(四)pptpd VPN服务器搭建

在安装pptpd之前还需要检查一下系统是否支持ppp服务,以及内核转发功能,我不详写,感兴趣的同学可以看这个网址: http://www.zyops.com/vpn-pptp/

1、安装PPTP
yum -y install pptpd

安装相对来说比较简单。

2、配置pptp

记住这个配置,待会儿写iptables转发的时候还需要用到。

# vim /etc/pptpd.conf

localip 192.168.22.1
remoteip 192.168.22.128-192.168.22.254 
3、设置用户名和密码

用户名和密码设置。 其中server 填写的* 代表该账号密码对 pptpd 和 xl2tpd 两种类型均适用。当然,你也可以单独填些pptpd 或者xl2tpd

IP addresses也是填的* 代表地址由服务器分配。也可以自定义。

# vim /etc/ppp/chap-secrets
# Secrets for authentication using CHAP
# client    server  secret          IP addresses
user01      *   0123456         *
user02      *   0123456         *
4、启动pptpd
# 启动
systemctl restart pptpd

# 查看启动状态
systemctl status pptpd
5、配置iptables转发

经过上面一步的启动,pptpd服务已经正常运行了。接下来要做的事情就是开启1701 tcp端口 并设置流量转发。1701 tcp端口是pptpd的服务端口。

开启端口: 我用的安全组,直接添加规则即可。使用iptables 或者 ufw 或者 firewalld 的同学自行Google。

允许ipv4转发

# vim /etc/sysctl.conf

# 在文件末尾添加一行
net.ipv4.ip_forward = 1 

执行sysctl -p使修改生效

流量转发

XEN架构:

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

OpenVZ架构:

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source VPS公网IP

一切配置完毕。如果一路下来都OK,那么应该可以连接了。

(五)xl2tpd + libreswan 搭建VPN

好了。到了最坑的一个VPN配置来了。

(1)安装xl2tpd和libreswan

1、依赖安装
  • 安装epel源

为什么要安装epel源呢?是因为必要组件xl2tpd在基础的yum源里面是没有的。

yum install epel-release -y
  • 安装依赖组件
yum install -y libreswan xl2tpd
2、修改IPSec配置文件(libreswan的配置文件)

ipsec.conf 配置文件(/etc/ipsec.conf

# /etc/ipsec.conf - Libreswan IPsec configuration file

# Uncomment when using this configuration file with openswan
#version 2
#
# Manual:     ipsec.conf.5

config setup
    # which IPsec stack to use, "netkey" (the default), "klips" or "mast".
    # For MacOSX use "bsd"
    protostack=netkey
    #
    # Normally, pluto logs via syslog. If you want to log to a file,
    # specify below or to disable logging, eg for embedded systems, use
    # the file name /dev/null
    # Note: SElinux policies might prevent pluto writing to a log file at
    #       an unusual location.
    logfile=/var/log/pluto.log
    #
    # Do not enable debug options to debug configuration issues!
    #
    # plutodebug "all", "none" or a combation from below:
    # "raw crypt parsing emitting control controlmore kernel pfkey
    #  natt x509 dpd dns oppo oppoinfo private".
    # Note: "private" is not included with "all", as it can show confidential
    #       information. It must be specifically specified
    # examples:
    # plutodebug="control parsing"
    # plutodebug="all crypt"
    # Again: only enable plutodebug when asked by a developer
    #plutodebug=none
    uniqueids=no
    # Enable core dumps (might require system changes, like ulimit -C)
    # This is required for abrtd to work properly
    # Note: SElinux policies might prevent pluto writing the core at
    #       unusual locations
    dumpdir=/var/run/pluto/
    #
    # NAT-TRAVERSAL support
    # exclude networks used on server side by adding %v4:!a.b.c.0/24
    # It seems that T-Mobile in the US and Rogers/Fido in Canada are
    # using 25/8 as "private" address space on their wireless networks.
    # This range has never been announced via BGP (at least up to 2015)
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10

# For example connections, see your distribution's documentation directory,
# or https://libreswan.org/wiki/
#
# There is also a lot of information in the manual page, "man ipsec.conf"
#
# It is best to add your IPsec connections as separate files in /etc/ipsec.d/
include /etc/ipsec.d/*.conf

我只是贴出来而已。 别误会。哈哈哈。

注意最后一行 include 了一些文件,在/etc/ipsec.d/目录下面,这才是我们要配置的地方。

创建xl2tpd_psk.conf 文件到文件夹(/etc/ipsec.d/

# vim /etc/ipsec.d/xl2tpd_psk.conf
# xl2tpd configuration
# compatible with xl2tp

conn L2TP-PSK-NAT
    rightsubnet=vhost:%priv
    also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
    authby=secret
    fragmentation=yes
    auto=add
    keyingtries=3
    dpddelay=30
    dpdtimeout=120
    dpdaction=clear
    rekey=no
    ikelifetime=8h
    keylife=1h
    left=120.79.85.91
    leftid=120.79.85.91
    leftprotoport=17/1701
    right=%any
    rightid=%any
    rightprotoport=17/%any

# for android and IOS
# auth by psk+ikev1
conn ikev1
    authby=secret
    pfs=no
    auto=add
    rekey=no
    left=%defaultroute
    right=%any
    ikev2=never
    type=transport
    leftprotoport=17/1701
    rightprotoport=17/%any
    dpddelay=15
    dpdtimeout=30
    dpdaction=clear
    sha2-truncbug=yes

conn ikev1-nat
    also=ikev1
    rightsubnet=vhost:%priv

简单来讲抄上去就可以了。详情还是自己去看官方文档吧,我不想坑你。 官网地址:https://libreswan.org/

设置PSK预共享密钥 文件(/etc/ipsec.secrets

先看一下这个文件的配置是不是这样的

include /etc/ipsec.d/*.secrets

如果是这样,就创建xl2tpd_key.secrets 到文件夹 (/etc/ipsec.d/)下面

Server IP Address %any: PSK "password"
  • 修改IP地址为你的外网IP地址,修改密码时主要一定要加引号

然后启动ipsec 并检查文档书写格式问题

# 启动ipsec
systemctl start ipsec

# 检查配置文件格式
ipsec verify

# 查看启动状态
systemctl status ipsec
配置xl2tppd服务器

xl2tpd.conf配置文件(/etc/xl2tpd/xl2tpd.conf

;
; This is a minimal sample xl2tpd configuration file for use
; with L2TP over IPsec.
;
; The idea is to provide an L2TP daemon to which remote Windows L2TP/IPsec
; clients connect. In this example, the internal (protected) network 
; is 192.168.1.0/24.  A special IP range within this network is reserved
; for the remote clients: 192.168.1.128/25
; (i.e. 192.168.1.128 ... 192.168.1.254)
;
; The listen-addr parameter can be used if you want to bind the L2TP daemon
; to a specific IP address instead of to all interfaces. For instance,
; you could bind it to the interface of the internal LAN (e.g. 192.168.1.98
; in the example below). Yet another IP address (local ip, e.g. 192.168.1.99)
; will be used by xl2tpd as its address on pppX interfaces.

[global]
listen-addr = 0.0.0.0
;
; requires openswan-2.5.18 or higher - Also does not yet work in combination
; with kernel mode l2tp as present in linux 2.6.23+
ipsec saref = yes
; Use refinfo of 22 if using an SAref kernel patch based on openswan 2.6.35 or
;  when using any of the SAref kernel patches for kernels up to 2.6.35.
; saref refinfo = 30
;
force userspace = yes
;
; debug tunnel = yes

[lns default]
ip range = 192.168.23.128-192.168.23.254
local ip = 192.19.23.1
require chap = yes
refuse pap = yes
require authentication = yes
name = LinuxVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

按照上面这个配置修改。

配置xl2tpd dns服务

options.xl2tpd文件 (/etc/ppp/options.xl2tpd

#require-mschap-v2
ipcp-accept-local
ipcp-accept-remote
ms-dns  223.5.5.5
ms-dns  223.6.6.6
# ms-dns  192.168.1.1
# ms-dns  192.168.1.3
# ms-wins 192.168.1.2
# ms-wins 192.168.1.4
noccp
auth
crtscts
idle 1800
mtu 1500
mru 1500
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
# To allow authentication against a Windows domain EXAMPLE, and require the
# user to be in a group "VPN Users". Requires the samba-winbind package
require-mschap-v2
# plugin winbind.so
# ntlm_auth-helper '/usr/bin/ntlm_auth --helper-protocol=ntlm-server-1 --require-membership-of="EXAMPLE\\VPN Users"' 
# You need to join the domain on the server, for example using samba:
# http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-openswan-xl2tpd-with-native-windows-clients-lucid.html

lcp-echo-interval 0
lcp-echo-failure 0

修改ms-dns为逆向要的dns查询服务器。(VIM检索命令/ms-dns,然后回车)

xl2tpd密码文件 (/etc/ppp/chap-secrets

密码之前安装pptpd的时候已经设置过了,这里就不再设置了。

启动服务
# 启动服务
systemctl restart ipsec xl2tpd

# 查看启动状态
systemctl status xl2tpd

如果遇到故障,可以在 (/var/log/messages)文件中看到相关信息,如有需要也可以自己打开相应软件的log日志。

(2)防火墙配置

因为ipsec验证要使用 udp 500 和 udp 4500端口。 而xl2tpd 则使用1723 TCP+UDP端口。

因此要在防火墙上面打开对应协议的端口。打开方式自行Google

开启ss-redir透明代理

ss-redir 是shadowsocks-libev的一个组件,用于透明代理。和ss-tunnel合并使用可转发UDP的DNS服务。

安装比较简单, yum instal shadowsocks-libev
如果安装不上,请前往github下载源码安装。

ss-redir配置文件 (/etc/ss-redir.json)

{
"server":"www.aaron.mobi",
"server_port":8388,
"local_address":"0.0.0.0",
"local_port":1082,
"password":"barfoo!",
"method":"rc4-md5"
}

local_address 千万设置成 0.0.0.0 不然会出错。

后台启动ss-redir 透明代理:

nohup ss-redir -c /etc/ss-redir.json -u -v &

参数-u 开启udp转发模式。 -v 则显示所有运行情况

下一步。将VPN连接的网络转发到透明代理端口1082

为了避免麻烦,我直接将转发的iptables 写成了脚本

iptables_nat.sh

#!/bin/bash
# iptables_nat.sh

# important , my server ip 
iptables -t nat -A PREROUTING -d 120.79.85.91 -j RETURN  

# return local proxy
iptables -t nat -A PREROUTING -d 127.0.0.0/24 -j RETURN  
iptables -t nat -A PREROUTING -d 192.168.0.0/16 -j RETURN  
iptables -t nat -A PREROUTING -d 10.42.0.0/16 -j RETURN  
iptables -t nat -A PREROUTING -d 0.0.0.0/8 -j RETURN  
iptables -t nat -A PREROUTING -d 10.0.0.0/8 -j RETURN  
iptables -t nat -A PREROUTING -d 172.16.0.0/12 -j RETURN  
iptables -t nat -A PREROUTING -d 224.0.0.0/4 -j RETURN  
iptables -t nat -A PREROUTING -d 240.0.0.0/4 -j RETURN  
iptables -t nat -A PREROUTING -d 169.254.0.0/16 -j RETURN

# redirect 192.168 host's subnet to ss tansparent port 1082
iptables -t nat -A PREROUTING -p tcp -s 192.168.20.0/22 -j REDIRECT --to-ports 1082

# postrouting all data to eth0
iptables -t nat -A POSTROUTING -s 192.168.20.0/22 -o eth0 -j MASQUERADE

在转发前千万测试一下你的shadowsocks连接是否是成功的。(我在这儿栽了的)

删除iptables配置脚本

iptables_del.sh

#!/bin/bash
iptables -t nat -F PREROUTING
iptables -t nat -F POSTROUTING

到这一步就大功告成了。可以打开手机测试一下了。


iptables 防火墙基本操作

编号

iptables -t nat -vnL POSTROUTING --line-number

删除

iptables -t nat -D PREROUTING 1

iptables 查询

iptables -t nat -L -n

重定向

iptables -t nat -A PREROUTING -p tcp -s 10.42.0.0/16 -j REDIRECT --to-ports 1081  

撤回

iptables -t nat -A PREROUTING -d 192.168.23.0/24 -j RETURN

转发

sudo iptables -t nat -A POSTROUTING -s 192.168.22.0/24 -o eth0 -j MASQUERADE

暂无评论

发表评论

您的电子邮件地址不会被公开,必填项已用*标注。

相关推荐

FRP简单使用记录

Frp 是一个Go语言开发的开源端口映射工具,感觉蛮好用的。平时偶尔需要用到,但是因为记不住怎么用,就非常麻烦 …