目的
- SOCKS5プロキシサーバをUbuntu 20.04上でIPv4/IPv6デュアルスタック構成で構築したい
- 一般的なプロキシサーバとしての用途でなく、接続元の隠蔽としての利用をしたい
今回は、SOCKS5プロキシを実現するため、Danteを利用する。
Ubuntuで最も簡単にDanteをインストールするにはapt install dante-server
を実行すればよいが、aptで入るDanteのバージョンはV1.2
と古い。
今回IPv6環境においてもSOCKS5プロキシを利用したいため、対応しているバージョンであるv1.4.3
をビルドして導入する。
Danteビルド
公式ページを参照のこと。
下記、簡単な手順を記す。
-
apt install gcc make
で必要なパッケージを導入する。 - 下記の通り、makeする。
# Download the source from inet.no
wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz
# Extract tarball
tar xzvf dante-1.4.3.tar.gz
# Make
cd dante-1.4.3
./configure
make
make install
- ビルドに成功すれば
/usr/local/sbin/sockd
ができているので、sockd -v
でバージョンを確認する。 -
apt
経由だとファイル名がdanted
なので、お好みでリネームする。本稿では以下danted
とリネームした前提で記載する。
Service設定
generated serviceを消す
私の環境では、/etc/init.d/danted
から自動的に生成されたsystemdサービス設定が存在したので、これを削除する。
rm /etc/init.d/dante
systemctl daemon-reload
systemctl list-unit-files --type=service | grep dante # サービスが消えたことを確認
サービス設定ファイル作成
サーバ起動時にIPアドレスがうまくバインドできず起動に失敗する事象が発生したので、暫定対応としてExecStartPre
でsleep 10
を入れている。
touch /etc/systemd/system/dante.service
vim /etc/systemd/system/dante.service
dante.service
[Unit]
Description=SOCKS (v4 and v5) proxy daemon (danted)
Documentation=man:danted(8) man:danted.conf(5)
After=network-online.target
[Service]
Type=simple
PIDFile=/run/danted.pid
ExecStart=/usr/local/sbin/danted -f /etc/danted.conf
ExecStartPre=/bin/sh -c ' \
sleep 10; \
uid=`sed -n -e "s/[[:space:]]//g" -e "s/#.*//" -e "/^user\\.privileged/{s/[^:]*://p;q;}" /etc/danted.conf`; \
if [ -n "$uid" ]; then \
touch /var/run/danted.pid; \
chown $uid /var/run/danted.pid; \
fi \
'
PrivateTmp=yes
InaccessibleDirectories=/boot /home /media /mnt /opt /root
ReadOnlyDirectories=/bin /etc /lib -/lib64 /sbin /usr
DeviceAllow=/dev/null rw
[Install]
WantedBy=network-online.target
Dante設定ファイル
うろ覚えですが、make成功時に/etc/sockd.conf
で設定ファイルが生成されていたはず。今回danted.conf
とリネームして使用。
詳細な設定内容は公式サイトとdanted.conf
のコメントを見るとすべてわかるはず。
以下に、簡単な設定内容を示す。パスワードは平文でやり取りされることに注意。
danted.conf
logoutput: /var/log/danted.log
internal: eth0 port=50001
external: eth0
socksmethod: username
clientmethod: none
user.privileged: root # 認証にusernameを使う場合はrootが必要
user.unprivileged: nobody
#user.libwrap: nobody
client pass {
from: 0/0 to: 0/0 # IPv4/IPv6すべてを通す時は0/0記法が可能
clientmethod: none # match all idented users that also are in passwordfile
socksmethod: username
}
socks block {
from: 0/0 to: lo0
log: connect error
}
socks pass {
from: 0/0 to: 0/0
command: bind connect udpassociate
log: connect error
socksmethod: username
clientmethod: none
protocol: tcp udp
}