mac, Ubuntuでautosshとsystemd, launchdで常にPortforwardする
こんにちは.今回はssh接続を極力維持してくれるAutosshと Linux, Unixのサービス管理を行うsystemd, launchdを組み合わせて,常にssh Portforwardを行う環境を作成します.
この設定は特定のネットワーク下で閲覧・アクセスできるサイト等を閲覧する際に, 毎回sshやVPN接続をする必要がなくなります.
autosshとは
autosshはssh接続を極力維持してくれるCLIコマンドです.
インストールは以下の方法で行います.
# Ubuntu
sudo apt install autossh
# macOS
brew install autossh
コマンドの使い方はsshとほとんど変わりません.
autossh -M 0 -f -L 12022:remote:22
-M
オプションはモニターポートです.特に何もなければ0で無効にしても良いと思います.詳しくはman autossh
に記述されています.
-f
オプションはautosshをバックグラウンドで実行します.
注意として,パスワードの要求などの入力を行うことができないので,
このオプションを使用する際はリモート先にパスワードなしでログインできる必要があります.
autosshとsystemd, launchdの組み合わせ
systemdはUbuntu,launchdはmacOSのサービス管理ツールです.
systemd, launchdにautosshと登録することで,
- sshが落ちた場合はautosshが再接続
- autosshが落ちた場合はsystemd, launchdが再接続
- システム起動時はsystemd, launchdが接続
というように,より強固にssh接続を維持することができます. 今回は,ssh configに書いた設定を元にautosshする方法でポートフォワードしていきます.
事前準備
まずは事前準備として,リモート先にパスワードなしでssh接続できるようにしておきます.
sshの認証を公開鍵認証に設定しておくと良いでしょう.
ここで注意でするのは,Ubuntuで秘密鍵にパスフレーズを設定した場合です.
macOSでは~/.ssh/config
にUseKeychain
を設定することで,
ssh使用時にパスフレーズがKeychainに保存され,
自動的にssh-agentへ読み込まれるのですが,
UbuntuではKeychainがないため自分で行う必要があります.
先ほど述べたように,autosshではssh時の入力を扱うことができないため, Ubuntuでautosshする際はパスフレーズなしの秘密鍵を用意しておく必要があります. macではKeychainが良しなしにやってくれるので必要ありません. 秘密鍵のパスワードは以下のコマンドで設定・解除できます.
ssh-keygen -f ~/.ssh/id_rsa -p
上記を解決したら,初回の通常のssh接続を行います. 初回ssh時にはfingerprintの確認が行われ,応答が必要なため,autosshする際に発生しないようにするためです. 今回はssh configに書いた設定でsshしていきます.
Host remote
HostName hoge
User hoge
LocalForward 6006 localhost:6006
ssh remote
The authenticity of host 'hoge (::1)' can't be established.
ED25519 key fingerprint is SHA256:hogehogehogehoge.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
yes以外のパスワード等の入力なしで初回ログインが済んだら成功です.次に進みましょう.
autosshをサービス化する
次に,autosshをサービス化するためにコンフィグを書いていきます.
mac: Launchdの場合
まずはautosshのフルパスの場所を確認しておきましょう.
$ which autossh
/opt/homebrew/bin/autossh
今回は/opt/homebrew/bin
にあるようです.Intel macだと/usr/local/bin
にあったりします.
Launchdの設定ファイルの場所はいくつかありますが,今回はユーザーがログインした際に実行するようにします.
こうすることで,先ほど記入した~/.ssh/config
の内容が使用できるようになります.
~/Library/LaunchAgents/remote.autossh.plist
に以下の内容のファイルを置きます.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>AUTOSSH_GATETIME</key>
<integer>0</integer>
</dict>
<key>UserName</key>
<string>[username]</string>
<key>Label</key>
<string>remote.autossh</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin</string>
<string>-M</string>
<string>0</string>
<string>-N</string>
<string>remtote</string>
</array>
</dict>
</plist>
ファイルが書き込めたらlaunchdに登録していきます.この際,plistのパスは絶対パスで書いてください.
launchctl load /Users/[username]/Library/LaunchAgents/remote.autossh.plist
今回はplistにRunAtLoad
を追加しているので,loadした時点で実行も行われているはずです.確認してみます.
$ launchctl list | grep remote.autossh
57892 0 remote.autossh
左からPIDとexit code,Labelが表示されます.今回はPIDがあり,exitcode=0なので成功です. サービスから削除を行う場合はunloadを行います.
launchctl unload /Users/[username]/Library/LaunchAgents/remote.autossh.plist
ssh configを変更した場合はstop, start
で再起動を行います.
launchctl stop iplab.autossh
launchctl start iplab.autossh
Ubuntu: Systemdの場合
Ubuntuではsystemdに設定を行なっていきます. RedHat系のCentOSやAmazonLinux等でもsystemdは同じなので, 少し変えれば同じように設定できると思います.(未確認)
/etc/systemd/system/remote.autossh.service
に設定を書いていきます.
[Unit]
Description=keep ssh
After=network-online.target ssh.service
[Service]
User=[username]
Type=simple
RestartSec=3
Restart=always
TimeoutStopSec=10
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -N remote
[Install]
WantedBy=multi-user.target
最後にサービスを起動して,正常に動いているかstatusを確認し,常時起動に設定しておきます.
sudo systemctl start remote.autossh.service
sudo systemctl status remote.autossh.service
sudo systemctl enable remote.autossh.service
以上で完了です.お疲れ様でした.