17

まず、私は SSL の設定が初めてであることに注意してください。以前は、IT 部門が事前にセットアップしてくれるという幸運に恵まれていました。そのため、あなたの回答のいくつかについて説明を求める必要がある可能性に備えてください. =)

私がやろうとしていること

従業員向けの社内イントラネット Web サイトをセットアップしています。たとえば、従業員ごとにカスタマイズされたコンテンツを表示するブラウザーの開始ページがあります。そのため、ユーザー名/パスワードやその他のプロンプトを必要とせずに、その従業員を識別できる必要があります (ただし、1 回限りのセットアップは問題ありません。毎回プロンプトを表示する必要はありません)。当然のことながら、これを行うには SSL が最適な方法のように思われます。

「ユーザー」アカウントを SSL_CLIENT_M_SERIAL および SSL_CLIENT_I_DN に関連付けるために MySQL データベースをセットアップします。これは、クライアント証明書ごとに一意であると想定しています (?)。この記事からそのアイデアを得ました: http://cweiske.de/tagebuch/ssl-client-certificates.htm

ユーザーが最初に内部 Web サイトにアクセスするとき、証明書はありません (クライアント用に手動で生成したくありません!)。その場合、$_SERVER["SSL_CLIENT_VERIFY"] == "NONE" になります。その場合、ユーザー アカウントのセットアップ ページに移動します。このページには、PHP が SSL クライアント証明書を生成し、それをブラウザーに送信してユーザーがインストールする手順が含まれます。素敵でシンプル。次に、ユーザーが証明書をインストールすると、関連付けが行われ、ブラウザーを再起動した後 (適切な測定のために)、ユーザーは内部 Web サイトに戻ります。

この時点で、Apache はクライアント証明書を要求する必要があり、ブラウザはそれを送信します。次に、PHP スクリプトは必要な $_SERVER 変数を解析し、MySQL データベースと比較します。繰り返しますが、素晴らしくシンプルです。

これまでに機能していること

サーバー側の証明書がインストールされています。はい、それらは自己署名されています (明らかな理由により)。Apache には mod_ssl がインストールされており、すべて正常に動作しているようです。$_SERVER 配列をダンプするだけの PHP スクリプトを作成しました。すべての SSL_SERVER_* キー値は、作成した証明書と一致します。

問題

クライアント証明書が機能しません。その同じ PHP スクリプトでは、何をしても SSL_CLIENT_VERIFY == "NONE" と他の SSL_CLIENT_* キーがありません。これは、SSLVerifyClient を ssl.conf でオプションに設定した場合に発生します。私が読んだすべてのチュートリアルによると、それらはすべて、Webサーバーがブラウザーにクライアント証明書を要求する必要があると言っています。事は、私はそれをすることができません! PHP スクリプトに直接進み、クライアント証明書がまったくないことを前提としています。これは、Firefox、Chrome、および IE で発生します。

そこで、SSLVerifyClientをrequiredに設定してWebサーバーを再起動してみました。そのオプションを設定すると、SSL 接続を確立することさえできなくなります。Firefox は、接続がリセットされたと言うだけです (他のブラウザーも独自のバージョンのエラーを表示します)。奇妙なのは、これらの接続試行のアクティビティがログにまったく表示されないことです! すなわち、access_log、error_log、ssl_access_log、ssl_error_log、および ssl_request_log はすべて何も表示しませ。あたかもその試みが一度も起こらなかったかのようです。これは、作業するエラー メッセージがないことを意味するため、イライラします。地獄に行くように私に積極的に言っているだけのウェブサーバー。

PHP の OpenSSL 拡張機能を使用して、独自のクライアント証明書を手動で生成/インストールしようとしました。証明書は問題なくインストールされましたが、その証明書をサーバーの証明書に関連付ける方法に関する情報が見つかりません (必要があると仮定しますか?)。また、オプションが設定されている場合、Apache はクライアント証明書を要求することさえしないため、とにかく問題ではないようです。また、require が設定されている場合は、説明なしで爆発します。このスキーマを機能させるには、とにかくオプションに設定する必要があります。

環境

OS: CentOS 5.7 64 ビット (VirtualBox)

アパッチ: 2.2.3

PHP: 5.3.10

私を助けるためにもっと情報が必要かもしれないと思うので、聞いてください!必要なものは何でもご用意します。

要約すると、上記の条件で Apache に SSL クライアント証明書を要求させる方法を知る必要があります。また、クライアント証明書をサーバー証明書と「互換性がある」ようにするために特別な署名/その他を行う必要がある場合(繰り返しますが、クライアント証明書ごとにシェルを介して手動で行う必要はありません!)、次のようにそれを知る必要があります。良い。

私は今のところこれに100%こだわっています。Google では、リモートで役立つものさえ見つかりません。これについてあなたが提供できる助けは、非常に高く評価されます!! ありがとう!=)

4

3 に答える 3

5

最初に、クライアント証明書を要求するように Apache Httpd を構成する必要があります。このためには、少なくともSSLVerifyClient optionalこの方法で認証する場所/ディレクトリで使用する必要があります。

次に、クライアントから送信された証明書は、Apache Httpd でも信頼されている必要があります。(原則として を使用SSLVerifyClient optional_no_caし、任意のクライアント証明書を Apache Httpd SSL/TLS スタックで通過させ、その後でのみ PHP 内で証明書を検証することができますが、それはかなりの作業であり、そうではないため、もう少し注意する必要があります。必然的に簡単なコード; さらに重要なことに、CA を制御しているシナリオにいるため、このコンテキストではこれはまったく役に立ちません。)

私が理解している限り、SSL_CLIENT_VERIFY(私自身はあまり使用していない変数) は、SSLVerifyClient optional_no_ca. で動作する可能性がありますがSSLVerifyClient optional、そうではないと思います。( /SSLVerifyClient require内の CA のいずれかによって) 信頼されていないクライアント証明書を使用する場合、または証明書がない場合は、接続を拒否します。私の知る限り、証明書なしまたは信頼できる証明書を使用してクライアントを通過させますが、証明書が信頼されていない場合は接続も拒否します。SSLCACertificateFileSSLCACertificatePathSSLVerifyClient optional

ここで、接続を拒否するとは、SSL/TLS 接続をアラートで突然閉じることを意味します。HTTP(S) エラー ページが生成される可能性はありません。標準のブラウザ エラーで表示されるのは、ssl_error_unknown_certificate_.... (使いやすさを考えた上でご検討ください。)

それ以降は、独自の CA を設定する必要があります。これは、ブラウザ内でキーを生成する Web ベースで、同じ Web サイト内にある可能性があります。証明書をまだ持っていないユーザーに (代わりにSSLVerifyClient require使用して) 許可する必要があるため、それは望ましくありません。optionalつまり、これらのディレクティブはホスト全体に適用する必要はありませんが、特定の場所/ディレクトリに固有のものにすることができます。

独自の Web ベースの CA を統合する (より一般的には、独自の CA を作成する) ことは、これらすべてに慣れていない場合、必ずしも簡単ではありません。既製のツール (例: OpenCA ) が存在するか、 JavaScript/ActiveXのさまざまなビットを使用して独自のツールを構築でき、SPKAC または PKCS#10 要求を処理する (および実際の証明書を発行する) サーバー側コードが必要になります。 . (このような CA を有効にするには、新しい証明書を申請するユーザーに、申請時に何らかの ID 証明、おそらくパスワードを提供してもらいたいと思うでしょう。)

これがセットアップされたら、内部 CA の CA 証明書を指すように構成SSLCACertificateFile(または...Path) する必要があります (Web ベースの CA であるかどうか、同じサイト上にあるかどうかに関係なく)。(もちろん、CA の秘密鍵は、おそらく CA の Web ベースのアプリケーション内で構成されたままにしておきますが、Apache Httpd 自体はそれを知る必要はありません。) ブラウザーは、それらの CA または中間体によって発行された証明書のみを提案します (ただし、SSLCADNRequestFile代わりに、受け入れられた CA のリストを送信するために使用されるも構成しました)。

これら 2 つの手順 (CA のセットアップとクライアント証明書を使用するための Web サイトのセットアップ) は、実際には独立していることに注意してください。両方が同じサイトの一部であるという事実は便利ですが、必須ではありません。最初に CA 全体をサイトにデプロイしなくても、Apache Httpd のセットアップを試すことができます (たとえそれが何をしているのかを確認するためだけであっても、それをお勧めします)。少数の証明書で管理できる独自の小さな CA を作成するためのツールが多数あります。たとえば、 OpenSSL の CA.plTinyCAです。これらのテスト証明書を使用することもできます(localhostおよびtestclienttestclient_rCRL を使用する場合は取り消されます。おそらく最初は不要です)。すべてのパスワードはtesttest.

(MySQL DB で) 既に予想したように、発行する証明書を管理し、それらをユーザーにマップする必要があります。SSL_CLIENT_M_SERIALただし、使用する正しい変数ではありSSL_CLIENT_I_DNません。SSL_CLIENT_I_DN発行者 DN (つまり、CA のサブジェクト DN) です。探しているのはSSL_CLIENT_S_DN、クライアント証明書のサブジェクト DN です。SSL_CLIENT_M_SERIALは証明書のシリアル番号です。証明書ごとに一意であるため、使用しないでください。1 人のユーザーが、同じサブジェクト DN を持つ複数の証明書を持つことができます (たとえば、1 つの証明書が期限切れまたは取り消された場合)。


これらすべてにもかかわらず、クライアント証明書が目標 (会社の従業員がパスワードなしでログオンできるようにする) を達成するための最良の方法であるかどうかはわかりません。

  • まず、ユーザーはとにかく自分の証明書をパスワードで保護する必要があります。あなたが本当に求めているのは、ある種のシングル サインオン (SSO) だと思います。

  • 第 2 に、ユーザーのコンピュータ リテラシーの程度によっては、実際には証明書の管理が非常に難しい場合があります。

    厳密に言えば、「証明書」という言葉には秘密鍵はまったく含まれていませんが、秘密鍵の使用を意味する場合があるという事実は、混乱を招く可能性があります。一方では、「証明書をブラウザーにインポートする」および「証明書を使用してログインする」という言葉を聞くことがあります。一方、「証明書を送信してください」と聞くこともできます。前者は、秘密鍵の使用と可用性を意味します (これらの表現では、「証明書」は単に意味.p12する場合があります)。後者には、秘密鍵を含めるべきではありません。

    ブラウザーのユーザー インターフェースは、証明書の管理やログアウトに関して非常に貧弱であったり、混乱したりする傾向があります。繰り返しますが、証明書が認識されない場合、SSL/TLS 接続は確立されないため、Web サーバーは HTML エラー ページを表示する機会がありません。

おそらく、他の形式の SSO を検討することもできます (たとえば、CAS、SAML ベースのもの、または Kerberos/SPNEGO など)。

于 2012-04-21T01:34:30.513 に答える
0

私は同様の問題を抱えています:

  • CentOS 6.3
  • アパッチ 2.2.15

いくつか試した後、私は自分の問題を認識しました。

SSLVerifyClient optionalorを設定し、 orSSLVerifyClient optional_no_caも指定した場合、構成で指定された CA 参照ファイル/パスで見つかった CA からリリースされた場合にのみ、Apache はクライアント証明書を取得します。SSLCACertificateFileSSLCACertificatePath

于 2013-01-25T08:45:05.397 に答える
-2

まだ行っていない場合は 、apacheドキュメントを参照してください。

一般的な原則は、自己署名証明書を作成し、それを使用する前に確認することです。

次に、クライアントがhttpを介してイントラネットサイトに接続しているように見えます。そこから、SSL証明書を使用してhttpsに切り替えるさまざまな方法があります。最も簡単な方法は、apacherewriteモジュールを使用することです。しかし、あなたの場合、php / mysqlチェックを行っているときに、クライアントをhttpからhttpsにリダイレクトすることができます。これは簡単な方法ではありません。

どちらの場合も(mod_rewriteによるapache自動リダイレクト、またはカスケードテスト(php / javascript / html)によるリダイレクト)、2つのvhost(1つはhttp用、もう1つはhttps用)を適切な方法で設定する必要がありますが、これはいくつかの仮説。

たとえば(debian-apache 2.2)、これはApacheによって行われる自動リダイレクトです(たとえば、上記の最初のケース):

cat / etc / apache2 / sites-available / test

# VHOST test

<VirtualHost *:80>

    DocumentRoot /home/www/test
    ServerName www.test.dev

    # ######################
    # Redirect commons
    # ######################
    RewriteEngine on
    # Case of vhosts
    RewriteOptions Inherit

    # ######################
    # Redirect (empty index)
    # ######################

    # Condition 1 to redirect : request matching with the server
    RewriteCond %{HTTP_HOST}   ^www\.test\.dev [NC]

    # Condition 2 to redirect : non empty HOST
    RewriteCond %{HTTP_HOST}   !^$

    # Automatic Empty requests Redirect
    RewriteRule ^(.*)/$ /index.php


    # ######################
    # Redirect to SSL
    # ######################
    RewriteCond %{HTTP_HOST}   ^www\.test\.dev [NC]
    RewriteCond %{HTTP_HOST}   !^$
    RewriteCond %{SERVER_PORT} ^80$
    RewriteCond %{REQUEST_URI} /

    # Redirection
    RewriteRule ^/(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

</VirtualHost>

SSLの2番目の仮想ホスト:cat / etc / apache2 / sites-available / test-ssl

# VHOST for ssl

DocumentRoot "/home/www/test"
ServerName www.test.dev

    # SSL
    SSLEngine on
    SSLCACertificateFile /etc/apache2/ssl/cur_cert/ca.pem
    SSLCertificateFile /etc/apache2/ssl/cur_cert/serveur.pem
    SSLCertificateKeyFile /etc/apache2/ssl/cur_cert/serveur.key


    <Directory "/home/www/test">
        Options FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        Allow from 127.0.0.1 192.168.0.0/16
    </Directory>


    <Directory "/home/www/test/cgi-bin">
        Options FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        Allow from 127.0.0.1 192.168.0.0/16
        Options +ExecCGI
        AddHandler cgi-script .cgi
    </Directory>

</VirtualHost>

あなたのケースはこれから少し遅れるかもしれません、例えばあなたは最初の仮想ホストにリダイレクト部分を持たず、単純な仮想ホストとhttps(ssl)のための2番目の仮想ホストだけを持っています。mysqlチェックを完了すると、リダイレクトはphp/javascriptによって実行されます。

これは、php、javascript、htmlの順に使用して、httpからhttpsへの切り替えをカスケードする方法のphpクラスからの要約の例です。

public function Redirect($url){

    if (TRUE !== Validator::isValidURL($url))
        die ("FATAL ERR: url not valid");

    // PHP ABSOLUTE URL REDIRECT (HTTP1.1)
    if (!headers_sent()) {

        header("Status: 200");
        header("Cache-Control: no-cache, must-revalidate"); // required for HTTP/1.1
        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // past Date
        header("Pragma: no-cache");
        header('Location: '.$url); // note: 302 code return by default with "Location"
        flush();
        exit();

        // if headers are already sent... do javascript redirect... if javascript is disabled, do html redirect.
    } else {

        // Js redirect
        echo '<script type="text/javascript">';
        //echo "<!--";
        echo 'document.location="'. $url .'";';
        //echo "//-->";
        echo '</script>';

        // HTML redirect if js disabled
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url="'.$url.'" />';
        echo '</noscript>';

        exit();
    }

    return FALSE;

} /* end of method (redirect) */

このアプローチを進めて特定のケースに適応させる方法をよりよく理解するのに役立つことを願っています。

于 2012-04-20T21:18:07.563 に答える