【OPKSSH】SSHのシングルサインオンを、OPKSSHとEntra IDで実現する
前置き
2025年3月に、Cloudflare社がOPKSSHのオープンソース化を発表 しました。物凄くざっくり説明すると、既存のOIDC・OpenSSHの仕様を上手く応用して、手動のSSH鍵管理を不要にしたプロダクトです。技術仕様については、前述のCloudflare社ブログを読んでください。
OPKSSH(github) の 設定例 を読むと、Entra IDはデフォルト設定を利用すれば簡単に実現できそうに見えます。しかしこれは 個人用Microsoftアカウント の設定であり、多くの方が期待している「組織用テナントでのSSO」を実現するには、一手間加える必要があります。
2025年4月時点で「加えるべき一手間」に関する情報がどこにもなかったので、花見を楽しんだ後の時間で確かめました。
事前準備
IdP(Microsoft Entra ID テナント)
- テナント作成済の場合、アプリケーション管理者 以上の権限を持つアカウントを用意してください。
- テナント未作成の場合、Microsoft Entra のプランと価格 から作成してください。プランは『Microsoft Entra ID P1(2025年4月現在、1ユーザ 899円+消費税/月)』で大丈夫です。(最初の1か月は無料)
SSH Server(RHEL9.5)
- 任意のLinuxサーバを用意します。今回は RHEL9.5 を使用しました。
- 2025年4月時点のサポート対象は Ubuntu・CentOS のみですが、
sshd_config
でAuthorizedKeysCommand
とAuthorizedKeysCommandUser
が使えるOpenSSHがインストールされていれば、問題なく動作するはずです。(少なくとも RHEL9.5 では動作しました)
SSH Client(Windows11)
任意の Linux・Windows・Mac クライアントを用意します。今回は Windows11 を使用しました。
設定手順
IdP(Microsoft Entra ID テナント)
アプリの新規作成
- Azure Portal にサインイン。
-
Microsoft Entra ID > 管理 > アプリの登録 > 新規登録
をクリック。 - 以下項目を入力し
登録
をクリック。
項目名 | 入力値 |
---|---|
名前 |
OpenPubKey SSH を入力(任意の名前でOK) |
アカウントの種類 |
この組織ディレクトリのみに含まれるアカウント を選択 |
リダイレクトURI - プラットフォーム |
パブリック クライアント/ネイティブ(モバイルとデスクトップ) を選択 |
リダイレクトURI - URI |
http://localhost:3000/login-callback を入力 |
-
概要
からディレクトリ(テナント)ID
・アプリケーション(クライアント)ID
をコピーしておく。
SSH Server(RHEL9.5)
install.sh を参考に、実運用向けにアレンジしました。
1. ユーザ・グループ作成
-
グループ
groupadd --system opksshuser
-
ユーザ
useradd -r -M -s /sbin/nologin -g opksshuser opksshuser
2. インストール
-
バイナリダウンロード
wget -q --show-progress -O /usr/local/bin/opkssh https://github.com/openpubkey/opkssh/releases/latest/download/opkssh-linux-amd64
-
権限設定
chmod 755 /usr/local/bin/opkssh && chown root:opksshuser /usr/local/bin/opkssh
-
コンテキスト設定
restorecon /usr/local/bin/opkssh
3. SELinux設定
-
TE(Type Enforcement)ファイル作成
cat << 'EOF' > /tmp/opkssh.te module opkssh 1.0; require { type sshd_t; type var_log_t; type ssh_exec_t; type http_port_t; type sudo_exec_t; class file { append execute execute_no_trans open read map }; class tcp_socket name_connect; } # We need to allow the AuthorizedKeysCommand opkssh process launched by sshd to: # 1. Make TCP connections to ports labeled http_port_t. This is so opkssh can download the public keys of the OpenID providers. allow sshd_t http_port_t:tcp_socket name_connect; # 2. Needed to allow opkssh to call `ssh -V` to determine if the version is supported by opkssh allow sshd_t ssh_exec_t:file { execute execute_no_trans open read map }; # 3. Needed to allow opkssh to call `sudo opkssh readhome` to read the policy file in the user's home directory allow sshd_t sudo_exec_t:file { execute execute_no_trans open read map }; # 4. Needed to allow opkssh to write to its log file allow sshd_t var_log_t:file { open append }; EOF
-
モジュールファイルの作成
checkmodule -M -m -o /tmp/opkssh.mod /tmp/opkssh.te
-
ポリシーパッケージの作成
semodule_package -o /tmp/opkssh.pp -m /tmp/opkssh.mod
-
カーネルへのパッケージ読み込み(設定反映)
semodule -i /tmp/opkssh.pp
-
不要ファイルの削除
rm -f /tmp/opkssh.*
4. sudo設定
-
定義作成
cat << EOF > /etc/sudoers.d/opkssh opksshuser ALL=(ALL) NOPASSWD: /usr/local/bin/opkssh readhome * EOF
-
権限設定
chmod 440 /etc/sudoers.d/opkssh
5. ログ設定
-
空ログファイル作成
touch /var/log/opkssh.log && chown root:opksshuser /var/log/opkssh.log && chmod 660 /var/log/opkssh.log
-
ログローテ設定作成
cat << EOF > /etc/logrotate.d/opkssh /var/log/opkssh.log { daily ifempty compress rotate 7 dateext dateformat _%Y-%m-%d missingok } EOF
-
ログローテ設定確認
logrotate -d /etc/logrotate.d/opkssh ; echo $?
6. OPKSSH設定
作成したアプリのテナントID・クライアントIDを、あらかじめ変数に設定しておきます。
TENANT_ID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
CLIENT_ID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
/etc/opk/providers
認証を許可するIdPを定義します。詳細は OPKSSH - /etc/opk/providers をご確認ください。
-
ディレクトリ作成(存在しない場合)
mkdir -m 755 /etc/opk
-
定義作成
cat << EOF > /etc/opk/providers https://login.microsoftonline.com/${TENANT_ID}/v2.0 ${CLIENT_ID} 24h EOF
-
権限設定
chown root:opksshuser /etc/opk/providers && chmod 640 /etc/opk/providers
/etc/opk/auth_id
Linuxユーザ を引き継げる EntraIDユーザ(UPN) を定義します。所謂認可の設定です。詳細は OPKSSH - /etc/opk/auth_id をご確認ください。
-
ディレクトリ作成(存在しない場合)
mkdir -m 755 /etc/opk
-
定義作成
cat << EOF > /etc/opk/auth_id maihai maihai@example.jp https://login.microsoftonline.com/${TENANT_ID}/v2.0 EOF
-
権限設定
chown root:opksshuser /etc/opk/auth_id && chmod 640 /etc/opk/auth_id
/etc/skel/.opk/auth_id
今回は ~/.opk/auth_id
を使用しませんが、ファイルが存在しないと /var/log/opkssh.log
で以下エラーを毎回吐きます。出力が気になる方は、以下ディレクトリとファイルを追加します。
2025/04/06 16:24:09 warning: failed to load user policy: failed to read user policy file /home/xxxx/.opk/auth_id: error reading xxxx home policy using command /usr/bin/sudo -n /usr/local/bin/opkssh readhome xxxx got output Failed to read user's home policy file: failed to open /home/xxxx/.opk/auth_id, open /home/xxxx/.opk/auth_id: no such file or directory
Error: failed to open /home/xxxx/.opk/auth_id, open /home/xxxx/.opk/auth_id: no such file or directory and err exit status 1
-
ディレクトリ作成
mkdir -m 755 /etc/skel/.opk
-
ファイル作成
touch /etc/skel/.opk/auth_id && chmod 640 /etc/skel/.opk/auth_id
OpenSSH設定
今回は グループ sso_entra
に所属するユーザ のみ、Entra IDでのSSOを許可します。
-
グループ作成
groupadd sso_entra
-
対象ユーザのグループ追加
usermod -aG sso_entra ユーザ名
-
定義作成
cat << EOF > /etc/ssh/sshd_config.d/05-opkssh.conf Match Group sso_entra AllowUsers * PubkeyAuthentication yes AuthorizedKeysCommand /usr/local/bin/opkssh verify %u %k %t AuthorizedKeysCommandUser opksshuser EOF
-
定義確認
sshd -T -C user=ユーザ名 \ | grep -i -e AllowUsers -e PubkeyAuthentication -e AuthorizedKeysCommand
-
sshd再起動
systemctl restart sshd
SSH Client(Windows11)
コマンドラインは、すべてPowerShellで実行します。(管理者権限不要)
1. インストール
OPKSSHは、管理者権限不要でインストールできます。
winget install openpubkey.opkssh
2. Powershellプロファイルの編集
opkssh login
実行時のオプションを、あらかじめプロファイルに定義しておきます。
-
プロファイル新規作成(存在しない場合)
New-Item -ItemType File -Path $PROFILE -Force
-
プロファイルのパス確認
$PROFILE
-
プロファイルの編集(以下を追加)
$tenant_id = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" $client_id = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" $issuer = "https://login.microsoftonline.com/$tenant_id/v2.0" $provider = "$issuer,$client_id"
3. 既存鍵ペアの退避
OPKSSHは、IdP(Entra ID)ログイン成功後に以下ファイル名で鍵ペアを生成します。
上書きされたくない場合は退避してください。
- 秘密鍵 :
~/.ssh/id_ecdsa
- 公開鍵 :
~/.ssh/id_ecdsa.pub
ログイン手順
1. Entra ID
-
SSH Client(Windows11)でPowershellを開き、以下コマンドを実行する。
opkssh login --provider $provider
-
Entra IDのログイン画面が自動で開くので、自分のユーザでログインする。
-
組織の代理として同意する
にチェックを入れ、承諾
をクリックする。(使用する権限は後述) -
You may now close this window
が表示されたら、ブラウザを閉じる。
2. SSH
通常のSSHログインと同様、以下コマンドでログインします。
ssh ユーザ名@xxx.xxx.xxx.xxx
補足
Entra IDで要求されるアクセス許可
OPKSSHのSSOは、以下のアクセス許可を要求します。
アクセス制御について
実運用では、OPKSSH・Entra IDアプリ双方でアクセス制御を行うべきです。
OPKSSHの認可設定に不備があっても、Entra IDで認証自体を拒否できます。
OPKSSH
/etc/opk/auth_id
で、ユーザの認可を制限します。
Entra ID
セキュリティグループ(メーリス)単位 で、ユーザの認証を制限します。
-
Microsoft Entra ID > 管理 > エンタープライズアプリケーション > 作成したアプリ
をクリック。 -
管理 > ユーザとグループ
をクリック。 -
ユーザーまたはグループの追加
をクリックし、対象グループを追加する。
Entra ID認証時に、リダイレクトエラーが発生した場合
AADSTS50011: 要求で指定されたリダイレクト URI が一致しません を参考に、正しいリダイレクトURIを確認してください。
Discussion