sudoをパスワードレス認証で使いたい
2025年12月09日 火曜日
CONTENTS
【IIJ 2025 TECHアドベントカレンダー 12/9の記事です】
昨年は「SSHでも二要素認証を使いたい」のタイトルでご紹介したSSHで二要素認証を利用する方法が好評だったので、今年はsudoをパスワードレス認証で使う方法について解説します。ちなみに、昨年の解説通りにSSHで二要素認証を行う環境が整っていれば、sudoでも二要素認証が実現します。
sudoのダメな使い方
かつては特権操作を行うとき、suコマンドを利用して一般アカウントからrootアカウントに切り替えるということがごく日常的に行われていました。ですが、自宅PCのようなプライベート環境ならばいざ知らず、業務システムを担うサーバ管理でこれはさすがにNGです。理由は枚挙にいとまがありませんが、少し考えるだけでもこれだけ挙げられます。
- rootパスワードをすべてのユーザが共有する必要があり、漏洩リスクが高い
- 監査ログに残るユーザ名がrootになり、誰が特権を行使したのか一目で判断がつかない
- rootになるとすべての操作が許可されてしまい、細かな認可の制御ができない
- 特権をはく奪すべきユーザがあっても、すぐに対応が難しい場合がある
そこで、sudoコマンドを利用するわけですが、sudoコマンドを利用さえすれば安全というものでもありません。アカウントが共有され、脆弱なパスワードが設定されていれば、sudoを利用したとてsuと大差はありません。各ユーザがユニークなidを利用し、適切に制限された権限を設定し、十分に強力なパスワードが設定されて初めて価値があると言えます。
大規模なサーバ管理の世界でユーザごとにユニークなアカウントを割り当てるには、それなりに考えられたシステム構成が必要で、それはそれでブログを一本書けるぐらいの話題なのですが、本稿の趣旨からは外れるので今回はとりあげません。何はともあれ、それを前提として話を進めます。
サーバには一切パスワードを設定しない
前述の条件を満たせば一定のセキュリティレベルを実現したと言えますが、本稿ではさらに一歩前進させ、sudoのパスワードレス認証を目指します。念のためお断りしておきますが、NOPASSWDのことではありませんよ。それではsu以下です。パスワード以外の手段でsudoの認証を行うという意味です。
今の時代、WebアプリケーションではFIDOやTOTPによって二要素認証が当たり前となり、サーバへのアクセスにはSSHでPKIに基づく認証が行われ、確実にパスワードレス認証の環境が整いつつあります。ところが、大半のサーバ環境ではsudoのために依然としてパスワードを設定することが一般的です。もしローカルアカウントに対して設定すればそのハッシュは/etc/shadowに記録され、万が一の場合には漏洩の可能性を秘めています。また、アカウント管理にLDAPを利用していても、パスワードの使いまわしによるリスクもあります。パスワードを認証に利用するデメリットについてはAIに問い合わせればいくらでも教えてくれるので、ここであらためて解説はしませんが、せっかくセキュリティレベル向上のためにsudoを利用しているのに、sudoを利用するためにパスワードを設定しなければならないのは、なんとももどかしい状況です。
本来、サーバシステムには一切パスワードなど設定したくないのです。
sudoの認証をカスタマイズするPAM
もっとも、心配することはありません。sudoコマンドがパスワードを認証に利用するのは、それがデフォルト設定であるからにすぎません。コンフィグレーションでいくらでもカスタマイズが可能です。ただし、/etc/sudoersをいくらながめても、認証方式にかかわる項目はどこにも見当たりません。なぜならsudo自身のコンフィグレーションではなく、PAM(Pluggable Authentication Modules)で管理されているからです。
PAMというのはサーバシステムの名前でも、プロトコルの名前でもありません。これはライブラリの名前です。古来よりUnix、Linuxの世界でなんらかの認証機能を備えるシステムでは広くPAMが利用され、例外なくこのライブラリがリンクされています。PAMが参照するコンフィグレーションファイルはコマンドによらず共通化されていて、かつコマンド自身のコンフィグレーションからは独立しているのです。
ただ、その用途はアプリケーションサーバやデータベースのように自身でアカウント管理機能を備えたシステムではなく、/etc/passwdなどに記録されたOSが管理するアカウントでの認証に限られます。それこそ、SSHやsudoのような。昔はもう少し用途があったのですが、今の時代にOSのアカウントをアプリケーションでも兼用するなどということはありませんので、話題に上ることは珍しくなったように感じます。
おかげで、sudoの認証方法をカスタマイズするには/etc/pam.d/sudoを編集すればよい、という情報にたどり着くにも一苦労かもしれません。それに、PAMの用途が減少した今、これから/etc/pam.dの下にあるあの複雑な設定ファイルを理解し、編集するだけの知識を身に着けるのは、言いたくありませんが徒労と言ってもよいぐらい不毛な時間です。ここではかいつまんで必要な解説だけにとどめることにします。
sudoとSSHの認証を統合する
いよいよ本題の「いかにしてsudoでパスワードレス認証を実現するか」ですが、SSH認証、より正確にはssh-agent認証を利用します。
SSHでサーバへログインするだけならば、アカウントにパスワードを設定する必要はありません。代わりに~/.ssh/authorized_keysに公開鍵を設定するだけですみます。公開鍵認証を利用しているからです。これをsudoの認証にも流用することで、sudoでパスワードレス認証を実現します。
クライアントPCでssh-agentを動かしておくと、sshでログインするときにsshdはSSHのセッションを通じてssh-agentプロトコルを利用して認証を行います。sudoでssh-agent認証を利用すると、パスワードの入力を求めるプロンプトが表示されることなく、同じことが行われます。
この仕組みのメリットは多岐にわたります。
- パスワードの管理が不要で、クレデンシャルの漏洩リスクが低い
- sshで接続された状態でなければ認証されない
- サーバシステムの脆弱性を通じてアカウントの乗っ取りが発生してもsudoには失敗する
- 認証が暗黙的に行われるため、sudoを実行するたびに認証を行っても利用上の負担がない
- sshの公開鍵認証で二要素認証を利用すれば、SSH秘密鍵の漏洩リスクも回避できる
sudoで普通にパスワード認証を利用すると、都度パスワードを入力するのは手間なので、一度認証したあと一定期間はパスワード入力を省略する設定が一般的です。本来、これは好ましいことではありません(入力機会を減らすことはメリットとも言えますが)。その点、ssh-agentを利用すれば認証は暗黙的に行われるので、常に認証を行う設定でも負担はありません。おかげで、万が一SSHの秘密鍵が漏洩したときには、authorized_keysから削除するだけですぐにでも対策が可能です。
pam_ssh_agent_authを利用する
sudoでssh-agent認証を利用する方法はとても簡単です。設定としては、/etc/pam.d/sudoに下記の一行を追加するだけで済みます。
auth sufficient pam_ssh_agent_auth.so file=~/.ssh/authorized_keys
ただ、その前にやることが二つあります。
- サーバ側でパッケージ pam_ssh_agent_auth をインストールする
- クライアント側でssh-agentをセットアップする
PAMは「プラガブル」の名前が示す通りプラグインによって機能を追加できる仕組みを備えていて、ここではssh-agentプロトコルを認証に使うプラグインpam_ssh_agent_authを利用します。主要なLinuxディストリビューションであれば標準的にパッケージが用意されていますが、デフォルトでインストールされていることはないはずなのでインストールが必要です。
また、ssh-agentプロトコルを利用するため、クライアント環境にssh-agentが必須です。もっとも、本件に限らずsshをより安全に利用するためにssh-agentは必須と考えた方がよいでしょう。
以上のコンフィグレーションを終えたら、sshに-vオプションを指定してログインしてみましょう。パスワードの入力を求められず、root権限でコマンドを実行できることがわかります。もしそれだけだと不安になるかもしれませんが、verboseオプションを設定しておけば、確かにssh-agent認証が行われていることを確認できます。
mypc $ ssh -v example.com example.com $ # ssh-addコマンドで、ssh-agentと通信できていることを確認 example.com $ ssh-add -l 256 SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx keisuk-t@iij.ad.jp (ED25519) example.com $ # sudoを実行するとプロンプトが表示されず、代わりにsshのセッションでauthentication agent connectionが開く example.com $ sudo ls ebug1: client_input_channel_open: ctype auth-agent@openssh.com rchan 2 win 65536 max 16384 debug1: channel 1: new [authentication agent connection] debug1: confirm auth-agent@openssh.com debug1: channel 1: FORCE input drain debug1: channel 1: free: authentication agent connection, nchannels 2
mypc $ ssh -v example.com example.com $ sudo ls [sudo] password for keisuk-t:
難しい設定もなく、非常に強力なパスワードレス認証が利用できるので、よかったら試してみてください。
sudoで二要素認証を利用する
さて、もう少しだけ話を続けましょう。以上の設定でsudoのパスワードレス認証が実現しましたが、さらにもう一つ上を目指します。
SSHの認証に二要素認証が構成されていれば、まったく同じ仕組みでsudoの認証も行われるのですから、sudoでも二要素認証が利用できるということです。その方法は昨年のブログで解説しているので、よかったらこちらも一読をお願いします。こちらはサーバサイドの設定は何も必要なく、クライアント側の環境整備だけで実現可能です。一番大変なのは、生体認証のデバイスを用意することかもしれません。
この場合、sudoのたびに生体認証を要求されることになりますが、指紋リーダーに指を置くことぐらい許容範囲でしょう。
この調子で「サーバ管理をパスワードレスで」を当たり前にしていきましょう。

Xのフォロー&条件付きツイートで、「IoT米」と「バリーくんシール」のセットを抽選でプレゼント!
応募期間は2025/12/01~2025/12/31まで。詳細はこちらをご覧ください。
今すぐポストするならこちら→
フォローもお忘れなく!
