質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

SSL

SSL(Secure Sockets Layer)とは、暗号化されたプロトコルで、インターネット上での通信セキュリティを提供しています。

Q&A

1回答

3412閲覧

クライアント証明書によるアクセス制限

Take_it

総合スコア357

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

SSL

SSL(Secure Sockets Layer)とは、暗号化されたプロトコルで、インターネット上での通信セキュリティを提供しています。

0グッド

3クリップ

投稿2019/06/30 13:57

編集2019/07/01 09:07

https://centossrv.com/apache-client-authentication.shtml

を参考に(というかほぼそのまま)、クライアント証明書によるアクセス制限を試みています。

書いてある通りにやったのですが、証明書をインストールしていないのに相変わらずアクセスができてしまいます。

特に何かエラーが出ているとかでもなく、お手上げ状態です。

何を確認すればいいかとか、どんな情報が必要だとかアドバイスを頂ければ幸いです。

ConoHa VPS
CentOS Linux 7.6.1810
Apache/2.4.6 (CentOS)
Let's Encryptを使用してhttpsでのアクセスは確立済。

AllowOverride をしました。

etc/httpd/conf/httpd.conf を編集し、

<Directory "/var/www/html">のAllowOverrideをNoneからAllにしたところ、証明書を要求するとこまではいきました。

しかし正しい証明書を選択しているはずなのにアクセスできず、

このサイトは安全に接続できません
vps.*****.com でログイン証明書が承認されなかったか、ログイン証明書が提示されていない可能性があります。
システム管理者にお問い合わせください。

となります。

原因として、AllowOverrideについてご指摘頂く前に見ていたのですが、

BASIC認証用ユーザーデータベース(例:/etc/httpd/conf/.htpasswd)がない場合=1件目の場合 [root@centos ~]# htpasswd -bcm /etc/httpd/conf/.htpasswd `openssl x509 -noout -subject -in /etc/pki/CA/certs/ユーザー名.crt |sed -e 's/subject= ([^ ]*)/\1/p' -e d` password ← クライアント証明書をBASIC認証用ユーザーデータベース(例:/etc/httpd/conf/.htpasswd)へ登録 BASIC認証用ユーザーデータベース(例:/etc/httpd/conf/.htpasswd)がある場合=2件目以降の場合 [root@centos ~]# htpasswd -bm /etc/httpd/conf/.htpasswd `openssl x509 -noout -subject -in /etc/pki/CA/certs/ユーザー名.crt |sed -e 's/subject= ([^ ]*)/\1/p' -e d` password ← クライアント証明書をBASIC認証用ユーザーデータベース(例:/etc/httpd/conf/.htpasswd)へ登録

この部分がうまくいっていない気がします。
-bcmのほうでやっても.htpasswdは作成されず、一旦空の.htpasswdを作成してから-bmで行っても空のままです。
その際に表示されるエラー?メッセージは下記です。

[root@******* ~]# htpasswd -bcm /etc/httpd/conf/.htpasswd `openssl x509 -noout -subject -in /etc/pki/CA/certs/********.crt |sed -e 's/subject= ([^ ]*)/\1/p' -e d` password Usage: htpasswd [-cimBdpsDv] [-C cost] passwordfile username htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password htpasswd -n[imBdps] [-C cost] username htpasswd -nb[mBdps] [-C cost] username password -c Create a new file. -n Don't update file; display results on stdout. -b Use the password from the command line rather than prompting for it. -i Read password from stdin without verification (for script usage). -m Force MD5 encryption of the password (default). -B Force bcrypt encryption of the password (very secure). -C Set the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 31). -d Force CRYPT encryption of the password (8 chars max, insecure). -s Force SHA encryption of the password (insecure). -p Do not encrypt the password (plaintext, insecure). -D Delete the specified user. -v Verify password for the specified user. On other systems than Windows and NetWare the '-p' flag will probably not work. The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.

####htpasswdコマンド

[root@******* ~]# htpasswd -bcm /etc/httpd/conf/.htpasswd hoge hogehoge Adding password for user hoge

これは普通に通りましたので、

`openssl x509 -noout -subject -in /etc/pki/CA/certs/********.crt |sed -e 's/subject= ([^ ]*)/\1/p' -e d` password

この部分が原因と思われます。

####opensslコマンド

[root@******* ~]# openssl x509 -noout -subject -in /etc/pki/CA/certs/*********.crt subject= /C=JP/ST=*****/L=******/O=********/CN=*********/emailAddress=****@****.com

これは正常に動いているようなので、sed以下の部分なんですが・・・正規表現?よくわかりません。。

####htpasswd生成成功

頂いたアドバイスに従い、

htpasswd -bm /etc/httpd/conf/.htpasswd "/C=JP/ST=*****/L=******/O=********/CN=*********/emailAddress=****@****.com" password

で.htpasswdの生成に成功しましたが、証明書を読み込むとエラーで接続できません。

####クライアント証明書の verify

[root@****** ~]# openssl verify -CAfile /etc/pki/CA/cacert.pem ./newcert.pem ./newcert.pem: OK

####curl コマンドでクライアント証明書認証

[root@****** ~]# curl -v --cacert /etc/pki/CA/cacert.pem --key ./newkey.pem --cert ./newcert.pem https://******.com * About to connect() to vps.******.com port 443 (#0) * Trying **.**.**.**... * Connected to vps.******.com (**.**.**.**) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/CA/cacert.pem CApath: none * unable to load client key: -8178 (SEC_ERROR_BAD_KEY) * NSS error -8178 (SEC_ERROR_BAD_KEY) * Peer's public key is invalid. * Closing connection 0 curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TaichiYanagiya

2019/06/30 14:07

.htaccess で SSLVerityClient を設定しているようですが、.htaccess は有効なのでしょうか? (AllowOverride 設定)
Take_it

2019/06/30 14:19

してませんでした。。 そちらを設定したところ、別の問題と(その原因?)らしきものが出てきたので質問を追記編集します。
guest

回答1

0

sed は **subject= ** を省いているだけです。
なので、"openssl x509 -noout -subject" で表示される DN を引数にして実行してみてください。

htpasswd -bm /etc/httpd/conf/.htpasswd "/C=JP/ST=*****/L=******/O=********/CN=*********/emailAddress=****@****.com" password

/etc/httpd/conf/.htpasswd ファイルに DN が登録されていることを確認ください。
また、httpd プロセス実行ユーザー(CentOS なら apache ユーザー)で、/etc/httpd/conf/.htpasswd ファイルを読み込めるよう、パーミッションも確認ください。


(2019/07/01 17:37) 追記
クライアント証明書に原因があるのか、Apache httpd やブラウザに原因があるのか、切り分けるといいと思います。

###クライアント証明書の verify

CA証明書: /etc/pki/CA/cacert.pem クライアント証明書: newcert.pem $ openssl verify -CAfile /etc/pki/CA/cacert.pem ./newcert.pem ./newcert.pem: OK

###curl コマンドでクライアント証明書認証

CA証明書: /etc/pki/CA/cacert.pem クライアント秘密鍵: newkey.pem クライアント証明書: newcert.pem $ curl -v --cacert /etc/pki/CA/cacert.pem --key ./newkey.pem --cert ./newcert.pem (URL) ・応答コードが 200 OK →クライアント証明書で接続できた ・応答コードが 401 Unauthorized →クライアント証明書が .htpasswd に登録されていない ・「curl: (56) Peer does not recognize and trust the CA that issued your certificate.」→クライアント証明書の Issuer が CA証明書(SSLCACertificateFile)と合っていない

投稿2019/07/01 03:49

編集2019/07/01 08:37
TaichiYanagiya

総合スコア12146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Take_it

2019/07/01 04:55

ありがとうございます。 無事、.htpasswdが生成されました。 しかしやはり証明書を選択してもアクセスが許可されません。。 .htpasswdのパーミッションは604になっていました。
TaichiYanagiya

2019/07/01 05:08

では、一旦、"SSLVerifyClient require" だけ設定して、クライアント証明書で接続できるか確認ください。
Take_it

2019/07/01 05:13

それでもやはり、接続できませんでした。
TaichiYanagiya

2019/07/01 06:21

CA 証明書(SSLCACertificateFile)が合っていないのではないでしょうか。
Take_it

2019/07/01 06:26

クライアント証明書の導入に取り掛かる前のイメージからサーバーを再構築して再挑戦してみます。
Take_it

2019/07/01 08:03

やはり症状変わりません。。 >CA 証明書(SSLCACertificateFile)が合っていない これを確認する方法はありますでしょうか・・・?
Take_it

2019/07/01 09:09

クライアント証明書の verify、curl コマンドでクライアント証明書認証について、結果を質問に追記しました。 curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY) となりました。
TaichiYanagiya

2019/07/01 09:17

クライアント秘密鍵ファイルが存在しているか確認ください。
Take_it

2019/07/01 09:23

newkey.pemはnewcert.pemと同じところ(root直下)にあります。
Take_it

2019/07/01 09:36

-8178 (SEC_ERROR_BAD_KEY) でググってみたところ、 https://stackoverrun.com/ja/q/6156132 こんなのを発見しました。 元々自分が理解できていない事柄について、カタコトの翻訳?なのでよくわからないのですが、 回答を見ると暗号化の問題?なのでしょうか。うーん。。
TaichiYanagiya

2019/07/01 09:44

クライアント秘密鍵ファイルが暗号化されているのではないでしょうか。 "openssl rsa -in ./newkey.pem -out ./newkey-dec.pem" で、暗号化を解除した ./newkey-dec.pem を使ってみてください。
Take_it

2019/07/01 09:51

[root@******** ~]# curl -v --cacert /etc/pki/CA/cacert.pem --key ./newkey- dec.pem --cert ./newcert.pem https://********.com * About to connect() to *********.com port 443 (#0) * Trying **.**.**.**... * Connected to ********.com (**.**.**.**) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/CA/cacert.pem CApath: none * Server certificate: * subject: CN=**********.com * start date: Jun 30 11:36:01 2019 GMT * expire date: Sep 28 11:36:01 2019 GMT * common name: **********.com * issuer: CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US * NSS error -8179 (SEC_ERROR_UNKNOWN_ISSUER) * Peer's Certificate issuer is not recognized. * Closing connection 0 curl: (60) Peer's Certificate issuer is not recognized. More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option. となりました。 Let's Encryptでサイト全体をSSL化しているのがダメなんでしょうかコレ。。 https://support.conoha.jp/vps/school/hellovps07/ これをやっています。
TaichiYanagiya

2019/07/01 11:17

サーバー証明書は別で作成したのですね。 "--cacert /etc/pki/CA/cacert.pem" を省いてください。
Take_it

2019/07/01 11:44

``` [root@******* ~]# curl -v --key ./newkey-dec.pem --cert ./newcert.pem https://*******.com * About to connect() to vps.fia-4u.com port 443 (#0) * Trying **.**.**.**... * Connected to *******.com (**.**.**.**) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 * Server certificate: * subject: CN=*******.com * start date: Jun 30 11:36:01 2019 GMT * expire date: Sep 28 11:36:01 2019 GMT * common name: *******.com * issuer: CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: vps.fia-4u.com > Accept: */* > * NSS: client certificate from file * subject: E=*******@*******.com,CN=******,O=*******,L=*******,ST=*******,C=JP * start date: Jul 01 07:53:41 2019 GMT * expire date: Jun 07 07:53:41 2119 GMT * common name: Admin * issuer: E=*******@********.com,CN=*******.com,O=*******,ST=*******,C=JP * SSL read: errno -12195 (SSL_ERROR_UNKNOWN_CA_ALERT) * Peer does not recognize and trust the CA that issued your certificate. * Closing connection 0 curl: (56) Peer does not recognize and trust the CA that issued your certificate. ``` となりました。 >クライアント証明書の Issuer が CA証明書(SSLCACertificateFile)と合っていない ということですが、これはつまりその・・・わかりません。。頼りきりで申し訳ありません。
Take_it

2019/07/01 12:00

サーバー側はLet's Encrypt、クライアント側が自己発行の証明書で、突き合せた結果「合ってないよ」ということでしょうか??
TaichiYanagiya

2019/07/01 12:52

サーバー証明書は無関係です。 "SSLCACertificateFile /etc/pki/CA/cacert.pem" になっていますか?
Take_it

2019/07/01 12:58

/etc/httpd/conf.d/ssl.conf ***前略*** <VirtualHost _default_:443> ****略***** SSLCACertificateFile /etc/pki/CA/cacert.pem SSLCARevocationFile /etc/pki/CA/crl.pem SSLCARevocationCheck chain としています。
TaichiYanagiya

2019/07/01 13:04

だとすると、ちょっとわからないです。 URL に対応する <VirtualHost> が別になっているとか?
Take_it

2019/07/01 13:23

SSLCACertificateFile に関する記述がどこかにないか見ていたら、 /etc/httpd/conf/httpd-le-ssl.conf に次のような記述がありました <IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin *****@*****.com DocumentRoot /var/www/html ServerName *********.com SSLCertificateFile /etc/letsencrypt/live/*********.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/*********.com/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateChainFile /etc/letsencrypt/live/*********.com/chain.pem </VirtualHost> </IfModule> これは無関係でしょうか・・・?
TaichiYanagiya

2019/07/01 13:24

そちらに SSLCACertificateFile 等を設定してみてください。
Take_it

2019/07/01 13:44

/etc/httpd/conf/httpd-le-ssl.conf を <IfModule mod_ssl.c> <VirtualHost *:443> #ServerAdmin *****@*****.com #DocumentRoot /var/www/html #ServerName *********.com #SSLCertificateFile /etc/letsencrypt/live/*********.com/cert.pem #SSLCertificateKeyFile /etc/letsencrypt/live/*********.com/privkey.pem #Include /etc/letsencrypt/options-ssl-apache.conf #SLCertificateChainFile /etc/letsencrypt/live/*********.com/chain.pem SSLCACertificateFile /etc/pki/CA/cacert.pem SSLCARevocationFile /etc/pki/CA/crl.pem SSLCARevocationCheck chain </VirtualHost> </IfModule> に書き換えて・・・ [root@******** ~]# curl -v --key ./newkey-dec.pem --cert ./newcert.pem https://*****.com * About to connect() to *****.com port 443 (#0) * Trying **.**.**.**... * Connected to *****.com (**.**.**.**) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * Server certificate: * subject: E=root@*********,CN=*********,OU=SomeOrganizationalUnit,O=SomeOrganization,L=SomeCity,ST=SomeState,C=-- * start date: Jun 30 12:24:17 2019 GMT * expire date: Jun 29 12:24:17 2020 GMT * common name: ********* * issuer: E=root@*********,CN=*********,OU=SomeOrganizationalUnit,O=SomeOrganization,L=SomeCity,ST=SomeState,C=-- * NSS error -8156 (SEC_ERROR_CA_CERT_INVALID) * Issuer certificate is invalid. * Closing connection 0 curl: (60) Issuer certificate is invalid. More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option. -kを付けてみたら、 [root@********* ~]# curl -v --key ./newkey-dec.pem --cert ./newcert.pem https://*****.com -k * About to connect() to *****.com port 443 (#0) * Trying **.**.**.**... * Connected to *****.com (**.**.**.**) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * skipping SSL peer certificate verification * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 * Server certificate: * subject: E=root@*********,CN=*********,OU=SomeOrganizationalUnit,O=SomeOrganization,L=SomeCity,ST=SomeState,C=-- * start date: Jun 30 12:24:17 2019 GMT * expire date: Jun 29 12:24:17 2020 GMT * common name: ********* * issuer: E=root@*********,CN=*********,OU=SomeOrganizationalUnit,O=SomeOrganization,L=SomeCity,ST=SomeState,C=-- > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: *****.com > Accept: */* > * skipping SSL peer certificate verification * NSS: client certificate from file * subject: E=*****@*****.com,CN=Admin,O=*********[*****.com],L=*****,ST=*****,C=JP * start date: Jul 01 07:53:41 2019 GMT * expire date: Jun 07 07:53:41 2119 GMT * common name: Admin * issuer: E=*****@*****.com,CN=*****.com,O=*********[*****.com],ST=*****,C=JP < HTTP/1.1 200 OK < Date: Mon, 01 Jul 2019 13:29:16 GMT < Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips < Content-Length: 38 < Content-Type: text/html; charset=UTF-8 < * Connection #0 to host *****.com left intact 現在:2019-07-01 22:29:16Hello World!       ←index.phpが意図した通りの出力をしている [root@********* ~]# となりましたが、ブラウザでアクセスすると証明書も要求されず、「このサイトは安全に接続できません」と出てしまいアクセスできませんでした。
Take_it

2019/07/01 13:54

これはもしかして、Let'sEncrypt導入前まで戻っていろいろやった方がいいのでしょうか。。
TaichiYanagiya

2019/07/01 14:11

元の /etc/httpd/conf/httpd-le-ssl.conf の設定はそのままコメントアウトせずに、クライアント証明書認証用の設定を追加してください。
Take_it

2019/07/01 14:38

-k なしでアクセスできるようになりました。 [root@********* ~]# curl -v --key ./newkey-dec.pem --cert ./newcert.pem https://********.com * About to connect() to ********.com port 443 (#0) * Trying **.**.**.**... * Connected to ********.com (**.**.**.**) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 * Server certificate: * subject: CN=********.com * start date: Jun 30 11:36:01 2019 GMT * expire date: Sep 28 11:36:01 2019 GMT * common name: ********.com * issuer: CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: **********.com > Accept: */* > * NSS: client certificate from file * subject: E=*****@*****.com,CN=Admin,O=********,L=Fukuroi,ST=********,C=JP * start date: Jul 01 07:53:41 2019 GMT * expire date: Jun 07 07:53:41 2119 GMT * common name: Admin * issuer: E=*****@*****.com,CN=********,O=********,ST=********,C=JP < HTTP/1.1 200 OK < Date: Mon, 01 Jul 2019 14:25:28 GMT < Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips < Content-Length: 38 < Content-Type: text/html; charset=UTF-8 < * Connection #0 to host ********.com left intact 現在:2019-07-01 23:25:28Hello World![root@********* ~]# しかし、ブラウザでアクセスするとやはり証明書を要求されません。(そしてアクセスできません) /etc/httpd/conf/httpd.conf の、 <Directory "/var/www/html"> にAllowOverride All を記述して/var/www/htmlに.htaccessを置いても、.htaccessを取り除きAllowOverride noneにして、SSLVerifyClient requireを直接httpd.confに記述しても、効果なしです。 でも一歩近づいた気がします!
Take_it

2019/07/01 14:39

ブラウザからは依然アクセスできませんが、先ほどとは異なりChromeは「危険」とは見なしていないようです。
TaichiYanagiya

2019/07/01 14:57

クライアント証明書、Apache httpd 設定は問題なさそうですね。 後はブラウザの問題だと思います。
Take_it

2019/07/01 15:16

ブラウザを変えてEdgeでアクセスしてみましたが、やはり証明書を要求されることなく、 このページに安全に接続できません サイトで古いか安全でない TLS セキュリティ設定が使用されている可能性があります。この問題が解決しない場合は、Web サイトの所有者に連絡してください。 となります。。
Take_it

2019/10/25 05:08

Windows 10 Enterpriseではないですし、Chromeですし、関係ないだろうと思いつつリンク先のものを試してみましたが解決しませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問