dante

http://www.inet.no/dante/

dante 是款简单的 socks 代理程序,可以实现 透明代理,配置简单

2017-02-06: Dante 1.4.2 is now available.
This is a maintenance release with various bug fixes and no new server features.

http://www.inet.no/dante/announce-1.4.2

2017 更新的 dante-1.4.2 版本在 Linux 仅修复了 CFLAGS 导致的编译错误:

configure check 'prototypes' FAILED with CFLAGS '-grecord-gcc-switches'

之前其他的 patch 还得继续用 -_-;

rpmbuild

安装 rpmbuild 编译环境以及 dante 编译依赖:

yum install -y autoconf automake binutils gcc make rpm-build rpmdevtools
yum install -y bison flex glibc-devel libtool pam-devel

patch

源码编译安装需要 3 处修改:

  1. socksify 环境变量配置补丁
  2. HAVE_SENDBUF_IOCTL 补丁
  3. AM_CONFIG_HEADER 宏升级

patch1

修复 socksify 环境变量,不然安装 rpm 包提示 libsocks.so.0 依赖库缺失错误:

# rpm -ivh dante-1.4.2-1.el7.centos.x86_64.rpm
error: Failed dependencies:
    libsocks.so.0()(64bit) is needed by dante-1.4.2-1.el7.centos.x86_64

patch 文件参考 gentoo ebuild 补丁:

https://gitweb.gentoo.org/repo/gentoo.git/tree/net-proxy/dante/files/dante-1.4.0-socksify.patch

patch2

另一个 patch 是修改 HAVE_SENDBUF_IOCTL 参考 gentoo, suse 的补丁:

https://gitweb.gentoo.org/repo/gentoo.git/tree/net-proxy/dante/files/dante-1.4.0-HAVE_SENDBUF_IOCTL.patch

https://build.opensuse.org/package/view_file/server:proxy/dante/dante-1.4.0-sendbuf_macro.patch

patch3

还有 autoconf 已经 弃用 AM_CONFIG_HEADER 宏,替换为 AC_CONFIG_HEADERS

error: 'AM_CONFIG_HEADER': this macro is obsolete.
You should use the 'AC_CONFIG_HEADERS' macro instead.

https://build.opensuse.org/package/view_file/server:proxy/dante/dante.spec

touch acinclude.m4
sed -i -e 's:AM_CONFIG_HEADER:AC_CONFIG_HEADERS:' configure.ac
autoreconf --force --install --verbose

https://gitweb.gentoo.org/repo/gentoo.git/tree/net-proxy/dante/dante-1.4.1-r1.ebuild

sed -i -e 's:AM_CONFIG_HEADER:AC_CONFIG_HEADERS:' configure.ac

configure

参考官网的精简版参数以及 gentoo 和 suse 打包的参数,最终:

%configure --disable-static --enable-shared --with-pic --with-libc=$DANTE_LIBC \
    --enable-preload --enable-clientdl --enable-serverdl --enable-drt-fallback \
    --without-gssapi --without-libwrap --without-upnp --without-glibc-secure \
    --sysconfdir=/etc/dante --with-socks-conf=/etc/dante/socks.conf \
    --with-sockd-conf=/etc/dante/sockd.conf

官网 Prod 版本的二进制编译参数,主要用作 socks 代理,去掉扩展参数:

https://www.inet.no/dante/sslfiles/binaries.html

--without-gssapi
--without-upnp (UPnP support disabled)
--without-libwrap (libwrap support disabled)

源码中自带的 dante-1.4.2/SPECS/dante.spec 编译参数:

%configure --without-glibc-secure %{_extraflags}

gentoo ebuild 的 编译依赖 以及 编译参数

https://gitweb.gentoo.org/repo/gentoo.git/tree/net-proxy/dante/dante-1.4.1-r1.ebuild

IUSE="debug kerberos pam selinux static-libs tcpd upnp"

CDEPEND="
    kerberos? ( virtual/krb5 )
    pam? ( virtual/pam )
    tcpd? ( sys-apps/tcp-wrappers )
    upnp? ( net-libs/miniupnpc:= )
    userland_GNU? ( virtual/shadow )
"
DEPEND="${CDEPEND}
    sys-devel/bison
    sys-devel/flex
"

econf \
        --with-socks-conf="${EPREFIX}"/etc/socks/socks.conf \
        --with-sockd-conf="${EPREFIX}"/etc/socks/sockd.conf \
        --enable-preload \
        --enable-clientdl \
        --enable-serverdl \
        --enable-drt-fallback \
        --with-libc=libc.so.6 \
        $(use_enable debug) \
        $(use_with kerberos gssapi) \
        $(use_with pam) \
        $(use_with upnp) \
        $(use_enable static-libs static) \
        $(use_with tcpd libwrap)

openSUSE 的 spec 文件:https://build.opensuse.org/package/view_file/server:proxy/dante/dante.spec

%build
DANTELIBC=`find /%{_lib}/ -maxdepth 1 -iname "libc.so.*"`

%configure \
  --disable-static \
  --with-pic \
  --enable-preload \
  --enable-clientdl \
  --enable-serverdl \
  --enable-drt-fallback \
  --enable-shared \
  --with-libc=$DANTELIBC

最终完成的 spec 文件:

https://github.com/lvii/outman/blob/master/dante/SPECS/dante-1.4.2.spec

  1. 下载 spec 文件到 ~/rpmbuild/SPECS/ 目录:
  2. 下载 补丁配置文件~/rpmbuild/SOURCES/ 目录
  3. 使用 spectool 下载源码
  4. 使用 rpmbuild 打包

编译所需的 源码

# mkdir -pv ~/rpmbuild/{SOURCES,SPECS}

## 下载 spec, patch 等文件到相关路径

# spectool -l -A -R ~/rpmbuild/SPECS/dante-1.4.2.spec
Source0: http://www.inet.no/dante//files/dante-1.4.2.tar.gz
Source1: sockd.service
Source2: sockd.init
Patch0: dante-1.4.2-sendbuf_macro.patch
Patch1: dante-1.4.2-socksify.patch

# spectool -g -A -R ~/rpmbuild/SPECS/dante-1.4.2.spec
Getting http://www.inet.no/dante//files/dante-1.4.2.tar.gz to /root/rpmbuild/SOURCES/dante-1.4.2.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1254k  100 1254k    0     0  1064k      0  0:00:01  0:00:01 --:--:-- 1068k

# spectool -g -A -R ~/rpmbuild/SPECS/dante-1.4.2.spec

# rpmbuild -bb --clean ~/rpmbuild/SPECS/dante.spec

install

编译完成后,编译好的 rpm 包位于 ~/rpmbuild/RPMS/x86_64/ 目录

yum install ~/rpmbuild/RPMS/x86_64/dante-1.4.2-1.el7.centos.x86_64.rpm

也可以使用 yum 直接安装在 Fedora Copr 平台上为 CentOS7 打包的 rpm 包:

yum install https://copr-be.cloud.fedoraproject.org/results/outman/dante/epel-7-x86_64/00515912-dante/dante-1.4.2-1.el7.centos.x86_64.rpm

dante 运行依赖 glibc-devel 提供的 libdl.so 库。安装好后使用 ldd 即可查看 依赖库

# ldd /usr/sbin/sockd
    linux-vdso.so.1 =>  (0x00007ffd67f44000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fa2a8208000)
    libpam.so.0 => /lib64/libpam.so.0 (0x00007fa2a7ff9000)
    libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fa2a7dc1000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fa2a7bbd000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fa2a77fc000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fa2a8510000)
    libaudit.so.1 => /lib64/libaudit.so.1 (0x00007fa2a75d3000)
    libfreebl3.so => /lib64/libfreebl3.so (0x00007fa2a73d0000)
    libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007fa2a71ca000)

# rpm -qf /lib64/libdl.so
glibc-devel-2.17-157.el7_3.1.x86_64

config

修改 sockd 服务配置文件 /etc/dante/sockd.conf 并启动 SOCKS5 代理:

logoutput: stderr
internal: 127.0.0.1 port = 1080
external: 45.67.89.10               ## <-- 公网 IP
clientmethod: none
socksmethod: none
user.privileged: root
user.unprivileged: nobody
client pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: error
}
client block {
        from: 0.0.0.0/0 to: 127.0.0.0/8
        log: error
}
socks pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        command: bind connect udpassociate
}
socks pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        command: bindreply udpreply
        log: error
}
socks block {
        from: 0.0.0.0/0 to: 127.0.0.0/8
        command: bind connect udpassociate
        log: connect error
}

启动服务:

systemctl enable sockd
systemctl start sockd

确认服务端口:

# netstat -lntpu
Proto Recv-Q Send-Q Local Address     Foreign Address    State     PID/Program name
tcp        0      0 127.0.0.1:1080    0.0.0.0:*          LISTEN    9070/sockd

KCPTUN

使用 kcptun 服务端连接 sockd 服务提供的 SOCKS 代理,提供给客户端连接使用

创建随机密码:

# cat /dev/urandom | tr -cd '[:alnum:]' | head -c16 | paste
NLe6avQOKIhpwxuM

将启动 kcptun 服务脚本 sockd.sh 放到 server_linux_amd64

#!/bin/bash

real_path=$(readlink -e $0)
exec_path=$(dirname "$real_path")
exec_file="${exec_path}/server_linux_amd64"

log=/tmp/kcptun.socks.log
key='NLe6avQOKIhpwxuM'
pid=$(pgrep -f -- "--key $key")

if [ -n "$pid" ]
then
    kill "$pid"
    rm -f "$log"
fi

"$exec_file" --nocomp --crypt salsa20 --key "$key" -t "127.0.0.1:1080" -l ":10101" \
--mode manual --nodelay 0 --interval 20 --resend 2 --nc 1 --mtu 1350 --dscp 46 \
--datashard 64 --parityshard 16 --log "$log" &

pgrep -af -- "--key $key

kcptun 服务启动后,可以看到对应端口:

# netstat -lnup
Proto Recv-Q Send-Q Local Address    Foreign Address    State    PID/Program name
udp        0      0 0.0.0.0:10101    0.0.0.0:*                   9037/./server_linux

在 Linux 客户端可以使用 kcptun 客户端就可以在本地创建 SOCKS5 代理了:

#!/bin/bash

real_path=$(readlink -e $0)
exec_path=$(dirname "$real_path")
exec_file="${exec_path}/client_linux_amd64"
pass_word="NLe6avQOKIhpwxuM"

IP=45.67.89.10
log=/tmp/kcptun.socks.log
pid=$(pgrep -f -- "--key $pass_word")

if [ -n "$pid" ]
then
    kill "$pid"
    rm -f /tmp/kcptun.log
fi

"$exec_file" --nocomp --crypt salsa20 --key "$pass_word" -r "${IP}:10101" -l ":9090" \
--mode manual --nodelay 0 --interval 20 --resend 2 --nc 1 --mtu 512 --dscp 46 \
--sndwnd 256 --rcvwnd 512 --datashard 64 --parityshard 16 --log "$log" &

kcptun 客户端启动后出现 9090 端口的 SOCKS5 代理,配合浏览器代理插件就可以科学上网了:

# netstat -lntp
Proto Recv-Q Send-Q Local Address    Foreign Address    State     PID/Program name
tcp        0      0 0.0.0.0:9090     0.0.0.0:*          LISTEN    1898/client_linux_a