5

jTDS を使用して SQLServer に接続しています。内部的に、jTDS は GSS を使用して kerberos のサービス チケットを取得し、安全なコンテキストを確立します。私のアプリは長期間存続し、接続は常に維持されているため、SQL サーバーが独自にそれらを更新できるようにするには、kerberos のサービス チケットを更新可能にする必要があります (kdc ポリシーは、12 時間後にすべてのチケットを期限切れにするように設定されています)。 )。

jTDS が kerberos トークンを取得するために行うことは、(多かれ少なかれ) 次のとおりです。

GSSManager manager = GSSManager.getInstance();

// Oids for Kerberos5
Oid mech = new Oid("1.2.840.113554.1.2.2");
Oid nameType = new Oid("1.2.840.113554.1.2.2.1");

// Canonicalize hostname to create SPN like MIT Kerberos does
GSSName serverName = manager.createName("MSSQLSvc/" + host + ":" + port, nameType);

GSSContext gssContext = manager.createContext(serverName, mech, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(false);
gssContext.requestCredDeleg(true);

byte[] ticket = gssContext.initSecContext(new byte[0], 0, 0);

私が疑っているのは、私が取得しているチケットは更新できないということです。次のようなことをして確認しています。

ExtendedGSSContext extendedContext = (ExtendedGSSContext) gssContext;
boolean[] flags = (boolean[]) extendedContext.inquireSecContext(InquireType.KRB5_GET_TKT_FLAGS);
System.out.println("Renewable = " + flags[8]);

特定の構成では、GSS は JAAS ログイン モジュールから kerberos TGT を取得しています。次の変数を false-Djavax.security.auth.useSubjectCredsOnly=falseに設定し、login.cfg ファイルで次のログイン モジュールを構成します。

com.sun.security.jgss.krb5.initiate {
   com.sun.security.auth.module.Krb5LoginModule required
      useKeytTab=true
      keyTab="/home/batman/.batman.ktab"
      principal="batman@GOTHAMCITY.INT"
      storeKey=true
      doNotPrompt=true
      debug=false
};

もう 1 つ気づいたことは、 のgetLifetime()方法がGSSContext機能していないように見えることです。チケットの実際の有効期間に関係なく、常に 2147483647 (最大 int) を返します。

jTDS ドライバーの分岐に慣れているので、必要に応じて GSS コンテキストを確立する方法を変更できます。

私が試したこと:

GSS API のネイティブ実装を使用します。

これは、更新可能なチケットを取得するという点ではうまく機能しますが、別の問題が発生します (チケットキャッシュが適切に設定され、そこにあるチケットが適切に更新されることを保証するという点で)。このオプションをバイパスできれば、それはいいことです。ここで私が観察したことは、getLifetime()メソッドが実際にチケットの実際の有効期間を秒単位で返すことです。

KerberosLoginModule の再実装:

この質問Jaas - Requesting Renewable Kerberos Ticketsへの回答に基づいて、LoginModule を再実装して、TGT を要求する前にKDCOptionRENEWを設定しました。KrbAsReqBuilderこれは、更新可能な TGT を取得するという意味では問題なく機能しますが、GSS がその TGT から取得したチケットはまだ更新できません。KDCOption オブジェクトのコンストラクターにブレークポイントを設定し、要求ごとに手動で RENEW フラグを設定すると ( KrbTgsReqGSS によって行われた場合でも) 動作しますが、その変更を生産的にするには、GSS を大幅に書き直す必要があり、快適ではありません。

4

1 に答える 1

1

管理者にとって、Kerberos チケットに有効期限があるという事実は重要なセキュリティ機能です。ユーザーはパスワードを知っているので、いつでも新しいチケットを取得できます。しかし、侵入者にとっては問題です。チケットの有効期限が切れると、システムへの侵入に使用できなくなります。管理者は、この有効期間をできるだけ短くしたいと考えていますが、短すぎないように (1 時間など)、ユーザーが現在よりも 10 倍多くのログイン要求を生成し、ActiveDirectory が処理するのが難しくなるためです。

Kerberos で認証する必要がある場合は、接続プール (および DataSource) を使用する必要があります。jTDS でこの機能を使用するには、ConnectionPoolImplementation を追加する必要があります (推奨: DBCP または c3p0、参照: http://jtds.sourceforge.net/features.html )。

データベースに接続する古い方法を使用してアプリケーションを作成する場合 (データソースなし、つまり、接続を作成し、作成するのに費用がかかるため、接続を維持する..)、次の障害は「ライフタイムの更新」です。ActiveDirectory では、Kerberos チケットはデフォルトで 7 日以内に更新できます。AD には 0 (無期限の更新ライフタイム) を設定できるグローバル設定がありますが、それなしでは 1 つのサービスが実行されないという理由だけで、ドメイン管理者にドメイン全体のセキュリティを下げるよう説得する必要があります。

于 2015-04-19T13:06:30.527 に答える