csatblogspotdotcom

Tuesday, January 20, 2009

代理软件tsocks

这个软件有个最大的优点就是能让应用层软件透明的使用socks代理。据其官方说法,tsocks是透明的socks代理库(transparent socks proxying library)。偶研究了下其实现方法,大概是这个样子的:
首先在系统中安装上/lib/libtsocks.so这个库以及一个/usr/bin/tsocks;
/lib/libtsocks.so就是个库文件,被/usr/bin/tsocks使用;
/usr/bin/tsocks这个文件是个shell脚本,用的是/bin/sh,所以运行时有些bug:会报basename的错(basename -bash 出错),需要在文件中basename后加上“--”,使之成为“basename -- -bash”;这个脚本的作用是设置环境变量“$LD_PRELOAD”以及作一些提示(环境变量$LD_PRELOAD设置了程序运行前优先加载的动态链接库),具体的说,若原$LD_PRELOAD为空则设之为/lib/libtsocks.so,若不为空则在原$LD_PRELOAD前加上/lib/libtsocks.so,使之优先级最高;这样在运行时,先使用/lib/libtsocks.so,会将原有的网络连接函数connect()替换为修改后的connect()函数,使网络连接的所有通信数据都经过tsocks;以下是官方解释:
about: http://tsocks.sourceforge.net/about.php
tsocks Internally
tsocks is based on the 'shared library interceptor' concept. Through use of the LD_PRELOAD environment variable or the /etc/ld.so.preload file tsocks is automatically loaded into the process space of every executed program. From there it overrides the normal connect() function by providing its own. Thus when an application calls connect() to establish a TCP connection it instead passes control to tsocks. tsocks determines if the connection needs to be made via a SOCKS server (by checking /etc/tsocks.conf) and negotiates the connection if so (through use of the real connect() function )

以下是操作过程:
首先安装软件后配置/etc/tsocks.conf,以下是俺的配置文件:
# This is the configuration for libtsocks (transparent socks)
# Lines beginning with # and blank lines are ignored
#
# This sample configuration shows the simplest (and most common) use of
# tsocks. This is a basic LAN, this machine can access anything on the
# local ethernet (192.168.0.*) but anything else has to use the SOCKS version
# 4 server on the firewall. Further details can be found in the man pages,
# tsocks(8) and tsocks.conf(5) and a more complex example is presented in
# tsocks.conf.complex.example

# We can access 192.168.0.* directly
#local = 192.168.0.0/255.255.255.0
local = 192.168.***.0/255.255.255.0

# Otherwise we use the server
#server = 192.168.0.1
server = 127.0.0.1
server_type = 5
server_port = ****
配置文件简单明了,无需解释

运行tsocks的话,有3中方式,vi /usr/bin/tsocks,里面有详细解释,俺在这里还是把/usr/bin/tsocks贴出来吧:
#!/bin/sh

### A wrapper script for the tsocks(8) transparant socksification library.
### Written by Dag Wieers .
###
### There are 3 modes of operandi:
###
### * tsocks
###
### This will socksify the current program only.
### eg.
### [user@host ~]# tsocks telnet www.foo.org
###
### * tsocks [on|off]
###
### This will socksify the current shell (and childs).
### eg.
### [user@host ~]# source /usr/bin/tsocks on
### (user@host ~)# telnet www.foo.org
### [user@host ~]# source /usr/bin/tsocks off
###
### * tsocks
###
### This will create a new socksified shell.
### eg.
### [user@host ~]# tsocks
### (user@host ~)$ telnet www.foo.org
### (user@host ~)$ exit
### [user@host ~]#

PRG="$(basename -- $0)"
LIB="/lib/libtsocks.so"

function set_socks {
if [ -z "$LD_PRELOAD" ]; then
export LD_PRELOAD="$LIB"
elif ! echo "$LD_PRELOAD" | grep -q "$LIB"; then
export LD_PRELOAD="$LIB $LD_PRELOAD"
fi
}

function unset_socks {
export LD_PRELOAD="$(echo -n "$LD_PRELOAD" | sed "s|$LIB \?||")"
if [ -z "$LD_PRELOAD" ]; then
export -n LD_PRELOAD
fi
}


case "$1" in
on) set_socks;;
off) unset_socks;;
show|sh)
if echo "$LD_PRELOAD" | grep -q "$LIB"; then
echo "$PRG: This shell is socksified."
else
echo "$PRG: This shell is NOT socksified."
fi
;;
-h|-?) echo "$PRG: Please see tsocks(1) or read comment at top of $0"
exit 1
;;
'')
set_socks
# PS1="$(echo -n "$PS1" | tr \[\] \(\)) " ${SHELL:-/bin/sh};;
PS1="(\u@\h \W)\$ " ${SHELL:-/bin/sh}
;;
*) set_socks
exec "$@"
;;
esac

查看是否进入tsocks模式(俺姑且这么称呼它),可以:
tsocks sh或者tsocks show

没有root权限时怎么办?
(from http://www.plenz.com/tunnel-everything)

If you may not become root ...

... just enter the two lines from above into a file called .tsocks.conf and place it in your home directory. Then, write a little shell script:

#!/bin/sh

TSOCKS_CONF_FILE=$HOME/.tsocks.conf
export TSOCKS_CONF_FILE
exec tsocks "$@"

I call this script viaservername. Place this script in a directory contained in your $PATH and make it executable.

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home