Opensslの設定めも

  2017.12.12
2016.04.14
2015.03.14


  Debian GNU/Linux stretchのOpensslによるWebサイトのSSL対応のメモです。

関連 apache2設定メモ   WebDav 設定メモ     

1 関連知識及び概要

  SSLはインターネットショッピングやネット銀行などインターネット越しで安全に通信できる手段である。公開鍵暗号と共通鍵暗号、一方向暗号という3つの 暗号を組み合わせてなりすましや盗聴、改ざんを防いでいる。
 その中で公開鍵暗号方式はSSLのキモである。公開鍵暗号方式は公開鍵と秘密鍵のペアがあり、公開鍵で暗号化したものは秘密鍵でしか復号化でき ない。逆に秘密鍵で暗号化したものは公開鍵でしか復号化できない。
 サーバーは秘密鍵を手元に置き、公開鍵はクライアントにリクエストに応じて渡す。公開鍵はその名のとおり複数のクライアントにばらまいても公開 鍵で暗号化したものは公開鍵では復号化できないので問題ない。しかし公開鍵をばらまいたサーバーの身元を保証してくれなければ顔の見えないネット 越しにデータを送るのは危険である。そこで認証局CAが公開鍵をばらまくサーバーの身元を有料で審査して電子証明書をサーバーの公開鍵に署名す る。(この署名というのもCAの公開鍵みたいな原理でできているらしい。)
 これでサーバーは堂々と公開鍵を配ることができる。ショッピングや銀行を使うクライアント側は、そのショッピングサイトや銀行の公開鍵をもらっ て電子証明書が正しいかどうかを、あらかじめブラウザに入っているCAの公開鍵を使って複合化して確認している。
 
 つまりOpnesslで勝手に無認可の認証局CAを作り電子証明書を作る。
 次に自分のサーバーの公開鍵暗号の公開鍵と秘密鍵を作成する。
 公開鍵に認証局CAの電子証明書の署名をしてもらう。

 ということの手順がこのページの流れ。

 CA(認証局)といっても実際にデーモンやソフトが稼働しているわけではない。
 自分でserverのCSR(証明書要求)を作成して、それに対しての証明書を作成する作業をしておくだけである。

 

2 Opensslのインストール

(1)インストール

#  aptitude install  openssl
 

(2)設定
 /etc/ssl/openssl.cnfの次の2つのセクションのところを直す。
default_days    = 3650      <-----------  defaultは365(1年)日で短すぎなので10年ぐらいに

# For the CA policy
[ policy_match ]
countryName             = match          <----------------matchは CAの内容と同じでなければならない
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional  <--------------- optionalは オプションなので無くてもOK
commonName              = supplied   <--------------- suppliedは 省略できない、必要
emailAddress            = optional




 
  nsCertType  = server   <-----コメントアウトを外す

 
  nsCertType = sslCA, emailCA  <-----コメントアウトを外す



 他に[ CA_default ]のdirの記述を書き換えると作業ディレクトリを変更できるが、今回はデフォルトのままにする。


3 CA(認証局)の構築

 CAは、依頼者(ここでは自分のWebサーバが依頼者になる)からCSR(証明書要求)を受け取り、証明書を発行する。しかし、待ち 受けのデーモンのようにCAを稼働させるのではなく、単に手作業で自分が認証局長になって証明書を発行するだけである。
 ここではCAの秘密鍵と証明書を作成する。 

#cd /usr/lib/ssl/misc
#./CA.pl -newca   <---- 新規のCAの作成
# ./CA.sh -newca
CA certificate filename (or enter to create) 
< ----ここはenter

Making CA certificate ...
Generating a 1024 bit RSA private key
.......++++++
................++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase:
XXXXX <----CA の秘密鍵のパスフレーズ。証明書発行 のときにも使う。
Verifying - 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) [AU]:JP 
< ----  国名
State or Province Name (full name) [Some-State]:GUNMA
  < ----県名
Locality Name (eg, city) []:Maebashi
< ----都市名
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Wasaraka
< ----会社名
Organizational Unit Name (eg, section) []:Lab.
< ---組織名
Common Name (eg, YOUR name) []:hogehoge
  < ---自分の名前
Email Address []:
         <--- メールアドレスは 入れないでenter

 
<--- challenge password以下も入れない  入れるとapache起動時にpassword入力しなければならないらしい

Enter pass phrase for ./demoCA/private/./cakey.pem:XXXXX
Check that the request matches the signature



Data Base Updated


 これによってカレントディレクトリに demoCAというディレクトリができる。
 demoCAという認証局長になってしまった。出世したもんだ。
 この認証局の電子署名も公開鍵暗号である。認証局はCAの秘密鍵で電子署名を暗号化する。
 サーバーは自分の公開鍵に 認証局の電子署名を組み込んでもらう。そしてその公開鍵を
 クライアントに配布する。
  クライアントはサーバからきた公開鍵の電子署名を確認するとき、たいていはブラウザに
 組み込まれている認証局の公開鍵を使って復号化して確認する。しかしdemoCAの公開鍵は
 当然ブラウザに組み込まれていないし、素性の知れない認証局なのでブラウザは警告をする。


   demoCA/cacert.pem         自己署名型CA証明書
  demoCA/private/cakey.pem  CAの秘密鍵

  CAの秘密鍵は他人に見られないようにpermissionを変更しておく。
   

# chmod 600 /usr/lib/ssl/misc/demoCA/private/cakey.pem

 証明書の確認は

# openssl x509 -in cacert.pem -text

4 サーバ認証の実現


作業手順は次のようになる。主語がサーバか CAか混同しないように注意しなければならない。



(1)サーバが、鍵のペア(公開鍵と秘密鍵)とCSR(証明書 要求)を 作成し、サーバがCSR(証明書要求)をCA(認証局)へ送る。
(2)サーバからCSRを受け取ったCAは、証明書を作成してサーバへ送る。
(3)CAから証明書をもらったサーバは、証明書を公開鍵に組み込む。
(4)クライアントは、”CAの証明書”をあらかじめクライアントのブラウザに組み込んでサーバにアクセスする。



(1)サーバの公開鍵ペアとCSR(証明書要求)の作成
  次のコマンドを実行すると サーバの秘密鍵のkey.pem , 公開鍵とサーバの情報が入ったCSR(証明書要求)が作成される。
# cd /usr/lib/ssl/misc/demoCA/
# openssl req -new -keyout ./private/key.pem -out csr.pem
Generating a 2048 bit RSA private key
........................+++
...............................+++
writing new private key to './private/key.pem'
Enter PEM pass phrase:サーバーの秘密鍵のパスフレーズを入力
Verifying - 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) [AU]:JP
State or Province Name (full name) [Some-State]:Gunma
Locality Name (eg, city) []:Sawatari
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Wasaraka(ここはCAと 同じにする)
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:karappi
Email Address []:


Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password <--- challenge password以下も入れない []:
An optional company name []:

 
(2)CSRに対してCAの署名入り証明書の作成
  今度はCA側として、CSRに対する処理を行う。
 証明書の作成の祭、CAの秘密鍵のパスフレーズを要求される。
  /etc/ssl/openssl.confの [ CA_default ]を変更していない状態においてはディレクトリのパスの関係から次のようにカレントディレクトリを移動してから実行する。パスワードは最初のcaを構築し たときのパスワードを使う。
# cd /usr/lib/ssl/misc/
# openssl  ca  -out  ./demoCA/certs/cert.pem  -infiles  ./demoCA/csr.pem
    cert.pemがCAの署名入り証明書付の公開鍵となる。cert.pemが0バイト(空)のができてしまったことがあった。認証局構築のときの会社名 (Wasaraka)と3(1)のサーバー公開鍵ペアとCSR作成のときのOrganization Name (Wasaraka)が一致させたらなおった(2017.12.8)
  

もしディレクトリの場所が/etc/ssl/openssl.confの[CA_default]記述と異なると次のようなエラーが出たりする。
:system library:fopen:No such file or directory:bss_file.c:356:fopen('./demoCA/private/cakey.pem','r')
また
failed to update database」 が出たときは demoCA/index.txtを削除して
 touch index.txt
を実行して空のindex.txtファイルを作成してから証明書の作成を再度行う。

(3)サーバはcaに署名してもらった証明書つき公開鍵と自分の秘密鍵をapacheの設定ファイルに組み込む。
 まず /etc/apache2/ssl/certs と/etc/apache2/ssl/privateというディレクトリを作成し、
 まず、/usr/lib/ssl/misc/demoCA/certs/cert.pemを/etc/apache2/ssl/certs /に、
 /usr/lib/ssl/misc/demoCA/private/key.pem を/etc/apache2/ssl/private/にコピーする。

# mkdir /etc/apache2/ssl/
# mkdir /etc/apache2/ssl/certs
# mkdir /etc/apache2/ssl/private
# cp  /usr/lib/ssl/misc/demoCA/certs/cert.pem  /etc/apache2/ssl/certs/
# cp  /usr/lib/ssl/misc/demoCA/private/key.pem  /etc/apache2/ssl/private/
  
次に/etc/apache2/sites-available/に設定ファイル(例 : hoge.example.com-ssl.conf)を作成する。
この設定ファイルのサンプルのもとは/etc/apache2/sites-available/default-ssl.conf
である。(jessie)

/etc/apache2/sites-available/hoge.example.com-ssl.conf    (ファイル名の拡張子は .conf   .sslはダメ)
 <IfModule mod_ssl.c>
        <VirtualHost _default_:443>
              ServerAdmin webmaster@localhost

              DocumentRoot /var/www/html
                DocumentRoot /home/karappi/public_html

                # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
                # error, crit, alert, emerg.
                # It is also possible to configure the loglevel for particular
                # modules, e.g.
                #LogLevel info ssl:warn

                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined

                # For most configuration files from conf-available/, which are
                # enabled or disabled at a global level, it is possible to
                # include a line for only one particular virtual host. For example the
                # following line enables the CGI configuration for this host only
                # after it has been globally disabled with "a2disconf".
                #Include conf-available/serve-cgi-bin.conf

                #   SSL Engine Switch:
                #   Enable/Disable SSL for this virtual host.
                SSLEngine on

                #   A self-signed (snakeoil) certificate can be created by installing
                #   the ssl-cert package. See
                #   /usr/share/doc/apache2/README.Debian.gz for more info.
                #   If both key and certificate are stored in the same file, only the
                #   SSLCertificateFile directive is needed.
                #SSLCertificateFile     /etc/ssl/cert/ssl-cert-snakeoil.pem
                #SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
                SSLCertificateFile      /etc/apache2/ssl/certs/cert.pem
                SSLCertificateKeyFile /etc/apache2/ssl/private/key.pem


                #   Server Certificate Chain:
                #   Point SSLCertificateChainFile at a file containing the
                #   concatenation of PEM encoded CA certificates which form the
                #   certificate chain for the server certificate. Alternatively
                #   the referenced file can be the same as SSLCertificateFile
                #   when the CA certificates are directly appended to the server
                #   certificate for convinience.
                #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
    
               #   Certificate Authority (CA):
                #   Set the CA certificate verification path where to find CA
                #   certificates for client authentication or alternatively one
                #   huge file containing all of them (file must be PEM encoded)
                #   Note: Inside SSLCACertificatePath you need hash symlinks
                #                to point to the certificate files. Use the provided
                #                Makefile to update the hash symlinks after changes.
                #SSLCACertificatePath /etc/ssl/certs/
                #SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt

                #   Certificate Revocation Lists (CRL):
                #   Set the CA revocation path where to find CA CRLs for client
                #   authentication or alternatively one huge file containing all
                #   of them (file must be PEM encoded)
                #   Note: Inside SSLCARevocationPath you need hash symlinks
                #                to point to the certificate files. Use the provided
                #                Makefile to update the hash symlinks after changes.
                #SSLCARevocationPath /etc/apache2/ssl.crl/
                #SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl

                #   Client Authentication (Type):
                #   Client certificate verification type and depth.  Types are
                #   none, optional, require and optional_no_ca.  Depth is a
                #   number which specifies how deeply to verify the certificate
                #   issuer chain before deciding the certificate is not valid.
                #SSLVerifyClient require
                #SSLVerifyDepth  10

               #   SSL Engine Options:
                #   Set various options for the SSL engine.
                #   o FakeBasicAuth:
                #        Translate the client X.509 into a Basic Authorisation.  This means that
                #        the standard Auth/DBMAuth methods can be used for access control.  The
                #        user name is the `one line' version of the client's X.509 certificate.
                #        Note that no password is obtained from the user. Every entry in the user
                #        file needs this password: `xxj31ZMTZzkVA'.
                #   o ExportCertData:
                #        This exports two additional environment variables: SSL_CLIENT_CERT and
                #        SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
                #        server (always existing) and the client (only existing when client
                #        authentication is used). This can be used to import the certificates
                #        into CGI scripts.
                #   o StdEnvVars:
                #        This exports the standard SSL/TLS related `SSL_*' environment variables.
                #        Per default this exportation is switched off for performance reasons,
                #        because the extraction step is an expensive operation and is usually
                #        useless for serving static content. So one usually enables the
                #        exportation for CGI and SSI requests only.
                #   o OptRenegotiate:
                #        This enables optimized SSL connection renegotiation handling when SSL
                #        directives are used in per-directory context.
                #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
                <FilesMatch "\.(cgi|shtml|phtml|php)$">
                                SSLOptions +StdEnvVars
                </FilesMatch>
                #<Directory /usr/lib/cgi-bin>
                #               SSLOptions +StdEnvVars
                #</Directory>

                <Directory /home/karappi/public_html/>
                        SSLOptions +StdEnvVars
                        Options ExecCGI Indexes FollowSymLinks MultiViews Includes
                        AllowOverride All
                        Order allow,deny
                        allow from all
                        ServerSignature Off
                        AddHandler cgi-script .cgi .pl
                        AddType text/html .rhtml .shtml
                </Directory>


                #   SSL Protocol Adjustments:
                #   The safe and default but still SSL/TLS standard compliant shutdown
                #   approach is that mod_ssl sends the close notify alert but doesn't wait for
                #   the close notify alert from client. When you need a different shutdown
                #   approach you can use one of the following variables:
                #   o ssl-unclean-shutdown:
                #        This forces an unclean shutdown when the connection is closed, i.e. no
                #        SSL close notify alert is send or allowed to received.  This violates
                #        the SSL/TLS standard but is needed for some brain-dead browsers. Use
                #        this when you receive I/O errors because of the standard approach where
                #        mod_ssl sends the close notify alert.
                #   o ssl-accurate-shutdown:
                #        This forces an accurate shutdown when the connection is closed, i.e. a
                #        SSL close notify alert is send and mod_ssl waits for the close notify
                #        alert of the client. This is 100% SSL/TLS standard compliant, but in
                #        practice often causes hanging connections with brain-dead browsers. Use
                #        this only for browsers where you know that their SSL implementation
                #        works correctly.
                #   Notice: Most problems of broken clients are also related to the HTTP
                #   keep-alive facility, so you usually additionally want to disable
                #   keep-alive for those clients, too. Use variable "nokeepalive" for this.
                #   Similarly, one has to force some clients to use HTTP/1.0 to workaround
                #   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
                #   "force-response-1.0" for this.
                BrowserMatch "MSIE [2-6]" \
                                nokeepalive ssl-unclean-shutdown \
                                downgrade-1.0 force-response-1.0
                # MSIE 7 and newer should be able to use keepalive
                BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

        </VirtualHost>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
                                               

設定ファイルを登録
# a2ensite hoge.example.com.ssl.conf
一応sslモジュールも追加
# a2enmod ssl

apache2の再起動
# /etc/init.d/apache2  restart


ところでapache2 を起動するたびにパスワードを求められるので、これは面倒である。
/etc/apache2/ssl/private下で次の命令をするとパスワードの入力を求めなくなる。セキュリティ上の弊害はわからない。
# openssl  rsa  -in  key.pem  -out  key.pem
 
  最後に443番ポートを開放することを忘れずに

5 クライアントのブラウザへの組み込み

/usr/lib/ssl/misc で次のコマンドを実行する。
# openssl x509 -inform pem -in demoCA/certs/cert.pem  -out cacert.der -outform der
  cacert.derをscpコマンドやあるいは直接媒体をつかってクライアントへもっていきブラウザに組み込む
 iceweaselでは 編集→設定→詳細→証明書を表示→サーバ証明書 で インポートをクリック cert.derをインポートする。
 google-chromeでは設定 → 高度な設定 → 証明書の管理  で サーバの証明書をインポートする。


6 補足

アクセス方法を強制的にsslにするには そのページがあるディレクトリに.htaccess を作成する
.htaccess
SSLRequireSSL
AuthType Basic
AuthName "Input ID and Password."
AuthUserFile /home/karappi/.htpasswd
require valid-user
  最初のSSLRequireSSL の記述が SSL
 あとはBASIC認証のパスワードを求める記述(apache2.4 BASIC認証の設定を参照)

目次