MacからUbuntuデスクトップにSSHで接続する
最低限やること
UbuntuマシンにSSHサーバーをインストールする
sudo apt-get update
sudo apt-get install openssh-server
SSHが実行されていることを確認する
sudo systemctl status ssh
macOSから、以下のコマンドを使用してUbuntuマシンにSSHで接続する
usernameは whoami
から、ip_address
は ip address show
から。
NICの意味合い
Predicatable Network Interface Namesという規則に基づく
- enp1s0: en→Ethernet、p1→PCIバス1、s0→スロット0
- wlp2s0: wl→WirelessLAN、p2→PCIバス2、s0→スロット0
ssh username@ip_address
接続できなかったら以下を確認する
- SSHサービスが起動していること
- ネットワーク接続
ping ip_address
- ファイアウォール設定
sudo ufw allow ssh
セキュリティ周り
接続したら公開鍵を ~/.ssh/authorized_keys
ファイルに追加
ポート番号の変更(例として 1234
)とパスワード認証の無効化とrootログインの禁止。/etc/ssh/sshd_config
ファイルを以下のようにする。
Port 1234
PasswordAuthentication no
PermitRootLogin no
SSHサービスの再起動
sudo systemctl restart ssh
ファイアウォールで新しいポートを許可する
sudo ufw allow 1234
一旦接続できることを確認
ssh -p 1234 username@ip_address
ファイアウォールの22番ポートを削除する。Ubuntuデスクトップなので気にしなくていいが、SSH接続が唯一のアクセス方法の場合、接続できることを確認せずに古いポートを削除するとアクセスできなくなる可能性がある。
sudo ufw delete allow 22
22/tcpポートも残っている場合があるので削除する。番号つきで設定されているファイアウォールを表示することもできる。
$ sudo ufw status numbered
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
...
番号を指定して削除する方法もある。
sudo ufw delete 1
外部からアクセスさせないようにする。たとえば特定のIPアドレスのみ許可する場合。例として192.168.1.2。
sudo ufw allow from 192.168.1.2 to any port 1234
ホームネットワーク内からのみ許可する場合はCIDRを指定する。Macを同じホームネットワークに接続している場合は ifconfig
コマンドから確認できる。inetが192.168.1.5でnetmackが0xffffff00(255.255.255.0に対応)の場合のCIDRは192.168.1.0/24になる。
sudo ufw allow from 192.168.1.0/24 to any port 1234
ufwコマンドの使い方は一通りここに書いてある
UbuntuデスクトップのGUIを無効にする
後でGUIを使いたい場合もあるかもしれないので後戻りできる方法をとる
runlevel
コマンドでランレベルを確認する。GUIが起動している場合だと5になっているはず(N 5
という出力になるはず)
ランレベルとは
- ランレベル0: システムを停止(シャットダウン)
- ランレベル1: シングルユーザーモード。基本的なシェルが利用可能で、システム管理者(rootユーザー)だけがログインできるモード。ネットワークや他のサービスは無効になっている。
- ランレベル2: Ubuntuのデフォルトランレベル。ほとんどのネットワークサービスとマルチユーザーサポートを含む全てのサービスが動作している状態。通常はGUIは含まれない
- ランレベル3-5: ランレベル2と同じ機能を提供し、設定によってはGUIが起動することもある。ランレベル2との明確な差はない
- ランレベル6: システムを再起動
ランレベルを3に落とす。変更後はrebootが必要。
sudo systemctl set-default multi-user.target
なお、ランレベル5に戻すには
sudo systemctl set-default graphical.target
トラブルシュート
- ランレベル3のCLIだけ表示されている状態で、USキーボードで入力してるのにJISの配列で認識されていそう。
- 設定を変える
sudo dpkg-reconfigure keyboard-configuration
- Keyboard model は Happy Hacking にする。で、その次の案内はNoを選んでキーボードの配列とかを自分で選ぶようにする。English(US)を2回選ぶ。AltGrとComposeキーについての案内は特に設定しないでいい
- rebootする
- 設定を変える
SSH Agent Forwarding を使って SSH キーを再利用する w/ 1Password
Ubuntu デスクトップでも SSH キーを生成するのは嫌なのでフォワードして使い回す。さらに1PasswordのSSH Agent機能も使いたい。
Host hoge
HostName hoge_ip
User hoge_user
Port hoge_port
AddKeysToAgent yes
UseKeychain yes
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
ForwardAgent yes
これで接続できる
ssh hoge
フォワードされているかも確認できる
ssh-add -l
# フォワードされていない場合:
# Could not open a connection to your authentication agent.
クライアントのSSH鍵を使いまわせてるかを一応GitHubにアクセスして試してみる
ssh -T git@github.com
止めときたいとき
ssh -t username@ip_address sudo systemctl suspend
IntelliJから接続できない
根本原因として、IntelliJがssh_configのパースに失敗してるっぽい。
IntelliJのターミナルからsshコマンド叩くと接続できるが、Remote Developmentの機能(Jetbrains Gateway)使うとエラーになる。1PasswordのSSH Agent機能を使っている。
SSH Connection Check Failed
Failed to connect to IDE backend: Invalid credentials
最終的には以下によって解決した。
やったこと
IntelliJのログ出力を確認する。Help > Show Log in Finder から開ける idea.log を確認する。そうしようと思ったのは https://youtrack.jetbrains.com/issue/IDEA-263763 でログを見てたから。
こういうログが見つかった。
2023-06-23 18:20:42,551 [2376380] INFO - net.schmizz.sshj.transport.random.JCERandom - Creating new SecureRandom.
2023-06-23 18:20:42,557 [2376386] INFO - #c.i.s.SshConnectionService - Path "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" to SSH agent socket is incorrect
2023-06-23 18:20:42,559 [2376388] INFO - #c.i.s.i.s.sshj - Client identity string: SSH-2.0-IntelliJ__IDEA_IU-231.9161.38__SSHJ_0.35.0
2023-06-23 18:20:42,567 [2376396] INFO - #c.i.s.i.s.sshj - Server identity string: SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
2023-06-23 18:20:42,633 [2376462] INFO - #c.i.s.i.s.sshj - Disconnected - BY_APPLICATION
2376386のログをググったところ以下がヒット
なるほど。
if you select OpenSSH config and authentication agent, it is not able to handle SSH config files that have an IdentityAgent field that contains a space.
最終的にここに辿り着いた。
こういう理由などがありデフォルトのパーサーがLegacyになっているようだ。OpenSSHも入っているしOpenSSHに切り替えて問題なし。
it won't work if OpenSSH is not installed on the machine
パーサーを変更したら接続できた。やったー。
接続はこれに従う
追記
以下に注意書きがあった
外部からの接続を模倣するためにテザリングしてSSH接続ができないことを確認しようとしたが、接続できてしまった。これはデュアルホーム(NICを2つ以上持つデバイスのこと)な場合、複数のネットワークに同時に接続ができるからで、実際にはテザリング経由ではなく有線経由でアクセスされていたため接続できてしまったというオチだった。
有線を抜いてテザリングした状態でSSH接続したところOperation timed outになったので裏付けられた。
特に、macOSのようなモダンなOSでは、通常は接続の速度や品質、コストなどの基準に基づいて「優先的に」利用されるネットワークインターフェースが選択されます。このため、例えばEthernet(有線接続)とWi-Fi(無線接続)の両方がアクティブな場合、通常はEthernetが優先的に利用されることが多いです。
しかし、テザリング経由の接続(たとえばUSB経由のテザリングやBluetooth経由のテザリングなど)も利用可能な場合、どのインターフェースを利用するかの選択はルーティングテーブルやOSのネットワーク設定に依存します。
したがって、テザリングと有線Ethernetの両方がアクティブな場合、macOSがどちらのインターフェースを利用するかを決定します。デフォルトの設定では、通常は有線Ethernetが優先されることが多いです。ただし、明示的なルーティング設定を行うことで、この動作を変更することも可能です。
netstat -nr
のdefaultの向き先でUbuntuデスクトップのアドレス向いてるやつが有線のNICに設定されていたので、テザリングしたからといってテザリングを経由している訳ではないということが分かった