CentOS 7上使用Dante sockd + PAM

迫于某些国内影音平台的版权限制和找不到合适的国外替代品*,我采用一台最低配的阿里云T5(512MiB RAM)来规避此限制。

我采用Dante sockd作为SOCKS5服务器,并用Stunnel建立SSL隧道(客户端一侧也用Stunnel做SSL卸载),以防止凭据被嗅探而成为代理池的一部分。

安装依赖,编译安装dante:

# yum install tcp_wrappers-devel pam-devel
$ cd dante-1.4.2/
$ ./configure --prefix=/opt/dante \
--with-socks-conf=/opt/dante/conf/socks.conf \
--with-sockd-conf=/opt/dante/conf/sockd.conf \
$ make
# make install
// 建立日志目录
# mkdir -p /var/log/dante

创建systemd unit:

# cat << EOF > /etc/systemd/system/dante-sockd.service
[Unit]
Description=Dante SOCKS Server
After=network.target
After=syslog.target
 
[Install]
WantedBy=multi-user.target

[Service]
Type=forking
ExecStart=/opt/dante/sbin/sockd -D -N 1
#ExecStop=/bin/kill -TERM $MAINPID
#ExecReload=/bin/kill -USR1 $MAINPID
 
# Give up if ping don't get an answer
TimeoutSec=600
 
Restart=always
PrivateTmp=false
EOF
# systemctl daemon-reload
# systemctl enable dante-sockd.service

创建logrotate配置:

# cat << EOF > /etc/logrotate.d/dante-sockd
/var/log/dante/*.log {
    weekly
    missingok
    rotate 4
    notifempty
}
EOF

Dante使用用户名-密码认证,需要在系统中建立一个账户。我认为这是有安全风险的(尽管可以将该用户的shell指向/usr/sbin/nologin)。vsftpd支持用PAM实现虚拟用户登录,而dante也支持PAM,故尝试使用基于PAM的虚拟用户。

欲使用PAM的用户名-(受慢哈希保护的)密码登录,需要pam_pwdfile.so。然而RHEL 7/CentOS 7的官方源不提供这个包,EPEL源也没有提供。故需要自行编译:

$ git clone https://github.com/tiwe-de/libpam-pwdfile
$ cd libpam-pwdfile
$ make
# cp pam_pwdfile.so /lib64/security/

建立dante的PAM配置文件:

# cat << EOF > /etc/pam.d/sockd
auth required pam_pwdfile.so pwdfile /opt/dante/conf/sockd.passwd
account required pam_permit.so
EOF

建立密码文件:

# yum install httpd-tools
# touch /opt/dante/conf/sockd.passwd
// 添加用户,可重复执行添加多个用户。
# htpasswd -p -b /opt/dante/conf/sockd.passwd USERNAME $(openssl passwd -1)
// 在交互界面输入(两次)密码

dante-sockd配置:

logoutput: /var/log/dante/sockd.log
debug: 0

internal: 127.0.0.1 port=1080
external: eth0 #根据网卡实际名称修改。

clientmethod: none
socksmethod: pam.username none

client pass {
    from: 127.0.0.1/32 to: 0.0.0.0/0
    log: error # connect disconnect
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    command: bind connect udpassociate
    log: error # connect disconnect iooperation
    socksmethod: pam.username
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    command: bindreply udpreply
    log: error # connect disconnect iooperation
    socksmethod: pam.username
}

*: 国外平台如Netflix,未购买某些作品之发行权;且Netflix的订阅较贵——欲观看全高清(1080p),需话费13.99USD每月——为了一部TV Drama或动漫而订阅显然是不值得的。