web-dev-qa-db-ja.com

nginxリクエストを認証するpam_krb5を使用したPAM

私はここと「Unix/Linux」でpam/nginxのgazzilionの質問を認識していますが、それらが未回答であるか、セットアップに関連していないため、もう一度やり直します:)

TL; dr

セットアップはApache+mod_kerb_authの組み合わせで完全に機能しますが、nginx+pam_krb5を使用すると自動チケット転送が機能しません。ただし、Kerberosに対する基本認証は機能します。問題は、何が原因であるか、および/またはそれをさらにデバッグする方法です。

以下に、すべての詳細、構成、環境を示します


私のセットアップ:

  • Windows 2012 DCラボ内(KDC用に新しくインストールおよび構成された)
  • 「サービス」としてのDebian Stretch Linux
  • そのDebianボックスには、kerb-client MIT、Apache2 + mod_kerb_auth、nignx + nginx_pam + pamがあります。
  • macOSクライアント

機能しているもの:

  • Keytabファイル、/ etc/krb5.confを使用して通常の設定を行い、realm/default_realmのすべてのビットと断片を含めます。 (下記参照)
  • KeytabファイルとSPNを使用してkinitを実行できます:HTTP/wiki.kwtest.local(以下を参照)
  • 同じDebianサーバーでApache2 + mod_kerb_authを使用すると、チケット転送を含めて完全に機能します(krb5.conf/keytab/KDC/infra setupが機能することを確認しています)。そのため、OSXでkinit + curl --negotiateまたはSafariを使用して、すぐにアクセスできます。
  • Pam auth(以下を参照)とpam設定を追加すると、safari経由でアクセスするときにADユーザー資格情報の入力を認証できます(-uによりcurlはすぐに401を取得します)...しかし、チケットの転送/検証は機能しません

セットアップ-詳細:

Kerberosクライアント構成/etc/krb5.conf

[libdefaults]
  default_realm = KWTEST.LOCAL
  kdc_timesync = 1
  # https://web.mit.edu/kerberos/krb5-1.12/doc/basic/ccache_def.html
  # we do not want the keyring due to docker
  ccache_type = 3
  forwardable = true
  proxiable = true
  # no reverse lookup
  rdns = false

[realms]
  KWTEST.LOCAL = {
    kdc = kdc.kwtest.local
    admin_server = kdc.kwtest.local
  }

[login]
  krb4_convert = true
  krb4_get_tickets = false

[logging]
  default = FILE:/var/log/kdc.log:SYSLOG
  kdc = FILE:/var/log/kdc.log:SYSLOG

# https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html?highlight=appdefaults#appdefaults
[appdefaults]
  forwardable = true
  # https://manpages.debian.org/stretch/libpam-heimdal/pam_krb5.5.en.html
  pam = {
    ignore_k5login=true
    debug=true
    forwardable = true
    proxiable = true
    minimum_uid = 0
    realm = KWTEST.LOCAL
    keytab = /mnt/config/kerberos/drupalwiki.keytab
  }

/etc/pam.d/dw-kerb-nginxでのPAM構成

cat /etc/pam.d/dw-kerb-nginx

auth  required  pam_krb5.so keytab=/mnt/config/kerberos/drupalwiki.keytab minimum_uid=20 forwardable=true realm=KWTEST.LOCAL trace=/var/log/pamtrace silent=false debug=true
account  required  pam_unix.so keytab=/mnt/config/kerberos/drupalwiki.keytab minimum_uid=20 forwardable=true realm=KWTEST.LOCAL trace=/var/log/pamtrace silent=false debug=true

/etc/nginx/sites-enabled/defaultにあるデフォルトサーバーのNginx構成

cat /etc/nginx/sites-enabled/default

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

        error_log /var/log/nginx/error.log debug;
        location / {
          auth_pam              "Secure Zone";
          auth_pam_service_name "dw-kerb-nginx";
          try_files $uri $uri/ =404;
    }
}

KVNO番号が一致します

#kdc KVNO
kvno HTTP/[email protected]
HTTP/[email protected]: kvno = 16

#client KVNO
klist -ke /mnt/config/kerberos/drupalwiki.keytab
Keytab name: FILE:/mnt/config/kerberos/drupalwiki.keytab
KVNO Principal
---- --------------------------------------------------------------------------
  16 HTTP/[email protected] (arcfour-hmac)

/mnt/config/kerberos/drupalwiki.keytabのService KeytabファイルにSPNがリストされています

klist -ke /mnt/config/kerberos/drupalwiki.keytab
Keytab name: FILE:/mnt/config/kerberos/drupalwiki.keytab
KVNO Principal
---- --------------------------------------------------------------------------
  16 HTTP/[email protected] (arcfour-hmac)

keytabファイルでのログインは、SPNを使用して機能します

kinit -k -t /mnt/config/kerberos/drupalwiki.keytab HTTP/[email protected]

klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/[email protected]

Valid starting       Expires              Service principal
01/07/2019 12:50:18  01/07/2019 22:50:18  krbtgt/[email protected]
    renew until 01/08/2019 12:50:18

質問(機能しないもの):

チケット転送、つまり既存のクライアントチケットは検証されません。代わりに、基本認証フォームが表示され、資格情報を入力します。そうすると、認証できます。したがって、基本的なkrb認証はすでに機能しており、チケットの転送/検証だけでは機能しません。

まったく同じクライアント(OSX Safari、OSX curl、Linux Curl)、まったく同じDebian StretchサーバーがApache2+mod_ker_authでも機能することに注意してください。したがって、サービスkeytabファイルまたは/etc/krb5.confを使用した単純な問題になることはほとんどありません。そうでない場合、Apache2も機能しません。

テスト方法

OSXクライアントからのテスト

# wikiuser is an user in the same AD/KDC ( not the user of the SPN)
kinit [email protected]

# ticket exists
klist
Credentials cache: API:34173A61-DFBB-4191-A39C-62EF67F1AC39
        Principal: [email protected]

  Issued                Expires               Principal
Jan  7 13:26:38 2019  Jan  7 23:26:20 2019  krbtgt/[email protected]

# the actual test
curl -u : --negotiate http://wiki.kwtest.local/index.html
<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>

Nginxを停止してApache2を起動しながら同じテストを行う

# on the Debian Service box
service nginx stop && service Apache2 start

今私のOSXボックスに

kinit
curl -u : --negotiate http://wiki.kwtest.local/index.html
worked!%

私が修正しようとしたこと

  • rsyslogとdebug = true/trace =/var/log/pamtrace設定を使用して、できるだけ詳細にpamを取得しようとしましたが、そこに出力がありませんでした。 PAMは、なんとかして認証の試みをまったく失敗させているようです。基本フォームに認証を入力して実際に正常に認証した場合にのみ、この試行がログに表示されますが、既存のチケットを使用して失敗した試行では何も記録されません
  • realmなどのすべてのpam_krb5パラメータと設定をいじってみますが、それでも機能しません
  • linuxクライアントを使用してcurlでテストしました、同じ結果

セットアップの詳細や情報に何かを忘れてしまった場合、私はケルベロスが複雑でこれらすべてのものに敏感であることを完全に認識しています。

3
Eugen Mayer

この質問に対する簡単な答えは、nginx_pamでは不可能です。

私が求める技術用語/プロトコルは「GSSAPI」またはSPENGOベースのkerberosチケット認証です。そのため、既存のkerberosチケットがある場合、ユーザーは自動的にログインします。

nginx_pamはSPENGO/GSSAPIを実装していないため、機能しません。何が起こるか

  1. 最初のリクエストでクライアントはリソースを要求します(まだ認証ヘッダーを送信していません)

  2. 私たちのnginxはnginx_pamを介してそれをpamに渡します。pamは「unauthorized」を返します(authヘッダーは存在しません)。 Nginxは、「WWW-Authorize:negotiate」というヘッダーを持つ「401」をブラウザーに返すはずです(ブラウザーは、「Authorization」ヘッダーに縁石チケットを含む新しいリクエストを自動的に送信します

  3. nginxはそのチケット(based64デコードなど)をアンパックし、チケットをpam(pam_krb)に渡す必要があります

  4. pamは "ok"または "forbidden"(このユーザーには許可されていません)を返します。前者は200、後者はクライアントに渡されたnginxの403

ステップ2はnginx_pamによって実装されていません。また、私は推測しています(わかりません)、pamは「承認済み」または「承認なし」のみをサポートしているため、ブール値であり、「非認証」、「承認済み」、「禁止」ではありません.. ..したがって、手順2と4はできません確定(同じ)

解決策:https://github.com/stnoonan/spnego-http-auth-nginx-module に切り替えました適切なGSSAPIベースの実装。

2
Eugen Mayer