接続先ネットワークの諸元
接続先ネットワークの諸元を以下のように仮定する.
- 内部ネットワークのIPアドレス: 198.51.100.0/24
- 内部ネットワーク向けDNSサーバ: 198.51.100.3, 198.51.100.4
- 内部ネットワークのドメイン: internal.example.jp
- 外部ネットワークから内部ネットワークへのSSH踏台サーバ: ssh.example.jp
SSH-VPNの設定
最初に,SSH踏台サーバに接続できることを確認する.公開鍵・秘密鍵の設定については,本稿では解説しない.
$ ssh ssh.example.jp
次に,sshuttle
を直接実行してSSH-VPNを構成できることを確認する.
$ sshuttle --remote=ssh.example.jp 198.51.100.0/24 --ns-hosts 198.51.100.2,198.51.100.3
このコマンド実行時に,sudo
コマンドのパスワードプロンプトが出現する場合には,sudoers の設定が必要である.
$ sshuttle --sudoers
というコマンドを実行して,/etc/sudoers.d/sshuttle.auto
ファイルを生成する.
sshuttle
により予定通りのルーティングが実現されているかどうかは,iptables の内容を見ると確認できる.
$ sudo iptables-save | grep sshuttle
:sshuttle-23400 - [0:0]
-A PREROUTING -j sshuttle-23400
-A OUTPUT -j sshuttle-23400
-A sshuttle-23400 -m ttl --ttl-eq 63 -j RETURN
-A sshuttle-23400 -d 198.51.100.3/32 -p udp -m udp --dport 53 -j REDIRECT --to-ports 23399
-A sshuttle-23400 -d 198.51.100.4/32 -p udp -m udp --dport 53 -j REDIRECT --to-ports 23399
-A sshuttle-23400 -m addrtype --dst-type LOCAL -j RETURN
-A sshuttle-23400 -d 127.0.0.1/32 -p tcp -j RETURN
-A sshuttle-23400 -d 198.51.100.0/24 -p tcp -j REDIRECT --to-ports 23400
最後に,sshuttle
をsystemd
経由で起動できるよう設定する.まず,以下のような内容のファイルを,~/.config/systemd/user/sshuttle.service
に用意する.
[Unit]
Description=sshuttle
Requires=gpg-agent-ssh.socket
After=gpg-agent-ssh.socket
[Service]
Type=simple
Environment=SSH_AUTH_SOCK=/run/user/%U/gnupg/S.gpg-agent.ssh
ExecStart=/usr/bin/sshuttle --remote=ssh.example.jp 198.51.100.0/24 --ns-hosts 198.51.100.3,198.51.100.4
[Install]
WantedBy=default.target
以下のコマンドで,設定ファイルを読み込んでから,sshuttle
を起動する.
$ systemctl --user daemon-reload
$ systemctl --user start sshuttle.service
dnsmasqの設定
最初に,従来のresolv.conf
をdnsmasq
用にコピーする.
# cp -p /etc/resolv.conf /etc/dnsmasq.resolv.conf
次に,内部ネットワークの名前解決は内部ネットワーク向けDNSサーバに,それ以外の名前解決は通常のサーバに依頼するようdnsmasq
を設定する.
# Never forward plain names (without a dot or domain part)
domain-needed
# Never forward addresses in the non-routed address spaces.
bogus-priv
# Change this line if you want dns to get its upstream servers from
# somewhere other that /etc/resolv.conf
resolv-file=/etc/dnsmasq.resolv.conf
server=/internal.example.jp/198.51.100.3
server=/internal.example.jp/198.51.100.4
この段階で,dnsmasq
が正しく動作しているかどうか,外部ネットワークおよび内部ネットワークおよびSSH踏台サーバの名前解決がそれぞれできているかどうかを確認する.
# 外部ネットワークの名前解決確認
$ host www.google.com localhost
# 内部ネットワークの名前解決確認
$ host some-machine.internal.example.jp localhost
# SSH踏台サーバの名前解決確認
$ host ssh.example.jp localhost
筆者の環境では,SSH踏台サーバのホスト名が内部ネットワークのドメイン名と一致してしまっていたため,名前解決ができなくなるトラブルが発生した.この場合は,SSH踏台サーバの名前解決を,内部ネットワーク向けDNSで行わないよう,以下を/etc/dnsmasq.conf
に追記しておく必要がある.
server=/ssh.example.jp/8.8.8.8
なお,8.8.8.8 の部分は,適宜に適切なDNSキャッシュサーバに書き換えること.
正常に動作しているようであれば,resolv.conf
を変更して,dnsmasq
を参照するようにする.
nameserver 127.0.0.1