Skip to content

About

Simple, secure SSH login approval and auditing via Discord, ntfy, and Bark, with optional SSH hardening.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

DisnanaSASPAM

日本語 | English

Disnana Simple Advanced Security PAM — SSHの公開鍵・FIDO・パスワードによる一次認証成功後に、Discordで追加承認を求めるUbuntu向けPAMゲート

v1.0.0 / 正式リリース — 独立したセキュリティ監査は未完了で、本番SSHサーバーでの運用は推奨しません。GitHub Actionsでは実際のSSH/PAM承認フローを検証済みですが、FIDO実機・Discord API全体のE2E・PAM有効状態での更新障害復旧には追加検証が必要です。必ず既存の管理用SSHセッションと、SSHに依存しない復旧用コンソールを確保してください

主な機能

  • 一次認証後の承認 — sshdのPAM accountフェーズでのみゲート。SSHの認証方式自体は置き換えない
  • 物理コンソール対象外 — 変更するのは/etc/pam.d/sshdのみ。login・sudo・su・common-accountは変更しない
  • Discordロール認可 — 承認ロールIDはカンマ区切りで複数指定可能。対象サーバー・チャンネルで、許可ロールを1つ以上持ち閲覧権限のあるメンバーのみ操作可能
  • 日本語・英語 — 初回セットアップで選択。主要CLI、Discord Embed・ボタン、Bark/ntfy通知の言語を共通で切り替え
  • シンプルなボタン操作 — Discordのボタンは無言でDeferし、元のEmbedを編集して処理済みボタンを無効化。成功時の本人向け追加メッセージは出さない
  • 通知先の追加 — ntfy.sh・BarkへのHTTPS通知(承認機能はなし)
  • Fail Closed — 拒否・期限切れ・Bot停止・認証デーモン停止では勝手にログインを許可しない
  • 操作メニューと管理機能 — 矢印キーのメニュー、部分設定変更、通知テスト、任意のSSH試行制限、更新・ダウングレード・ロールバック

動作の概要

SSHの公開鍵 / FIDO / パスワード一次認証が成功
  └─ sshd の PAM account フック: pam_saspam.so (Rust)
      └─ /run/saspam/pam.sock(root専用)
          └─ saspamd(Rust製承認デーモン)
              ├─ /run/saspam/bot.sock → Discord Bot(Python・非root)
              │     └─ ロールとチャンネル権限を検証して承認 / 拒否
              └─ 任意の通知 → ntfy / Bark(通知専用)
                    ├─ 承認 → PAM_SUCCESS → SSHログイン
                    └─ 拒否・期限切れ・障害 → PAM_PERM_DENIED

Discord Botは通常のDiscord APIへ接続するため、Tailscale・NetBirdは必須ではありません。プッシュ通知から直接承認するWeb画面は、v1.0.0にはありません

インストール(まずは使い捨てUbuntu VMで)

検証対象はUbuntu 22.04・24.04のamd64・arm64、systemd、OpenSSH Serverです。その他のバージョンはすべての組み合わせを検証しているわけではありません

公開中の正式版v1.0.0を明示して導入します。正式版という区分は、独立した監査や本番運用の安全性を保証するものではありません

curl -fsSL https://raw.githubusercontent.com/disnana/DisnanaSASPAM/main/scripts/install.sh | sudo bash -s -- --version v1.0.0

GitHub ReleaseのアーカイブとSHA256SUMSを取得・照合します。インストールだけではSSHのPAM保護は有効化されません。--versionを省略するとGitHubの最新の正式Releaseを取得します。導入する版を固定するには上記の指定を使ってください。既存環境の更新は下記の更新手順を参照してください

rootでリモートスクリプトを実行する前に、保存して中身を確認することも推奨します。SHA-256は同じ公開元のチェックサムとの照合であり、独立した発行者署名の検証ではありません

初期設定と承認テスト

Discord Developer PortalでBotを作成し、Bot Token、Guild(サーバー)ID、通知Channel ID、承認Role IDを用意してください。通知先は専用の非公開チャンネルが推奨です。Botにチャンネル閲覧・送信・Embed・履歴参照の権限を付与します。特権のMessage Content Intentは不要です

sudo saspam setup       # 初回言語・Discord・通知設定
sudo saspam doctor      # sshd、PAM、認証デーモン、Botの状態確認
sudo saspam test        # PAMを変更せず、Discordの承認ボタンをテスト

承認ロールは複数指定できます。以下ではどちらか1つのロールがあれば承認・拒否できる方式(OR条件)

Discord server (guild) ID: 111111111111111111
Discord notification channel ID: 222222222222222222
Allowed Discord role IDs: 333333333333333333, 444444444444444444

実際のロール・チャンネルの閲覧権限も必要です。@everyoneロールを承認ロールとして指定することはできません

メンションは「承認ロール全員(標準)」「@everyone(追加確認あり)」「なし」から選択できます。メンション先と承認権限は別であり、@everyoneへ通知しても全員がSSHログインを承認できるようにはなりません。実際のメンション通知はBot側のDiscord権限にも依存します

SSH保護を有効にする

sudo saspam testで本当にDiscord承認できたことを確認し、現在のSSHセッションを閉じずにコンソールなどSSH以外の復旧手段を確保してください。その後に実行します

sudo saspam enable --ack-recovery --ack-tested

現在の設定に対する直近15分以内の承認テスト成功が必要です。有効化後は別ターミナルから新しいSSH接続を試し、承認・拒否・期限切れの挙動を確認してください

SASPAMによるSSH保護だけを解除する場合:

sudo saspam disable
sudo saspam status

TestDisk風メニューと設定の部分変更

Alpha.7の操作修正: SSH・PTY端末の↑↓キーでメニューが終了する問題を修正しました。ANSI CSI / SS3 / 修飾キー付きカーソルシーケンスに対応します。数字は10・11など複数桁も入力でき、EnterまたはSpaceを押してはじめて確定します。存在しない番号(例: 11項目の画面で12や111)は範囲外と表示し、メニューを終了しません。0+EnterまたはEsc・Qで戻り、Backspaceで数字を修正できます。数字を打ちかけて↑↓を押すと、入力を取り消してカーソル移動します

sudo saspam                         # ↑↓ / Enter / Space / Esc
sudo saspam menu                    # メニューを明示起動
sudo saspam config                  # 必要な設定だけを選んで変更
sudo saspam config show             # 秘密鍵などを隠して設定確認
sudo saspam config set language en  # CLI・Bot・通知を英語に変更
sudo saspam config set language ja
sudo saspam config set mentions roles
sudo saspam config set mentions none
sudo saspam config set timeout 60
sudo saspam config set roles 333333333333333333,444444444444444444
sudo saspam config set ntfy topic --generate
sudo saspam config set ntfy on
sudo saspam config set bark key     # デバイスキーは非表示で対話入力
sudo saspam config set bark on
sudo saspam notify test ntfy
sudo saspam notify test bark
sudo saspam notify test all

Bark・ntfyは通知専用です。公開プッシュサービスへは接続元IP・ホスト名などの情報が送られる場合があるため、プライバシーに注意してください

SSH保護中の設定変更はサービスの再起動で一時的に承認要求が拒否されることがあります。CLIは変更前の確認を求め、検証・再起動に失敗した場合は旧設定への復旧を試みます。無停止変更の保証ではありません

認証方式の表示(v1.0.0)

標準設定では認証方式欄を表示しません。パスワード・通常の公開鍵・FIDO鍵のいずれでも、Discord承認要求にはユーザー、接続元、承認期限と要求IDが表示されます。不明(取得不可) の欄も出しません

改造OpenSSHを別途検証・管理している利用者のみ、次のコマンドで実験的な表示をONにできます。これらのコマンドはOpenSSHのパッチ適用や再ビルドを一切実行しません

sudo saspam config show
sudo saspam config set auth-methods experimental --ack-ssh-risk --ack-recovery
sudo saspam config set auth-methods off

SSH保護を有効化済みの場合は、Botの再起動に伴う一時的な承認不能を確認する --ack-interruption も必要です。saspam の部分設定メニューからも、リスク・復旧確認後に切り替え可能です。標準UbuntuのOpenSSHでは実験モードでも認証方式を取得できず、不明(取得不可) が表示されます

改造SSHの独自配布・運用は本体のサポート対象外です。セキュリティ修正の未適用、SSHログイン不能、認証処理への影響があり得るので、独立した復旧コンソールを確保してください。実験機能のリスクと操作

認証ログを使った承認後の別の監査通知は、従来どおり任意のログ監視ツールとして利用できます

SSH認証ログの監査(alpha.6・任意)

2025年のSSHログ通知を作り直した読み取り専用の監査ツールを、別のReleaseアセットとして配布します。Ubuntu標準のOpenSSHを置き換えず、Accepted password / Accepted publickey などを解析してパスワード・通常の公開鍵・ECDSA-SK・Ed25519-SKを分類できます

SSHのPAM承認前に認証方式を表示する機能ではありません。実SSH検証ではAcceptedログが承認後にしか監視側へ届きません。v1.0.0の承認Embedは認証方式欄を標準で非表示にしており、この監査ツールで実験モードの「不明」を解消することもできません。未確認の認証方式を推測して表示することもありません

リリースファイルはSHA-256照合後に手動実行できます。自動起動・SSH保護への組み込みはありません。導入・検証手順

バージョン不要の更新(alpha.5以降)

alpha.4には自動選択機能がありません。v1.0.0を指定する下記の更新手順を使ってください。alpha.5以降はバージョン指定なしで候補を選べます

sudo saspam update            # 最近のRelease一覧から選択
sudo saspam update --list     # 利用可能な版と現在との差を表示
sudo saspam update --latest   # 最新の配布版を自動選択

対話メニューの「更新・ダウングレード」からも選択できます。更新の--latestは試験版も含めた最新の互換Releaseを選びます。v1.0.0を選ぶ場合は--version v1.0.0を使ってください。古いバージョンを選んだ場合は確認が必要です。現在の版を再配置するには --allow-reinstall を使います。各Releaseのチェックサムとアーキテクチャ互換性を確認したうえで、従来のFail Closed更新機構に処理を渡します

更新・ダウングレード・自動ロールバック

sudo saspam update --version v1.0.0 --dry-run
sudo saspam update --version v1.0.0

既にv1.0.0の場合は、意図した再配置に限って--allow-reinstallを追加します(同じ版の--dry-runにも必要です)。旧版への変更には--allow-downgradeが必要ですが、互換性を検証した版だけを指定してください。Alpha版へのダウングレードは通常の更新手順ではありません

直前の確定済み更新を取り消す必要がある場合だけ実行します:

sudo saspam update --rollback

更新処理は、新版の事前検証、旧版と設定のバックアップ、サービス切替、承認テスト、確定の順。独立したsystemdタイマーが未完了更新を検知した場合は旧版への復元を試みます。更新中もSSHのPAMフックは解除せず、承認できない接続は拒否する構成です

alpha.3以前から移行する場合は更新機構がないため、復旧経路と設定バックアップを確保し、旧版の移行手順に従ってください。alpha.4以降はPAM保護を解除せず、バージョンを指定したsaspam updateを使用します

--block-new-sshは未提供で、指定するとエラーになります。ファイアウォールを使った新規SSH接続の一時遮断は安全性検証後に対応する方針です。詳細な更新・復旧手順

任意のSSH攻撃対策

sudo saspam security audit
sudo saspam security apply --ack-recovery
sudo saspam security rollback

現在の任意設定はMaxAuthTries 4・LoginGraceTime 45・MaxStartups 10:30:60です。IPごとの時間制BANではありません。SSHポート・パスワード認証・rootログインを勝手に変更しません

SASPAMの標準承認待ち60秒とLoginGraceTime 45の整合性は、環境で別途確認が必要です。実機での挙動を確認するまでsecurity applyを安易に実行しないでください

障害・復旧・制限事項

SSHへ新しくログインできない場合、既存の管理用セッションまたは実際のコンソールから:

sudo saspam disable
sudo /usr/sbin/sshd -t
sudo saspam status
sudo journalctl -u saspamd -u saspam-discord -n 100 --no-pager

Botが停止しているときは勝手に承認されず、未承認要求は期限切れになります。認証デーモン停止時はPAMが拒否します。既存のSSHセッションや多重化済みのチャネルには再承認を要求しません

実Discord APIのすべての経路、FIDOハードウェア、PAM有効状態の障害復旧、独立したセキュリティ監査、署名・provenance検証はv1.0.0でも未完了です。本番SSHサーバーでの運用は推奨しません。DockerによるBot分離やVPN経由のBark/ntfy承認画面はv1.0.0では提供していません

ドキュメント / Documentation

内容 日本語 English
README このページ English README
インストール・設定 日本語 English
構成・権限境界 日本語 English
ロックアウト時の復旧 日本語 English
セキュリティと制限 日本語 English
更新・ダウングレード 日本語 English

日英ドキュメント一覧

ライセンス・脆弱性報告

MIT License。脆弱性の悪用可能な詳細は公開Issueへ書かず、GitHubの非公開脆弱性報告など適切な非公開窓口を利用してください

About

Simple, secure SSH login approval and auditing via Discord, ntfy, and Bark, with optional SSH hardening.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages