ホーム » 技術 » ssh-tunnelで自宅とオヒス間をつないでみる

ssh-tunnelで自宅とオヒス間をつないでみる

さてここ1か月に渡ってプライベートオフィス(以下オヒス)の環境構築に取り組んできたのだが、残る問題が自宅とオヒスの間を結ぶネットワークだった。もともと自宅LANはCentOSをルータ代わりにした簡単なNAT環境で、難しいことは何もなかった。ここにオヒスのLANをいい感じに繋ぎたいのだが、こちらも似たような構成になっている。図にするとこうだ。

簡単にできるかと思いきや意外に面倒なところではまってしまい、途中でlibreswanを試して1週間時間を無駄にしたが、結局問題が何かが判明したのでssh-tunnelでの実装を紹介したい。

ssh-tunnelの概要

上述の図にも示した通り、プライベートIPアドレスによって構成された2つのサブネットを接続することがゴールだ。この間を繋ぐ仮想の経路をssh-tunnelで作成する。

ssh-tunnelの利用そのものは簡単だ。まず/etc/ssh/sshd_configで設定をいくつか変更する。tunnelは一方から他方へ作成すればよいので、まずc1で以下のように設定する。

PermitTunnel point-to-point

また、c1からc2へrootで適切にsshログインできるようにしておく。設定は個々でお任せする。そのうえで次のようなコマンドを実行する。

[root@c1 ~]# ssh -N -w0:0 root@c2

これでc1、c2の両方にtun0ができる。続いて双方でIPアドレスを割り当てルーティングを行う。

c1:
ip link set tun0 up
ip a add 192.168.250.1/24 peer 192.168.250.2 dev tun0
ip r add 192.168.252.0/24 via 192.168.250.2 dev tun0
c2:
ip link set tun0 up
ip a add 192.168.250.2/24 peer 192.168.250.1 dev tun0
ip r add 192.168.251.0/24 via 192.168.250.1 dev tun0

ここまでで、pingは正しく届くようになる。続いてfirewalldを設定する。まずtun0を対応付けたzoneを作る。こんな設定でよいはずだ。

firewall-cmd --permanent --new-zone=tun
firewall-cmd --permanent --zone=tun --add-interface=tun0
firewall-cmd --permanent --zone=tun --add-masquerade
firewall-cmd --reload

それからsubnetの設定がどうなっているかは環境によると思うが、一般的にはWAN側をexternal、LAN側をinternalに分けているのではないかと思う。もしinternalにmasquerade設定を入れていないのなら、ここで入れるようにする。さもないと双方のsubnetがfirewalld的に届かないことになる。

firewall-cmd --permanent --zone=internal --add-masquerade
firewall-cmd --reload

以上の設定で、c1←→c2のローカルIPアドレス、c1/c2から対抗のsubnetへの通信、subnet←→subnetの通信すべてがtunnelを通して行えるようになるはずだ。

systemdで設定を自動化する

さて以上の設定を自動化するにはどうすればよいだろうか。ssh-tunnelは最初に起動したsshプロセスがTERMINATEすると消え、それに合わせてIPアドレスもroute設定も全部消えてしまう。これらをいちいち手動で入れ直すのは面倒だ。そこでsystemdでサービス化しておき、自動起動するようにしてみよう。

2つのファイルを用意する。まず/etc/systemd/system/ssh-tunnel.serviceだ。

[Unit]
Description = ssh tunnel
After=network.target

[Service]
ExecStart = /bin/ssh -N -w0:0 root@c2
ExecStartPost = /usr/local/bin/ssh-tunnel
Restart = always
Type = simple
RestartSec=30s

[Install]
WantedBy = multi-user.target

続いて/usr/local/bin/ssh-tunnelだ。これはchmod +xしておく。

#!/bin/bash

i=0
while [[ $i -lt 10 ]]; do
        if ip tuntap | grep -q tun0; then
                break
        fi
        sleep 2
        let i++
        echo $i
done
if [[ $i -ge 5 ]]; then
        logger ssh-tunnel: connection timeout tun0
        exit 1
fi

ip link set tun0 up
ip a add 192.168.250.1/24 peer 192.168.250.2 dev tun0
ip r add 192.168.252.0/24 via 192.168.250.2 dev tun0
ssh -T root@xorn.northcave.sakura.ad.jp <<EOL
ip link set tun0 up
ip a add 192.168.250.2/24 peer 192.168.250.1 dev tun0
ip r add 192.168.251.0/24 via 192.168.250.1 dev tun0
EOL

exit 0

waitを入れているのはtunnelが起動するのにちょっと時間がかかるためだ。たぶんsleepを1つ入れておけば問題ないとは思うのだが、念のためループにしてある。また対抗側のIPアドレス設定もこちらからリモートで設定してしまう。こうすればtunnelの作成と同時に行えるのでタイミングも合う。

用意できたら起動する。

systemctl enable ssh-tunnel
systemctl start ssh-tunnel

これで自動的に設定されるようになる。ルータマシンがリブートしてもsystemdによって再接続されるので楽だ。

というわけで

これでようやくオヒスから自宅のNASをCIFSでマウントできるようになってメデタシメデタシである。スループットがいまいちなので仕事上支障がでないか心配なのでしばらくテストをしようと思っているが、もしまた何かあったら記事にしてみたい。

参考リンク