首页 > Computer > SOCKS代理的透明化和可路由
2011
08-05

SOCKS代理的透明化和可路由

前面我写了关于SSH的一系列文章:http://blog.lilinux.net/tag/ssh/ 。发现通过搜索引擎访问本站的读者大多是想了解SSH转发的。

在Li哥看来,与VPN相比,SSH动态转发只是一个SOCKS代 理,不如VPN那种建立一个点到点连接的方式处理方便。首先,VPN连接可以在路由表中配置,不需要软件支持和显式指定;其次,因为VPN的“连接”性 质,用户可以灵活地配置流量的走向,比如访问Chinternet用原本的连接,访问Internet用VPN连接。当然,SOCKS代理的优势也是显而 易见的,只要有一个SSH账号,即可建立隧道,一般来说,要比VPN的花费要少。在后续的文章中,Li哥将介绍在普通的无SSH支持的PHP主机上实现穿 透代理。

本文的目的是将SOCKS代理透明化和可路由化

它的应用场景如下:
1. 透明代理,即可不指定代理而自动使用SOCKS代理转发。换句话说,把代理配置在了应用层以下
2. 共享代理,即把只能本地访问的SOCKS代理(SSH隧道)转换成可共享的。也就是不透露SSH账号且只建立一次隧道,即可供多人使用。
3. 转发规则自定义,即可将分组分类(比如按目的地址分类)并配置转发。
4. 其它。

redsocks

用过squid的读者应该知道,用squid和iptables来实现上面的需求很简单,首先在服务端squid.conf中的port选项后增加“transparent”字段,然后将相应请求用iptables redirect到端口即可。

iptables -t nat -A PREROUTING -p tcp --dport 80 -d xx.xx.xx.xx -j REDIRECT --to-port 3128

但SSH建立的socks代理不具备这样的功能,只能通过第三方的软件来扩展。 本文介绍一款名为redsocks的软件。redsocks是我目前发现在这方面最好的软件。
redsocks可以在http://darkk.net.ru/redsocks/下载,也可在此下载http://blog.lilinux.net/attachment/darkk-redsocks-a37aa7a.zip

redsocks的官方说明

This tool allows you to redirect any TCP connection to SOCKS or HTTPS
proxy using your firewall, so redirection is system-wide.

Why is that useful? I can suggest following reasons:
* you use tor[1] and don't want any TCP connection to leak.
* you use DVB ISP and this ISP provides internet connectivity with some
  special daemon that may be also called "Internet accelerator" and this
  accelerator acts as proxy. Globax[2] is example of such an accelerator.

Linux/iptables, OpenBSD/pf and FreeBSD/ipfw are supported.
Linux/iptables is well-tested, other implementations may have bugs,
your bugreports are welcome.

Transocks[3] is alike project but it has noticable performance penality.

Transsocks_ev[4] is alike project too, but it has no HTTPS-proxy support
and does not support authentication.

redsocks的安装

1. 安装libevent组件

libevent的官方页面:http://www.monkey.org/~provos/libevent/
值得注意的是,发行版源仓库中的libevent一般的版本较低,在编译redsocks时会失败。Debian/Ubuntu所需的libevent可以从此下载:http://ftp.de.debian.org/debian/pool/main/libe/libevent/

本站也提供libevent的deb包下载:http://blog.lilinux.net/attachment/libevent.zip

2. 编译redsocks

解压、make
这个应该不需要详细介绍了

3. 编辑配置文件

在redsocks目录下建立配置文件redsocks.conf。内容如下(因为配置文件注释与C++相同,故用C++代码风格加亮)

base {
	log_debug = on;
	log_info = on;
	 //日志文件,调试时可指定为标准错误"stderr"
	log = "file:/home/lige/soft/redsocks/socks.log";

	// 是否以后台模式运行
	daemon = on
	redirector = iptables;
}

redsocks {
         //local_ip设置为0.0.0.0则可共享,设备为127.0.0.1则只能在本机使用
	local_ip = 0.0.0.0
	local_port = 12345;

	// 本来有的代理的IP和端口,可能是由ssh -D指定的
	ip = 127.0.0.1;
	port = 1080;

	// known types: socks4, socks5, http-connect, http-relay
	type = socks5;
}

4. iptables策略

新建一个脚本tp-socks.sh,用来运行redsocks和生成iptables策略
脚本摘自przemoc.net

#!/bin/sh

# iptables路径
IPTABLES="/usr/local/sbin/iptables"

# redsocks路径
REDSOCKS_DIR="/home/lili/soft/redsocks"
REDSOCKS="$REDSOCKS_DIR/redsocks"

# 配置文件中指定的端口
REDSOCKS_PORT="12345"

# socks代理IP和端口
SOCKS_HOST="127.0.0.1"
SOCKS_PORT="1080"

# 运行redsocks
if [ "$USER" != "root" ]; then
	echo -n 'Restarting redsocks... '
	pkill -U $USER redsocks 2>/dev/null
	sleep 1
	cd $REDSOCKS_DIR && $REDSOCKS
	if [ $? -eq 0 ]; then
		echo Done
	else
		echo Error
	fi
	exit 0;
elif [ "$1" != "iptables" ]; then
	exit 0
fi

$IPTABLES -t nat -D PREROUTING -p tcp -j REDSOCKS_FILTER 2>/dev/null
$IPTABLES -t nat -D OUTPUT     -p tcp -j REDSOCKS_FILTER 2>/dev/null
$IPTABLES -t nat -F REDSOCKS_FILTER 2>/dev/null
$IPTABLES -t nat -X REDSOCKS_FILTER 2>/dev/null
$IPTABLES -t nat -F REDSOCKS 2>/dev/null
$IPTABLES -t nat -X REDSOCKS 2>/dev/null

# Create our own chain
$IPTABLES -t nat -N REDSOCKS
$IPTABLES -t nat -N REDSOCKS_FILTER

# Do not try to redirect local traffic
$IPTABLES -t nat -I REDSOCKS_FILTER -o lo -j RETURN

### 以下是iptables策略配置,包括白名单和黑名单,默认开启白名单
### 你应该至少修改一行配置,也很简单

# Redirect only specified addresses and do not try redirect other traffic. (whitelist option)
# 白名单选项:只重定向指定的分组到SOCKS代理,其它的都按默认路由转发
$IPTABLES -t nat -A REDSOCKS_FILTER -m iprange --dst-range 192.168.0.10-192.168.0.30 -j REDSOCKS
$IPTABLES -t nat -A REDSOCKS_FILTER -d 126.0.0.0/8 -j REDSOCKS
$IPTABLES -t nat -A REDSOCKS_FILTER -j RETURN

## Do not redirect LAN traffic and some other reserved addresses. (blacklist option)
# 黑名单选项:指定的分组通过默认路由转发,其它的都转向SOCKS代理
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 0.0.0.0/8 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 10.0.0.0/8 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 127.0.0.0/8 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 169.254.0.0/16 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 172.16.0.0/12 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 192.168.0.0/16 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 224.0.0.0/4 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -d 240.0.0.0/4 -j RETURN
#$IPTABLES -t nat -A REDSOCKS_FILTER -j REDSOCKS

## Do not redirect traffic for the SOCKS-Server
## Not needed if server is not on a whitelist or is already blacklisted.
# 不转发。实际没什么意义,不需要SOCKS时只需要清空nat表即可
#$IPTABLES -t nat -I REDSOCKS -p tcp -d $SOCKS_HOST --dport $SOCKS_PORT -j RETURN

# Redirect all traffic that gets to the end of our chain
# 将未指定的转发到SOCKS代理,实际上不会用到
$IPTABLES -t nat -A REDSOCKS   -p tcp -j REDIRECT --to-port $REDSOCKS_PORT

## Filter all traffic from the own host
# 将分组转到REDSOCKS_FILTER,以保证对分组的区分处理,作用于本机
## BE CAREFULL HERE IF THE SOCKS-SERVER RUNS ON THIS MACHINE
$IPTABLES -t nat -A OUTPUT     -p tcp -j REDSOCKS_FILTER

# Filter all traffic that is routed over this host
# 将分组转到REDSOCKS_FILTER,以保证对分组的区分处理,作用于子网
$IPTABLES -t nat -A PREROUTING -p tcp -j REDSOCKS_FILTER

echo IPtables reconfigured.

一般来说,只需要增加白名单里的条目即可。

5. 运行
打开redsocks

./tp-socks.sh

加载iptables策略

sudo ./tp-socks.sh iptables

实例:自动使用SOCKS代理访问某微博网站

这事儿不能说太细,仅供参考

把这个网站的IP添加到脚本的白名单策略中
$IPTABLES -t nat -A REDSOCKS_FILTER -d xx.xx.xx.xx -j REDSOCKS

但是由于DNS污染,本地解析的IP可能是错误的,而且socks代理的远端DNS解析的方法不适用。解决的办法有2种:
(1) 将DNS解析,即目的端口为53的分组转发到SOCKS代理
(2) 在远程计算机上解析IP后,在/etc/hosts中将IP和站点绑定

经过以上步骤,站点成功打开。值得注意的是,这种方法应用于网关时,子网中的主机可以不用更改任何选项访问此站点。这就是透明化的好处之一

最后编辑:
作者:wy182000
这个作者貌似有点懒,什么都没有留下。

留下一个回复