Google Authenticator を使用した SSH 公開鍵認証では、依然としてパスワードが要求されます

Google Authenticator を使用した SSH 公開鍵認証では、依然としてパスワードが要求されます

libpam-google-authenticator を使用して ssh で 2FA を有効にしようとしています。すべてのユーザーが認証を有効にする必要はありません。全員が ssh 公開キーを使用し、誰もパスワードを持っていません。私は Debian buster を実行しており、bullseye の libpam-google-authenticator も試しました。

私の問題は、PAM設定に何を入れても、認証が有効になっていないユーザーは直接ログインすることはなく、常にパスワードを要求されます。

libpam-google-authenticator をインストールし、/etc/ssh/sshd_config を次のように設定しました。

PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PasswordAuthentication no
PermitEmptyPasswords no

.google_authenticator ファイルを持たないユーザーでもログインできるように、正しい PAM 構成を解明できませんでした。使用しているものに応じて、ユーザーにパスワードの入力を求めるか (パスワードを持っていない)、まったくログインできないかのいずれかになります。

/etc/pam.d/sshdで試してみました(このようにUbuntu 14.04.1 で公開鍵 (パスワードなし) + Google 認証システムを使用して SSH を取得しようとしています):

#@include common-auth
auth       required     pam_google_authenticator.so debug nullok

この場合、認証システムが設定されていないユーザーは、次のデバッグで拒否されます。

Aug 05 15:11:18 <host> sshd(pam_google_authenticator)[746624]: debug: start of google_authenticator for "<user>"
Aug 05 15:11:18 <host> sshd(pam_google_authenticator)[746624]: debug: end of google_authenticator for "<user>" Result: The return value should be ignored by PAM dispatch
Aug 05 15:11:18 <host> sshd[746620]: error: PAM: Permission denied for <user> from <IP>

pam_permitフォールバックケースを設定する必要がありますか?

また、前後の とauth requiredのさまざまな組み合わせも試しましたが、いずれも認証子のないユーザーにはパスワードの入力が求められ、認証子のあるユーザーにもパスワードの入力が求められる場合があります。auth sufficient@include common-auth

これを実現するためのレシピを持っている人はいますか?

答え1

これが私の動作構成です。認証が有効になっているユーザーもいれば、有効になっていないユーザーもいます。また、公開キーを使用した SSH ログインのみが許可され、パスワードは許可されません。

/etc/ssh/sshd_configでは、

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PermitEmptyPasswords no

/etc/pam.d/sshdでは、

# Standard Un*x authentication.
#@include common-auth

# Require authenticator, if not configured then allow
auth    required    pam_google_authenticator.so debug nullok
auth    required    pam_permit.so

@include comon-auth使用したくない pam_unix が含まれているため、無効にする必要があります。次に、pam_permit認証子のないユーザーに対して認証を成功させる必要があります (認証子の場合は、pam_google_authenticatorpass ではなく ignore を返します)。

これでもまだsshキーでrootログインはできません。sshdはログに記録します。

sshd[1244501]: fatal: Internal error: PAM auth succeeded when it should have failed

これについては、SSH 上の Google Authenticator PAM が 2FA なしでのルートログインをブロック

上記のように動作させると、@zoredacheが提案したように、SSH設定を使用して特定のグループに2FAを強制する方が実際には良いと思います。これにより、特定のIPを2FAを必要としないホワイトリストに簡単に追加できます。この場合、sshd_configは次のように指定します。

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
#AuthenticationMethods any # default
PermitEmptyPasswords no

Match Group adm Address *,!172.16.1.0/24
    AuthenticationMethods publickey,keyboard-interactive

そして/etc/pam.d/sshには

 Standard Un*x authentication.
#@include common-auth

# Require authenticator; SSH should not allow any user in who doesn't have it
auth       sufficient   pam_google_authenticator.so debug nullok
auth       requisite    pam_deny.so

答え2

をコメントアウトする必要はないと思いますし、コメントアウトしたいとも思いません。@include common-auth少なくとも私はそうしませんでしたし、正しく動作しているようでした。しかし、私はまだこれをテストしているところです。

これを実現するためのレシピを持っている人はいますか?

これをシェル スクリプトに翻訳する時間はありませんが、これは私にとってはうまく機能すると思われる Ansible プレイブックの抜粋です。Ansible を使用していない場合でも、これが何をしているのかを理解できると思います。

- hosts: linux_systems
  tasks:

  - name: Add group 'totp'
    group:
      name: totp
      state: present
      system: yes

  - name: Create directory for totp secrets
    file:
      state: directory
      path: /var/lib/google-authenticator
      owner: "0"
      group: "0"
      mode: "0700"

  - name: install libpam-google-authenticator
    apt:
      update_cache: yes
      cache_valid_time: '{{ apt_cache_valid_time | default(7200) }}'
      state: present
      name:
      - libpam-google-authenticator

  - name: Create secret for 'example-user'
    args:
      creates: /var/lib/google-authenticator/example-user
    shell: |
      TOTP_USER=example-user; \
      google-authenticator \
        --force --quiet \
        --emergency-codes=10 \
        --time-based \
        --qr-mode=none \
        --allow-reuse \
        --window-size=3 \
        --rate-limit=4 --rate-time=30 \
        --secret=/var/lib/google-authenticator/${TOTP_USER}

  - name: update pam
    lineinfile:
      insertafter: '^@include common-password'
      path: /etc/pam.d/login
      line: 'auth required pam_google_authenticator.so nullok user=root secret=/var/lib/google-authenticator/${USER}'

  - name: update pam
    lineinfile:
      insertafter: '^@include common-password'
      path: /etc/pam.d/sshd
      line: 'auth required pam_google_authenticator.so nullok user=root secret=/var/lib/google-authenticator/${USER}'

  - name: update sshd ChallengeResponseAuthentication
    notify: Restart sshd
    lineinfile:
      path: /etc/ssh/sshd_config
      regexp: '^ChallengeResponseAuthentication .*'
      line: 'ChallengeResponseAuthentication yes'

  handlers:

  - name: Restart sshd
    service:
      name: sshd
      state: restarted

関連情報