OpenSSLの設定ファイル(openssl.cnf)の使い方メモ

Linux
Linux
スポンサーリンク

つい先日 OpenSSL の設定ファイル(openssl.cnf)を作成する機会があったのですが、設定ファイルの書き方やオプションの指定方法などがさっぱり分からず苦労しました、、、秘密鍵の作成などツールとして OpenSSL を使っている方は多いかと思いますが、OpenSSL の設定ファイルの使い方についてはあまり知られていないのではないでしょうか? そこで今回は、OpenSSL の設定ファイルについて調べた内容をまとめてみました。

OpenSSLのバージョン

今回使用したOpenSSLのバージョンは次の通りです。バージョンによっては設定ファイルで指定できるオプションに違いがありますので、必ずそのバージョンのマニュアル(man)をご確認ください。

openssl version

OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)

OpenSSLコマンドの基本

はじめに OpenSSLコマンドの基本をおさらいしておきましょう。

OpenSSLは openssl に続けて、OpenSSLユーティリティと呼ばれるコマンドを指定し、そのコマンドに対応するオプションやパラメータを設定して実行します。

openssl コマンド [ オプション ... ] [ パラメータ ... ]

例えば、秘密鍵を作成する genpkey コマンド に -algorithm オプションを指定してパラメーターに RSA を設定して実行すれば、RSAの秘密鍵が出力されます。

openssl genpkey -algorithm RSA

OpenSSLで利用できるコマンドはオプションに help 指定して実行すれば確認できます。

openssl help
help:

Standard commands
asn1parse         ca                ciphers           cmp               
cms               crl               crl2pkcs7         dgst              
dhparam           dsa               dsaparam          ec                
ecparam           enc               engine            errstr            
fipsinstall       gendsa            genpkey           genrsa            
help              info              kdf               list              
mac               nseq              ocsp              passwd            
pkcs12            pkcs7             pkcs8             pkey              
pkeyparam         pkeyutl           prime             rand              
rehash            req               rsa               rsautl            
s_client          s_server          s_time            sess_id           
smime             speed             spkac             srp               
storeutl          ts                verify            version           
x509

また、各コマンドのマニュアルは、man openssl- に続けてコマンドを指定して実行すれば参照することができます。

man openssl-コマンド

例えば、genpkey コマンドのマニュアルは以下で確認できます。

man openssl-genpkey

OpenSSLの設定ファイルを作成するには、各コマンドのマニュアルを参照することになるので覚えておきましょう。

OpenSSLの設定ファイルの基本

OpenSSLの設定ファイルの場所を確認するには version コマンドに -d オプションをつけて実行します。

openssl version -d

OPENSSLDIR: "/etc/pki/tls"

上の例の場合は、/etc/pki/tls/ ディレクトリの下に openssl.cnf というファイルがあり、それが OpenSSLの設定ファイルです。

/etc/pki/tls/openssl.cnf   ←OpenSSLの設定ファイル

OpenSSLのコマンドを実行すると、通常はこの設定ファイルが参照されますが -config オプションで自分で作成したOpenSSLの設定ファイルを参照するように指定することができます。

openssl genpkey -config my.cnf

Using configuration from my.cnf   ← my.cnfが参照される

ただし、-config オプションに対応していないコマンドもあります。コマンドのマニュアルに -config オプションの記載があれば対応していますが、記載がなければそのコマンドではOpenSSLの設定ファイルを指定することはできません。

openssl rand -config my.cnf

rand: Unknown option: -config   ← -configオプションに対応していない

OpenSSLの設定ファイルの構成と書式

OpenSSLの設定ファイルは、「デフォルトセクション」と「名前付きセクション」から構成されます。

「デフォルトセクション」は、設定ファイルの先頭から最初の名前付きのセクションの前まで続きます。次の例の場合は [ section_one ] の上の行までが「デフォルトセクション」になり、[ section_one ]、[ section_two ] が名前付きセクションになります。

(デフォルトセクション)
 ↓
 ↓
[ section_one ]
(section_one の名前付きセクション)
 ↓
 ↓
[ section_two ]
(section_two の名前付きセクション)
 ↓
 ↓

セクション名
 セクション名は [ セクション名 ] のように角括弧で囲みます、セクション名は英数字とアンダースコアが使えます。角括弧とセクション名の間のスペースは入れても入れなくても問題無いようです。上の例ではスペースを入れて [ section_one ] としていますが [section_one] としても問題ありません。セクション名として認識されるのはどちらもスペースを除いた「section_one」になります。
 

各セクションは名前と値のペアで構成され、名前に対応する値は「=」で指定します。次の例の2行目の「var」は名前、「/temp」が値です。

# デフォルトセクション(ここはコメント)
var = /temp
configdir = $ENV::HOME/config # 設定ファイル用ディレクトリ(ここもコメント)

[ section_one ]
message = Hello World
TEMP=${var}

[ section_two ]
greeting = $section_one::message

コメント
 「#」以降の文字列はコメントとして扱われます。

名前
 名前には英数字と「.(ピリオド)」「,(カンマ)」「;(コロン)」「_.(アンダースコアピリオド)」 が使えます。


 「=」に続く空白は削除され、行の終わりまでの文字列が値として設定されます。

変数展開(デフォルトセクション)
 指定された値は $名前 または ${名前} で参照できます。上の例の名前「var」に指定された値は $var または ${var} で参照できます。

変数展開(名前付きセクション)
  名前付きセクションで指定された値は、$セクション名::名前 または ${セクション名::名前} で参照できます。上の例の名前「message」に指定された値は $section_one::message または ${section_one::message} で参照できます。

変数展開(環境変数)
 環境変数は $ENV::環境変数 または ${ENV::環境変数} で参照できます。例えば環境変数 $HOME は $ENV::HOME または ${ENV::HOME} で参照できます。

OpenSSLの設定ファイルの構成と書式については、このくらいを押さえておけば十分かと思います。詳細やOpenSSLの設定ファイルで指定できるオプションについては man config をご参照ください。

OpenSSLの設定ファイルの作り方(req)

それでは実際に、OpenSSLの設定ファイルを作成してみましょう。

今回は、以下のCSR(証明書署名要求)を作成するための設定ファイルを作成してみます。

Country Name JP
State or Province Name Tokyo
Locality Name Shinjuku-Ku
Organization Name Sample Inc.
Organizational Unit Name Information System Division
Common Name www.example.com
Email Address sample@example.com

設定ファイルのオプションの確認

CSRは req コマンドで作成しますので、man openssl-req の「CONFIGURATION FILE FORMAT」の章を確認して使えそうなオプションを探します。

CONFIGURATION FILE FORMAT
(略)
prompt
If set to the value no this disables prompting of certificate fields and just takes values from the config file
directly. It also changes the expected format of the distinguished_name and attributes sections.
(略)
man openssl-req より引用

「prompt = no」を指定すれば、対話式のプロンプトが表示されなくなり、設定ファイルから直接値を取得してくれるようです。 distinguished_name と attributes オプションも関係しそうですので、さらに確認していきます。

attributes
This specifies the section containing any request attributes: its format is the same as distinguished_name.
Typically these may contain the challengePassword or unstructuredName types. They are currently ignored by
OpenSSL's request signing utilities but some CAs might want them.

distinguished_name
This specifies the section containing the distinguished name fields to prompt for when generating a certificate or
certificate request. The format is described in the next section.
(略)
man openssl-req より引用

distinguished_name オプションで識別子フィールド(CSRの内容)を含む名前付きセクションを指定して、その名前付きセクションでCSRの内容を指定してあげればよさそうです。書式は次の章に説明があるようなので、確認してみましょう。

DISTINGUISHED NAME AND ATTRIBUTE SECTION FORMAT
EXAMPLES
(略)
[ req ]
default_bits = 2048
default_keyfile = keyfile.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no
output_password = mypass

[ req_distinguished_name ]
C = GB
ST = Test State or Province
L = Test Locality
O = Organization Name
OU = Organizational Unit Name
CN = Common Name
emailAddress = test@email.address
(略)
man openssl-req より引用

CSRの指定方法の書式の例がありました。以上を参考にしてCSRを作成するための設定ファイルを作成します。

完成した設定ファイル

今回作成した設定ファイルは次の通りです。

my.cnf
# デフォルトセクション
country_name                = JP
state                       = Tokyo
locality_name               = Shinjuku-Ku
organization_name           = Sample Inc.
organizational_unit_name    = Information System Division
common_name                 = www.example.com
email_address               = sample@example.com

[ req ]
prompt              = no
distinguished_name  = csr

[ csr ]
C               = $country_name
ST              = $state
L               = $locality_name
O               = $organization_name
OU              = $organizational_unit_name
CN              = $common_name
emailAddress    = $email_address

デフォルトセクションでCSRの内容を変数にして、それを [ csr ] の名前付きセクションで指定しています。また「distinguished_name」オプションで指定する名前付きセクションは、書式の例では [ req_distinguished_name ] でしたが分かりやすく [ csr ] にしてみました。このようにオプションで名前付きセクションを指定して、その名前付きセクションで値を指定するのは OpenSSLの設定ファイルの特徴ですので覚えておきましょう。

この設定ファイルを req コマンドで指定して実行すると、はじめにコマンド名と同じ [ req ] 名前付きセクションのオプションが実行され、次に「distinguished_name」オプションで指定されている [ csr ] 名前付きセクションのオプションが実行されます。

確認のため作成した設定ファイルを指定して実行してみましょう。

openssl genpkey -algorithm RSA -out private.key
openssl req -new -config my.cnf -key private.key -out my.csr
openssl req -text -in my.csr

Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = JP, ST = Tokyo, L = Shinjuku-Ku, O = Sample Inc., OU = Information System Division, CN = www.example.com, emailAddress = sample@example.com
(略)

おわりに

ここまでお読みいただいた方は既にお気づきかと思いますが、OpenSSLの設定ファイルが少し分かりづらいのは、各セクションを構成する名前と値のペアが、変数であるのか、設定のオプションであるのか、はたまた名前付きセクションを指定するためのオプションであるのかが、パッと見では分からない点にあります。

OpenSSLの設定ファイルを扱う際は、マニュアルを読んで名前と値のペアがなんの役割をしているかをしっかり把握しておくのが良さそうですね。

コメント

タイトルとURLをコピーしました