ss-local + privoxy 代理

ss-local 是 shadowsocks 的本地 socks5 服务器,因此,如果需要使用 ss-local 提供的 socks5 代理,就必须让应用程序使用 socks5 协议与之通信。但是很可惜,除了部分浏览器、软件直接支持 socks5 协议外,其它的都只支持 http 代理。因此,我们需要借助 privoxy 来将 http 代理协议转换为 socks5 代理协议,与后端的 ss-local 进行通信。

相关说明

shadowsocks 有两种使用姿势:

  • ss-local + privoxy:使用 privoxy 作为前端的 http 代理(支持 CONNECT),可选择全局、gfwlist 两种方式;
  • ss-redir + iptables:支持代理所有 TCP、UDP 流量(本机 UDP 除外),可选择全局、绕过大陆地址两种方式。

今天我们要说的是第一种姿势,即ss-local + privoxy;第二种姿势可以前往 ss-redir 透明代理

这两种方式的主要区别在于:gfwlist绕过大陆地址;相信经常 FQ 的人对这两种模式都比较熟悉:

  • gfwlist:gfwlist 就是一个包含了几乎所有被墙域名的列表,因此,使用这种模式只会让被墙的网站走代理;但是很多国外没被墙的域名还是走的直连,因此访问国外未墙网站的时候速度依旧很慢,甚至出现连接超时的情况;
  • 绕过大陆地址:顾名思义,只有发往大陆地址的流量不会走代理,其它的不管有没有被墙,统统走代理上网;这样就不会出现 gfwlist 模式的国外未墙网站访问慢的问题了。我个人建议使用这种模式。

当然,对于 gfwlist 模式出现的问题也不是没有解决办法,我们只需把要走代理的网站添加至 privoxy 规则文件,一样可以走代理。

ss-local 篇

安装

shadowsocks 有 libev、python、go 几个主要分支(ssr 不在讨论范畴内),这里推荐使用广泛的两个: libev、python。
python 版的特点是没有 ss-redir、ss-tunnel,并且需要依赖 python 环境;libev 则是使用 C 语言开发的,性能比较好。

Python

C - libev

配置

vim /etc/ss-local.json
{
    "server": "1.2.3.4",
    "server_port": 8989,
    "method": "aes-128-cfb",
    "password": "123456",
    "fast_open": false,
    "local_address": "127.0.0.1",
    "local_port": 1080,
    "workers": 2
}

## 配置说明:
{
    "server": "1.2.3.4",          # 服务器IP
    "server_port": 8989,          # 服务器Port
    "method": "aes-128-cfb",      # 加密方式
    "password": "123456",         # 端口密码
    "fast_open": false,           # tcp_fastopen
    "local_address": "127.0.0.1", # 本地监听IP
    "local_port": 1080,           # 本地监听Port
    "workers": 2                  # worker进程数量
}

运行

## python
nohup sslocal -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &

## libev
nohup ss-local -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &

privoxy 篇

安装

## CentOS/RHEL
yum -y install privoxy

## ArchLinux
pacman -S --need privoxy

全局

全局模式是最简单最粗暴的,即:所有流量都走 ss-local,不区分什么国内国外。
因此请你确定否需要这种模式,如果不需要,请跳过此段,直接到 - gfwlist 模式

gfwlist

gfwlist 是由 AutoProxy 官方维护,由众多网民收集整理的一个中国大陆防火长城的屏蔽列表;
因为这是 Firefox 浏览器直接使用的一种格式,因此,如果需要用在 privoxy 上就需要进行转换;
这里我提供一个 shell 转换脚本,除了正则语法无法自动处理外,其它的基本 OK,gfwlist2privoxy

环境变量

# privoxy 默认监听端口为 8118
proxy="http://127.0.0.1:8118"
export http_proxy=$proxy
export https_proxy=$proxy
export no_proxy="localhost, 127.0.0.1, ::1, ip.cn, chinaz.com"

# no_proxy 环境变量是指不经过 privoxy 代理的地址或域名
# 只能填写具体的 IP、域名后缀,多个条目之间使用 ',' 逗号隔开
# 比如: export no_proxy="localhost, 192.168.1.1, ip.cn, chinaz.com"
# 访问 localhost、192.168.1.1、ip.cn、*.ip.cn、chinaz.com、*.chinaz.com 将不使用代理

代理测试

# 访问各大网站,若均有网页源码输出则配置成功
curl -sL www.baidu.com
curl -sL www.google.com
curl -sL www.google.com.hk
curl -sL www.google.co.jp
curl -sL www.youtube.com
curl -sL www.facebook.com
curl -sL www.wikipedia.org

# 获取当前 IP 地址,应该显示本机 IP
curl -sL ip.chinaz.com/getip.aspx

shell 脚本

因为每次都需要繁琐的设置 proxy 环境变量,因此这里提供一个简陋的 ss-privoxy 脚本,用于一键启用、关闭代理。

Python
新建ss-privoxy文件,chmod +x ss-privoxycp -af ss-privoxy /usr/local/bin/

#!/bin/bash

case $1 in
start)
    nohup sslocal -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &
    systemctl start privoxy
    proxy="http://127.0.0.1:8118"
    export http_proxy=$proxy
    export https_proxy=$proxy
    export no_proxy="localhost, 127.0.0.1, ::1, ip.cn, chinaz.com"
    ;;
stop)
    unset http_proxy https_proxy no_proxy
    systemctl stop privoxy
    pkill sslocal
    ;;
reload)
    pkill sslocal
    nohup sslocal -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &
    ;;
set)
    proxy="http://127.0.0.1:8118"
    export http_proxy=$proxy
    export https_proxy=$proxy
    export no_proxy="localhost, 127.0.0.1, ::1, ip.cn, chinaz.com"
    ;;
unset)
    unset http_proxy https_proxy no_proxy
    ;;
*)
    echo "usage: source $0 start|stop|reload|set|unset"
    exit 1
    ;;
esac

C - libev
新建ss-privoxy文件,chmod +x ss-privoxycp -af ss-privoxy /usr/local/bin/

#!/bin/bash

case $1 in
start)
    nohup ss-local -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &
    systemctl start privoxy
    proxy="http://127.0.0.1:8118"
    export http_proxy=$proxy
    export https_proxy=$proxy
    export no_proxy="localhost, 127.0.0.1, ::1, ip.cn, chinaz.com"
    ;;
stop)
    unset http_proxy https_proxy no_proxy
    systemctl stop privoxy
    pkill ss-local
    ;;
reload)
    pkill ss-local
    nohup ss-local -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &
    ;;
set)
    proxy="http://127.0.0.1:8118"
    export http_proxy=$proxy
    export https_proxy=$proxy
    export no_proxy="localhost, 127.0.0.1, ::1, ip.cn, chinaz.com"
    ;;
unset)
    unset http_proxy https_proxy no_proxy
    ;;
*)
    echo "usage: source $0 start|stop|reload|set|unset"
    exit 1
    ;;
esac

配置命令别名vim /etc/profile.d/ss-privoxy.sh

加载别名文件source /etc/profile

ss-privoxy 用法
ss.start:启动 ss-local+privoxy 代理;
ss.stop:停用 ss-local+privoxy 代理;
ss.reload:重载 ss-local.json 配置文件;
ss.set:设置 shell_proxy 环境变量;
ss.unset:删除 shell_proxy 环境变量;