マイナンバーカードでPAM認証

2017-12-23

Linux Advent Calendar 2017 の23日目です。

Linuxをサーバーとして利用している場合、SSHの公開鍵認証を使うのが一般的ですのでパスワード認証を使う機会はもう少ないだろうと思います。

しかしデスクトップPCへのログインはどうでしょうか。まだまだパスワードが使われていますし、オンプレで設置している物理サーバーのrootパスワードを複数人で共有するといった運用もまだ残っているのではないでしょうか。

こんな時、物理的な認証トークンがあればずっと安全な運用になるのですが、私達はそんなデバイスを既に持っているではありませんか。そう、マイナンバーカードです。

今回はマイナンバーカード内の鍵でLinuxにログインしたり、sudoしたり、多要素認証デバイスとしてカードを活用する方法を紹介します。

Linux

LinuxにはPAMという認証システムとアプリケーションを分離するための仕組みが用意されています。

デフォルトの認証モジュール(pam_unix.so)は/etc/shadowを参照してパスワード認証を行っていますが、パスワード認証以外にも様々な認証モジュール用意されていて、独自の認証モジュールを自作することだってできます。

PKCS#11に対応したデバイスで認証するためのpam_p11というPAMモジュールがあります。マイナンバーカードは既にOpenSC経由でPKCS#11 APIを扱えるようになっていますので、pam_p11からOpenSCのpkcs11モジュールをロードすればうまくいきそうです。

インストール

まずJPKIに対応したOpenSC 0.17とlibpam-p11をインストールします。

Debian Buster以降やUbuntu 17.10 Artful以降は標準でOpenSC 0.17が入っていますのでaptでインストールできます。 それ以外の方は自分でビルドしてください。

# apt install opensc libpam-p11

公開鍵の設置

pam_p11はユーザーのホームディレクトリに配置した公開鍵または証明書を参照してカードの所有を確認します。

公開鍵はSSHと同様に ~/.ssh/authorized_keys に設置します。 ちょっと紛らわしいですがsshdだけでなくloginやsudoなどのプログラムがPAM経由でこのファイルを参照するということです。

以下のコマンドで公的個人認証の公開鍵を配置します。

$ mkdir ~/.ssh/
$ pkcs15-tool --read-ssh-key 1 >> ~/.ssh/authorized_keys

あるいは、証明書で認証する場合は ~/.eid/authorized_certificates にPEM形式の証明書を配置します。

以下のコマンドで公的個人認証の証明書を配置します。

$ mkdir ~/.eid/
$ pkcs15-tool -r 1 >> ~/.eid/authorized_keys

PAMの設定

続いてPAMの設定を行いますが、今回はマイナンバーカードを利用した認証方式として、

  1. マイナンバーカードだけで認証
  2. マイナンバーカードとUNIXパスワードの両方を必要とする二要素認証
  3. マイナンバーカードとUNIXパスワードのどちらか一つを必要とする認証

の構成例を紹介します。

DebianやUbuntuでは共通のPAM設定ファイル/etc/pam.d/common-authに以下の様な記述が見つかるはずです。

auth   [success=1 default=ignore]      pam_unix.so nullok_secure
auth   requisite                       pam_deny.so
(略)

この辺りを変更していきます。

マイナンバーカードだけで認証

これがマイナンバーカードだけで認証する設定例です。pam_unix.soの設定をpam_p11_openssh.soで置き換えます。

-auth   [success=1 default=ignore]      pam_unix.so nullok_secure
+auth   [success=1 default=ignore]      pam_p11_openssh.so opensc-pkcs11.so
 auth   requisite                       pam_deny.so
(略)

pam_p11_openssh.soは設置した公開鍵~/.ssh/authorized_keysを参照しますので証明書を設置した場合はpam_p11_opensc.soに置き換えてください。

Ubuntuのログイン画面(gdm3)ではこの様にパスワードの代わりにカードの暗証番号を入力します。 ログイン画面

他のログインマネージャーでも動作するはずです。

マイナンバーカードとUNIXパスワードの両方を必要とする二要素認証

以下のようにpam_unix.soの前にpam_p11の設定を記述します。

+auth   [success=1 default=ignore]      pam_p11_openssh.so opensc-pkcs11.so
+auth   requisite                       pam_deny.so
 auth   [success=1 default=ignore]      pam_unix.so nullok_secure
 auth   requisite                       pam_deny.so
(略)

たとえばこれでsudo suを実行するとJPKI認証用の暗証番号を入力した後に通常のパスワードを入力し両方の認証が通ってからrootに成れます。

$ suod su
Password for token User Authentication PIN (JPKI): ****
[sudo] hamano のパスワード: ********
# id
uid=0(root) gid=0(root) groups=0(root)

マイナンバーカードとUNIXパスワードのどちらか一つを必要とする認証

+auth   [success=2 default=ignore]      pam_p11_openssh.so opensc-pkcs11.so
 auth   [success=1 default=ignore]      pam_unix.so nullok_secure
 auth   requisite                       pam_deny.so
(略)

/etc/pam.d/以下の設定はしくじるとログインできなくなるので慎重にやりましょう。

Recent Entries

認証器としてのキーボード

Using LDAP directory for FIDO 2.0

パスポートのセキュリティ

55億円詐欺と本人確認

マイナンバーカードでPAM認証

マイナンバーカードでmacOSにログイン

マイナンバーカードでSSHする

Python Flaskでつくる LDAPログインページ

GitHub EnterpriseとLDAPで認証連携する

PythonでLDAP Persistent Search

Hot Entries