Gentoo Linuxな生活​/サーバ設定関連

HTTPでのクライアント認証 anchor.png

HTTPでのクライアント認証はいろいろとありますね。.htaccessを使う方法、httpd.confに記述しておいて、ダイジェスト認証を使う方法など。だけど、コレだと、''ちっとセキュリティ的になんとなく心配だったり。気にしすぎなのかもしれませんが、せっかくだから、SSLを使った暗号化通信で、SSLキーのクライアント認証をしてみたい!と思った次第です。なんだか高級そうで、セキュリティも高そうだし。

Page Top

SSLでの認証の方式 anchor.png

SSL.JPG

右の図を見てみてください。SSLのシーケンスがどのように開始されるかを説明しております。まず、通信を使用とする双方(または片方)がお互いの証明書を交換し合います。お互いの証明書が間違いないかどうかを認証局(CA)という第三者機関(べりサインとかですね)に問い合わせます。これを問題なし!と判定したら、お互いに、公開鍵という公開しても問題ない暗号化するための鍵を双方で交換し合います。これを受け入れたところからSSLの暗号化通信が始まります。 で、公開鍵をなぜお互いに見せ合いしても問題ないかというと、データを暗号化する際にもらった公開鍵で暗号化します。データを受け取った側は、誰にも秘密な秘密鍵を使って暗号化を解くわけです。暗号化を解くためには、この秘密鍵でないと暗号化が解けません。なので、公開鍵がばれてしまっても、秘密鍵がわからない限り暗号は容易に解けないというわけです。いちおう設定には 自前認証局でSSLクライアント認証を参考にさせてもらってます。

Page Top

証明書の発行 anchor.png

ここで問題なのが、自分自身を証明する証明書の発行ですが、本当に第三者機関をつかうと、結構お金をとられてしまいます(1年間10万円らしい)。なので、嫌ですね。OpenSSLには、この認証局を自前で何とかする機能があります。ですが、公開組織で認証されていないため、ブラウザなどで警告が出ます(この証明書はチェックできなかったよと言われる)。ブラウザはあらかじめ登録された第三者機関に問い合わせに行くので仕方がありません。ですが、個人で運用するぶんにはコレで十分だと思います。

Page Top

準備 anchor.png

Page Top

作業場所 anchor.png

$ mkdir -p ssl/CA        ←認証局の場所
$ mkdir -p ssl/server    ←サーバ証明書の場所
$ mkdir -p ssl/client     ←クライアント証明書の場所
Page Top

/etc/ssl/openssl.cnfの設定 anchor.png

[ CA_default ]
default_days = 365 # デフォルトの証明期間(1年)

[ req ]
default_bits = 1024 # デフォルトKEY長(IE5以下のためにKEY長を512bitに)

[ req_distinguished_name ]
countryName_default = JP # デフォルト国名
stateOrProvinceName_default = Kanagawa # デフォルト州名
localityName_default = Yokohama # デフォルト地方名
0.organizationName_default = CA # デフォルト機構名
commonName_default = XXX.XXX.XX # デフォルトドメイン
emailAddress_default = foo@bar.com # デフォルトメールアドレス
Page Top

認証局を作る(認証局) anchor.png

証明書を認証する認証局を作ります。つまりはベリサインの代わりを構築するわけですね。認証局も認証するためにパスワードが必要です。覚えておきましょう

$ cd ssl/CA
$ /etc/ssl/misc/CA.sh -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Using configuration from /usr/lib/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..++++++++++++
...++++++++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase: CAのパスワード
Verifying password - Enter PEM pass phrase: 認証局のパスワード
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Kanagawa]:
Locality Name (eg, city) [Yokohama]:
Organization Name (eg, company) [CA]:
Organizational Unit Name (eg, section) [none]:
Common Name (eg, YOUR name) [XXX.XXX.XX]:
Email Address [foo@bar.com]:

これを実行すると以下ができます。

ssl/CA/ownCA/private/cakey.pem - 認証局の秘密鍵 
ssl/CA/ownCA/cacert.pem - 自己署名型の認証局証明書
Page Top

サーバ証明書&鍵 anchor.png

Page Top

サーバ証明書発行願と鍵を作る(サーバ管理者) anchor.png

まずは暗号鍵と、サーバ証明書を発行してもらうための発行願を作ります。

$ cd ssl/admin
$ openssl req -new -keyout securekey.pem -out csr.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Generating a 1024 bit RSA private key
................++++++++++++
...........++++++++++++
writing new private key to 'securekey.pem'
Enter PEM pass phrase: サーバ管理者のパスワード
Verifying password - Enter PEM pass phrase: サーバ管理者のパスワード
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Kanagawa]:
Locality Name (eg, city) [Yokohama]:
Organization Name (eg, company) [server]:
Organizational Unit Name (eg, section) [none]:
Common Name (eg, YOUR name) [XXX.XXX.XX]:
Email Address [foo@bar.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

この結果以下が出来ます。

ssl/admin/csr.pem #サーバ証明書発行願
ssl/admin/securekey.pem #サーバ秘密鍵
Page Top

認証局でサーバ証明書発行願を認証してもらう(認証局) anchor.png

サーバ証明書発酵用に、/etc/ssl/ssl.confを変更いたします。

[ usr_cert ] nsCertType = server
$ cd ssl/CA
$ cp ../admin/csr.pem . 
$ openssl ca -out server_cert.pem -infiles csr.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Enter PEM pass phrase: 認証局のパスワード
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'JP'
stateOrProvinceName :PRINTABLE:'Kanagawa'
localityName :PRINTABLE:'Yokohama'
organizationName :PRINTABLE:'server'
organizationalUnitName:PRINTABLE:'none'
commonName :PRINTABLE:'XXX.XXX.XX'
emailAddress :IA5STRING:'foo@bar.com'
Certificate is to be certified until Dec 16 01:56:12 2002 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

この結果、サーバ証明書が出来ます。

ssl/CA/server_cert.pem #認証局署名済サーバ証明
Page Top

作った証明書でサーバを運用するよう設定する(サーバ管理者) anchor.png

次に、サーバ側は、この証明書を使用するように設定しましょう。HTTPサーバですね。ただし、先ほどパスワードを設定していますから、apacheを起動するたびにパスワードを聞かれてしまいます。コレを防ぐために、セキュリティは下がりますがパスワードを解除しておきます。

# cd ssl/admin/
# openssl rsa -in securekey.pem -out securekey_unpass.pem

こうして出来たファイルを適当な場所にコピーします。例えば/etc/apache2/ssl

# cp securekey_unpass.pem /etc/apache2/ssl/securekey.pem
# cp ../CA/server_cert.pem /etc/apache2/ssl/server_cert.pem

次に、/etc/apache2/modules.d/41_mod_ssl.default-vhost.confに、コピーしたさっきのファイルを設定します。

SSLCertificateFile /etc/apache/ssl/server/server_cert.pem
SSLCertificateKeyFile /etc/apache/ssl/server/securekey.pem
Page Top

クライアント証明書&鍵 anchor.png

次にクライアントの証明書と鍵を作ります。最終的に出来たものをブラウザにインストールすると、これでクライアント(つまりは使う人)が誰であるかを特定できます。

Page Top

クライアント証明書発行願&鍵を作る(ユーザ) anchor.png

では、同じようにクライアント側の証明書発行願を作ります。これは証明書を発行して欲しい各ユーザが行います。

$ cd ssl/client
$ openssl req -new -keyout privatekey.pem -out privatecsr.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..................++++++++++++
.............++++++++++++
writing new private key to 'privatekey.pem'
Enter PEM pass phrase: クライアントのパスワード
Verifying password - Enter PEM pass phrase: クライアントのパスワード
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Kanagawa]:
Locality Name (eg, city) [Yokohama]:
Organization Name (eg, company) [server]:
Organizational Unit Name (eg, section) [none]:
Common Name (eg, YOUR name) [XXX.XXX.XX]:
Email Address [foo@bar.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

これで出来たものが

ssl/user/privatekey.pem - クライアントの秘密鍵 
ssl/user/privatecsr.pem - クライアントの証明書発行願
Page Top

クライアント証明書を発行する(認証局) anchor.png

次にユーザからクライアント証明書発行願を受け取って、認証局で証明書を発行してあげます。 先にクライアント証明書発酵用に/etc/ssl/ssl.confを変更します。

[ usr_cert ] nsCertType = client

次に発行作業です

$ cd ssl/CA
$ cp ../user/privatecsr.pem .
$ openssl ca -out private_cert.pem -infiles privatecsr.pem 
Using configuration from /usr/lib/ssl/openssl.cnf
Enter PEM pass phrase: CAのパスワード
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'JP'
stateOrProvinceName :PRINTABLE:'Kanagawa'
localityName :PRINTABLE:'Yokohama'
organizationName :PRINTABLE:'user'
organizationalUnitName:PRINTABLE:'Users Name'
commonName :PRINTABLE:'foo@bar.com'
Certificate is to be certified until Dec 16 03:11:29 2002 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

これで、クライアント側証明書ができます。

ssl/CA/demoCA/private_cert.pem

出来た証明書と、秘密鍵の2つを受け取って、ブラウザにインストールできる形にしてあげます。

$ cd ssl/CA

 このディレクトリに先ほど作ったprivate_cert.pemとprivatekey.pemを置く

$ openssl pkcs12 -export -inkey privatekey.pem -in private_cert.pem 
                    -certfile ownCA/cacert.pem -name uso -out private_cert.p12
Enter PEM pass phrase: クライアントのパスワード
Enter Export Password: ブラウザ取込用パスワード
Verifying password - Enter Export Password: ブラウザ取込用パスワード

クライアントパスワードが認証局管理者にばれてしまいますが、まぁ信頼できる人、ということでクライアントさんは信じてください(笑)逆に認証局運営者は悪用しないよう心しないといけません。

これで出来たprivate_cert.p12をユーザさんに渡してあげて、自分が使用するブラウザにインストールしてあげると、このブラウザを使用するユーザが誰なのかがわかるという仕組み。

Page Top

クライアント認証のためのapacheの設定 anchor.png

まず、クライアント認証をするために、提示されたクライアント証明書をどうやって許可されたユーザと判定するのでしょうか。これには、 先ほど作った認証局の証明書で署名されたユーザ証明書は信頼できると判断するようにしましょう。まずサーバ証明書をapacheからみえる場所にコピーします。

# cp ssl/CA/demoCA/cacert.pem /etc/apache2/conf/trustCA

次にapacheの設定を変えます。/etc/apache2/conf/modules.d/41_mod_ssl.default-vhost.confを開きます。

SSLCACertificatePath conf
SSLCACertificateFile conf/trustCA

次に、例えばWebサーバの特定の場所はかなりセキュリティ的にクリティカル(例えば会社内に構築した上司の悪口サイトとかアハハ!!(~▽~*)/≡クルッヽ( )ノギャハハ!!≡クルッ(*_ _)/バンバン!!)で、セキュアなアクセスを構築するために、以下の方針を立てます。

  • URLはhttp://foo.bar.com/board
  • SSLでの通信しか許さない
  • クライアント認証を要求する。自分が信頼する認証局で署名したユーザしか許さない

ためには、/etc/apache2/commonappache.confにこんな風に設定します。

<Directory /home/var/www/localhost/htdocs/board>
   Options -Indexes FollowSymLinks MultiViews
   AllowOverride All
   SSLRequireSSL  ←SSLでの通信以外許さない
   SSLVerifyClient require ←SSLクライアント認証を要求する
   <IfModule mod_access.c>
         Order deny,allow
         Allow from all
   </IfModule>
</Directory>

で、apacheを再起動します

# /etc/init.d/apache2 restart

これで、http://foo.bar.com/boardでアクセスするとForbiddenではじかれましたね?次に、https://foo.bar.com/boardでアクセスすると、証明書を要求されましたね?ユーザ証明書が無いブラウザでアクセスすると、アクセスがはじかれます。ユーザ証明書をインストールしたブラウザで、ユーザ証明書を選択して送ってあけると、パスワードを入力する小窓がでましたよね。ここで、自分で設定したパスワードを入力してあげると、アクセスが許可されて通信OKになります。これはセキュアだ!

Page Top

制限事項 anchor.png

SSLクライアント認証をOKにすると、アクセスするたびにパスワード聞かれるし、テキストボックスに入力して「送信」ボタンを押すようなWebページだと、「Method not Allowed」とエラーがでます。なんなんだよぅ~!お陰で結局うちでは使えませんでした。(;´д`)トホホ


Front page   Freeze Diff Backup Copy Rename ReloadPrint View   New Page Page list Search Recent changes   Help   RSS of recent changes (RSS 1.0) RSS of recent changes (RSS 2.0) RSS of recent changes (RSS Atom) Powered by xpWiki
Counter: 9379, today: 2, yesterday: 4
Princeps date: 2009-08-19 (Wed) 01:10:19
Last-modified: 2009-08-19 (Wed) 01:10:57 (JST) (3938d) by maruo
ページ内検索

ログイン

ユーザー名:


パスワード:





パスワード紛失

メインメニュー

サブメニュー
自宅鯖計画

Gentoo Linuxな生活

玄箱HGにGentoo格闘記

航空ショーへ行こう

モータースポーツな世界

奥深き写真の世界への誘い

我思う ゆえに我あり



携帯用QRコード