- ssh サーバの設定の仕方を説明する自分用のメモである。
- 併せて mosh の設定の仕方も説明する。
セットアップ手順
ここでは公開鍵認証を使った接続に限定する。
人によって細かい点は異なるだろうが、セットアップを次のような手順で進めることを想定する。
- OpenSSH のインストール
-
openssh-server
(サーバ側) -
openssh-client
(クライアント側)
-
- ホスト名で接続する準備
-
avahi
のインストール - 必要であればホスト名の変更
-
- SSH 接続の設定
- サーバ側の
sshd_config
ファイルの書き換え - サーバ側のファイアウォールの許可設定
- クライアント側で
~/.ssh/config
ファイルを作成 - クライアント側で公開鍵を作成
- サーバ側に
~/.ssh/authorized_keys
ファイルを保存 - サーバ側の
~/.ssh/authorized_keys
ファイルの権限を変更する - デフォルトシェルの変更 (特に Windows)
- サーバ側の
- デーモンの起動/再起動
- mosh のセットアップ
これらを順に (詰まりそうな箇所を中心に、ありきたりなところは省略気味に) 説明する
OpenSSH のインストール
macOS
- OpenSSH は標準搭載
- システム環境設定 → 共有 → リモートログイン をオンにしておく
Windows 11
- "OpenSSH サーバー" のサービスを追加する
- 設定 → アプリ → オプション機能 → オプション機能を追加する
Linux (FreeBSD とかその他の OS も含む)
- 各々のディストリビューションから
openssh-server
をインストールする (標準搭載したディストリビューションもある)
ホスト名で接続する準備
macOS
- ホスト名は システム環境設定 → 共有 → 編集 から変えられる
Windows 11
- ホスト名は 設定 → システム → 名前の変更 から変えられる
- 文字数制限があることに注意
Linux
- 名前解決用に
avahi-daemon
/avahi
をインストール - ホスト名の変更の仕方の例:
-
sudo hostnamectl set-hostname [new-hostname]
の実行 -
sudo hostname [new-hostname]
の実行 -
/etc/openrc/conf.d/hostname
をhostname="[new-hostname]"
に変更
-
サーバ側の sshd_config
ファイルを書き換える
-
sshd_config
は OpenSSH サーバーの設定ファイル -
sshd_config
の設定を反映するには OpenSSH サーバーの再起動が必要。 - Unix系なら
/etc/ssh/sshd_config
に存在する。- 通常は
su
/sudo
を使わないと書き換えられない。
- 通常は
- Windowsなら
C:\ProgramData\ssh\sshd_config
に配置する。- 通常は管理者権限を得たプログラムでないと書き換えられない。
- 標準ではこの場所にファイルは置いていないので
sshd install
を実行するかC:\Windows\System32\OpenSSH\sshd_config_default
からこの場所にコピーする。
sshd_config
の変更箇所
- 下に示した箇所のコメントを外すなり、
yes
をno
に変えるなりして編集する。 - テンプレートにない項目は適宜追加する。
- macOS はOSのアップデート毎に sshd_config の内容が初期設定に戻されるので、アップデート毎に直す必要がある
- Linux 等では
openssh-server
パッケージのアップデートで sshd_config が初期状態に戻ることはあるけど、その都度注意してもらえるかな - 自動化スクリプトを用意すると楽かも
# Debian/Ubuntu 系 のみ
Include /etc/ssh/sshd_config.d/*.conf
Port 22
# 変える必要があるなら変える
Protocol 2
AddressFamily inet6
LoginGraceTime 20
PermitRootLogin no
StrictModes yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
PermitEmptyPasswords no
# 完全にパスワード認証を無効化するには、次の項目も変更したほうがよさそう
ChallengeResponseAuthentication no
# or
kbdInteractiveAuthentication no
# macOS では後述の mosh を使うために次の設定も変えておく (でもできない)
PermitUserEnvironment yes
ファイアウォールの設定
macOS
システム全体のファイアウォールをオンにしているのであれば:
システム環境設定 → セキュリティ & プライバシー → ファイアウォールオプション → リモートログイン (SSH) をオンにする
Linux : firewall-cmd
まずシステムに firewall-config
がインストールされていることを確認しよう
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=mdns # avahi-daemon
sudo firewall-cmd --permanent --add-service=ssh # openssh-server
sudo firewall-cmd --permanent --add-service=mosh # mosh
sudo systemctl restart firewalld
Linux : ufw
まずシステムに ufw
がインストールされていることを確認しよう
sudo ufw default deny
sudo ufw allow 22
sudo ufw enable
Linux : その他
よく分からない。またわかったらここに書くかも。
Windows
netsh advfirewall firewall add rule name="sshd" dir=in action=allow protocol=TCP localport=22
クライアント側で公開鍵を作る
これはクライアントの種類によりけりだしなぁ...
普通に ssh-keygen
で秘密鍵 id_rsa
と公開鍵 id_rsa.pub
ファイルを作って ~/.ssh
に入れ、サーバ側の authorized_keys
に id_rsa.pub
の内容を追記しておくのが1つの手
秘密鍵を安全に保存する方法
- 例えば macOS であれば Secretive のような App を使えば Mac の Secure Enclave に秘密鍵を保存して、認証に Touch ID を使ったり、 Secure Enclave が搭載されていない Mac でも物理的なセキュリティキーを使って認証することもできる。
- iOS デバイスであれば Termius のような ssh クライアントが Touch ID / Face ID での認証に対応する。
あとは出力された公開鍵をサーバ側の ~/.ssh/authorized_keys
に入れておく。
クライアント側で ~/.ssh/config
ファイルを作る
ssh 接続がしやすくなるために ~/.ssh/config
ファイルに接続情報は記載しておいた方が楽
~/.ssh/config
ファイルの例 (認証に App を使う例)
Host My-Computer:
Hostname Computer-Name.local
User my-name
Port 22
IdentityAgent /path/to/identity-agent/socket.ssh
- ssh の接続は
ssh My-Computer
で済む - Visual Studio Code のリモート接続もこの情報を利用する
サーバ側の ~/.ssh/authorized_keys
ファイルの権限を変更する
root や 管理者が読み取りできて且つユーザ以外が書き換えできないような権限にしておかないと Permission denied になってしまう
macOS / Linux
chmod 0700 ~/.ssh
chmod 0600 ~/.ssh/authorized_keys
Windows
C:\Users\ユーザ
以下にあるディレクトリ ~/.ssh
とファイル ~/.ssh/authorized_keys
に対して プロパティ → "セキュリティ" タブ → 詳細設定 から次のようにパーミッションを変更し、適用する
- ユーザ : フルアクセス
- Administrators : 読み取りと実行のみ
- その他 : 一覧から削除する
- 継承が有効になって権限が変更できない場合は "継承の無効化" ボタンを押し、 "継承されたアクセス許可をこのオブジェクトの明示的なアクセス許可に変換します" を押す。
デフォルトシェルの変更
macOS / Linux
基本的にログインシェルになると思うけど、書き換える方法があるのだろうか...
Windows
標準は cmd.exe
になるらしい。例えば PowerShell 7 に変更するのであれば
Get-Command pwsh.exe
でパスを確認した上で
# C:\ProgramFiles\PowerShell\7\pwsh.exe であれば
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\ProgramFiles\PowerShell\7\pwsh.exe" -PropertyType String -Force
とする。
デーモンの起動/再起動
Linux (systemd)
# デーモンの起動
sudo systemctl start sshd.service
sudo systemctl start avahi-daemon.service
# 自動的に起動するようにする
sudo systemctl enable sshd.service
sudo systemctl enable avahi-daemon.service
# デーモンの再起動
sudo systemctl restart sshd.service
sudo systemctl restart avahi-daemon.service
# ステータス
systemctl status sshd.service
systemctl status avahi-daemon.service
# ステータスでエラーが表示されるようであれば、次のコマンドを実行してエラー内容を確認する
sudo /usr/sbin/sshd -T
Linux (OpenRC)
# 自動的に起動するようにする
sudo update-rc.d ssh
# デーモンの再起動
sudo /etc/init.d/ssh restart
macOS
システム環境設定 → 共有 → リモートログイン を一度オフにしてからオンにする、或いは
sudo launchctl stop com.openssh.sshd # stop しても自動的に再起動する
Windows
管理者権限で実行
# サービスの起動
Start-Service sshd
# 自動的に起動するようにする
Set-Service sshd -StartupType Automatic
# サービスの再起動
Restart-Service sshd
mosh のセットアップ
- mosh は SSH と同じくリモート端末のシェルにアクセスできるが、接続が途切れやすい環境でもセッションが中断することなく使える。
- SSH により認証を行い、その後は UDP により接続を行う。従って、 SSH が設定され、 UDP を介した通信ができるように構成する必要がある。
Linux
- 公式サイト の手順に従い各々のディストリビューションごとに設定する。
- ファイアウォールがある場合は ssh の場合と同じく次のコマンドで。
sudo firewall-cmd --permanent --add-service=mosh
sudo systemctl restart firewalld
macOS
- Homebrew や MacPorts でインストールした後、 ssh から見て
mosh-server
の PATH が通っていることを確認する。
which mosh-server # mosh-server のバイナリの場所を確認
ssh localhost 'printenv PATH' # mosh-server の場所が $PATH に含まれているか確認
- 含まれていなかった場合、 ssh から見た PATH に追加するよう指定する
# ~/.ssh/environment で ssh から見たパスを指定する (以下は x86_64 Homebrew の例)
PATH="/usr/local/bin:/usr/bin:/bin"
# 上の設定が読み込まれるように /etc/ssh/sshd_config に以下のキーを追加
PermitUserEnvironment yes
-
ファイアウォールを有効にしている場合は
- システム環境設定 → セキュリティ & プライバシー → ファイアウォールオプション で
/usr/local/bin/mosh-server
(x86_64 Homebrew の場合) の通信を許可する - この記事 のようにカスタムシェルスクリプトを用意する
- システム環境設定 → セキュリティ & プライバシー → ファイアウォールオプション で
-
mosh-server
を許可してもアクセスできないことがある