6.Linuxの暗号化
6.1. 暗号化の基礎
6.1.1. 暗号化とは
暗号化は暗号文を使用して通信と情報を保護する手法のこと。
コンピュータサイエンスにおいて、暗号化は、解読が困難な方法でメッセージを変換するための、数学的概念とアルゴリズムと呼ばれる一連のルールベースの計算から派生した安全な情報および通信技術を指す。 これらの決定論的アルゴリズムは、暗号キーの生成、デジタル署名、データ プライバシーを保護するための検証、インターネット上の Web ブラウジング、クレジット カード取引や電子メールなどの機密通信に使用される。
暗号化の用途
- 暗号化 … 情報をその本当の意味を隠す秘密コードに変換する方法。情報の暗号化と復号化の仕組みは暗号化と呼ばれる
- 完全性 …. 情報は、変更が検出されない限り、保存中または送信者と目的の受信者の間での転送中に変更されることはないことを保証する
- 認証 … 送信者と受信者は、互いの身元と情報の発信元/宛先を確認できる
暗号化の主要な要素
暗号化には2つの主要な要素がある。
- キー … データの暗号化に使用されるもの。秘密にしておく必要がある。
- アルゴリズム … メッセージのエンコードとデコードに使用されるメソッドのこと。
共通鍵暗号方式(対称暗号方式)
共通鍵暗号方式は暗号化と復号を同じ鍵で行うもの。
AESやDES、blowfishなどが代表例としてある。
このタイプの暗号化は、平文を暗号文に暗号化し、その暗号文を平文に復号化するために同じ鍵が使われるため対称と言える。 一般的に、非対称暗号化よりも高速となる。
公開鍵暗号方式(非対称暗号方式)
公開鍵暗号は暗号化/復号化に公開鍵ペアを使用する暗号。 対になる鍵の一方が公開鍵で、もう一方が秘密鍵となる。
鍵 | 説明 |
---|---|
公開鍵 | 一般にアクセス可能なリポジトリで公開され、公開鍵ペアの所有者と通信する必要がある人は誰でもアクセス可能 |
秘密鍵 | 秘密鍵は所有者のみが所有する |
これらの鍵はそれぞれ平文を暗号化された暗号文に変換することができるが、 一方の鍵で暗号化された暗号文はもう一方の鍵でしか復号できない。
特徴は以下の通り。
- 公開鍵で暗号化された暗号文は秘密鍵でしか復号化できない
- 秘密鍵で暗号化された暗号文は公開鍵を使ってのみ復号できる
- 共有秘密鍵を交換することなくメッセージを送信できる
またRSA暗号方式による秘密鍵の生成に関しては「512bitや1024bit程度の長さは容易に計算できる」とされているため、2048bit以上の長さを用いることが推奨されている。
ハッシュによるデータの整合性
ハッシュ関数を用いた暗号化では特定のデータを一定長の固定サイズの値に変換する暗号化を行う。この変換された値はハッシュ値と呼ばれる。
ハッシュの特徴は以下の通り。
- ハッシュ関数は固定長の出力を生成する
- ハッシュ値から元のデータを再構築するのは困難(一方向性)
- セキュリティを向上させるためにソルトを使用してハッシュ化する方法がある
- ハッシュアルゴリズムにはCRC2(非推奨)、md5、**sha-1*などがある
6.1.2. 公開鍵基盤(PKI)とトラストチェーン
公開鍵基盤(PKI)
PKI(公開鍵基盤)は異なるコンピュータシステム間の通信を保護するために使用されるシステムのこと。 暗号化に用いられる「公開鍵」と「公開鍵の持ち主」の関係を保証する仕組みともいえる。
PKIは暗号化キーのペアとデジタル証明書に基づき、公開鍵基盤は認証局の階層と証明書署名要求プロセスで構成される。
認証局(CA)
認証局(CA)はWeb サイト、電子メール アドレス、企業、個人などの身元を検証するために機能する組織のこと。 公開キーの信頼性を検証する第三者といえる。
デジタル証明書として知られる電子文書の発行を通じて、それらを暗号キーにバインドする。 公開キーの信頼性を検証する信頼できる第三者機関と言える。
認証局には以下の役割がある。
- 有効なCSRに署名する
- 秘密鍵のセキュリティを維持する
- 侵害された証明書または悪用された証明書を取り消す
証明書署名要求(CSR)
証明書署名要求(CSR) は基本的に生成される公開キーであり、CA に送信して署名を受けることができるもの。
CAがCSRに署名すると、署名したCAによって信頼される証明書が生成される。
CRL
CRLは認証局が執行させた電子証明書のリスト(証明書失効リスト)のこと。
利用者はCRLを定期的にDLすることで証明書の有効性を確認する。
OCSP
OCSPは電子証明書の失効を問い合わせるプロトコルのこと。
OCSPレスポンダと呼ばれるサーバにアクセスすることで証明書の有効性を確認する。
トラストチェーン(証明書チェーン)
トラストチェーンは対象となる証明書からルート証明書(Root CA)までの一連の証明書が連鎖している状態のこと。
これは証明書を発行する証明局が最上位にあるルート証明局と公開鍵証明書の所有者に1つ以上の中間認証局が存在する階層構造になっていることに由来する。
6.1.3. 公開鍵証明書(ディジタル証明書)と認証局
公開鍵暗号方式においては公開鍵証明書によって公開された鍵が意図している所有者のものであることが保証されている必要がある。
公開鍵証明書は、信頼できる第三者として認証局(CA:Certification Authority)によりデジタル署名(後述)されて発行され、その証明書に含まれる公開鍵の真正性と有効性(公開鍵の所有者が正当な所有者であること、証明書が有効期限内であること等)を保証する仕組みです。ちょうど、公的身分証明書が、信頼できる公的機関の発行証明によって信頼性を担保するのと似ている。
公開鍵証明書には、公開鍵そのものに加えて発行者の情報や有効期間などの情報が含まれる。
認証局(CA)
認証局(CA)はWeb サイト、電子メール アドレス、企業、個人などの身元を検証するために機能する機関のこと。
デジタル証明書として知られる電子文書の発行を通じて、それらを暗号キーにバインドする。 公開キーの信頼性を検証する信頼できる第三者機関と言える。
認証局には以下の役割がある。
- 公開鍵証明書の発行
- 認証局は電子証明書の発行依頼を受けて、申請内容と証明書署名要求(CSR※)と呼ばれる情報を精査した上で公開鍵証明書を発行する
- 公開鍵証明書の失効、CRLの発行
- 認証局は申請を受けて証明書の失効手続きを行い、証明書が失効されていることを以下の二つの手段で公開する
- 証明書失効リスト(CRL:Certificate Revocation List)の発行
- OCSP(Online Certificate Status Protocol)への応答
- 認証局は申請を受けて証明書の失効手続きを行い、証明書が失効されていることを以下の二つの手段で公開する
また認証局にはパブリック認証局とプライベート認証局(オレオレ認証局,自己証明認証局)がある。
パブリック認証局の発行したルート証明書(認証局が自らの正当性を証明するために発行するデジタル証明書)は、いわゆる公的機関の証明書の扱いであり一般的なメーラやブラウザに組み込まれている。
対してプライベート認証局は社内などの制限された場だけで利用することを想定されたもの。運用規定を自由に設定できるという柔軟性がある。
ディジタル署名
デジタル署名はデータが通信の途中で改ざんされていないこと、またメッセージが作成者本人のものであることを証明するための技術。
デジタル署名は送信するメッセージからハッシュ関数を用いてメッセージダイジェスト(MD)を求め、MDから秘密鍵を用いて署名を生成し送信する。 受信者は、公開鍵を用いて署名を検証(MDを復号)する。
またメッセージからMDを求め、復号したものと照合し、一致していることを確認するという仕組みといえる。
X.509
X.509はITU-Tが定めたPKIの標準規格のこと。 以下に関するフォーマットを定めている。
- 公開鍵証明書
- 認証局(CA)
- 証明書失効リスト(CRL)
6.1.4. サーバ証明書とクライアント証明書
サーバ証明書
サーバ証明書はでクライアントがアクセスしているサーバが確かに目的の相手に間違いないことを確認するために使用されるもので、サーバの公開鍵を含んだ証明書に認証局が署名をして発行されているのが一般的となる。企業内などでは、プライベート認証局を使って自己署名が行われる場合もある。
Webサイトなどにアクセスする際に提示される。
クライアント証明書
クライアント証明書は企業内LANや外部から自社内にアクセスする場合、クライアント側が正当な権利を持っているか確認する必要がある場合に用いられるもの。
6.2. X.509証明書と公開鍵暗号基盤
6.2.1. OpenSSL
SSL/TLSの実装としてのツールにOpenSSLがある。 OpenSSLの機能は以下の通り。
- 秘密鍵/公開鍵の作成、パラメータ管理
- 公開鍵の暗号操作
- X.509証明書と証明書署名要求(CSR)/証明書失効リスト(CRL)の作成
- メッセージダイジェストの計算
- RSA暗号方式による暗号化と復号
- SSL/TLSクライアントとサーバテスト
- S/MIME署名と暗号化メールの取り扱い
- タイムスタンプの要求/生成、検証
SSL/TLSとは
SSLはWebサーバとWebブラウザ間でよく使用される暗号化通信を行うための設定で、使用にはサーバ証明書が必要になる。
サーバ証明書にはサーバについての情報と、サーバの公開鍵、証明書を発行した認証局の情報とその署名が含まれる。
署名は、証明書を発行する認証局(CA)が「認証局の秘密鍵」で行う。SSLサーバはこの証明書をクライアントに渡し、クライアントであるブラウザは予め内蔵している認証局の公開鍵を使って、受け取った証明書の署名を復号する。復号できれば証明書が改ざんされていない(接続先サーバが正しい)ことが確認できる。
なお、サーバ証明書の署名はルートCAもしくは中間CAによって署名されますが、現在ではセキュリティレベルの向上などの理由で、ルートCAが直接署名するのではなく、中間CAを1つ以上用いる階層構造を取る認証が主流となっている。
opensslの設定ファイル
openSSLの設定ファイルは以下の通り。
- Debian系 …
/usr/lib/ssl/openssl.cnf
- RedHat系 …
/etc/pki/tls/openssl.cnf
opensslコマンド
OpenSSLの操作を行うコマンド。
openssl <サブコマンド> [オプション]
サブコマンド | 説明 |
---|---|
ca | CAの管理 |
ciphers | 使用可能な暗号スイートを一覧表示 |
crl | CRLの管理 |
dgst | メッセージダイジェストの計算 |
genrsa | RSA暗号方式の秘密鍵を生成 |
rsa | RSA暗号方式の鍵管理 |
req | CSRの管理 |
rsautl | RSAアルゴリズムを使用したメッセージの暗号化と復号 |
s_client | SSL/TLSプロトコルを使用し指定しサーバ接続 |
s_server | SSL/TLSプロトコルを使用しデータを受け取るサーバとして動作 |
verify | X.509証明書の検証 |
x509 | X.509証明書の管理 |
OpenSSLのコマンド例
# 設定ファイルの確認
openssl ca
# openssl genrsa はRSA秘密鍵の生成を行う
# 秘密鍵の作成(TripleDES方式で暗号化したRSA形式の秘密鍵を2048bitで作成)
openssl genrsa -out private.key -des3 2048
openssl genrsa -des3 2048 > /etc/pki/CA/private/cakey.pem
# 秘密鍵の作成
openssl genrsa -<algorithm> -out <key_filename> <key_size>
openssl genrsa -aes128 -out mykey.key 2048
# openssl rsa は秘密鍵の管理を行う
# 暗号化された秘密鍵を暗号化解除したファイルの変換する
openssl rsa -in private.key -out private-nopass.key
# 秘密鍵から公開鍵を作成する
openssl rsa -in private.key -pubout -out publkey.key
# RSA形式の秘密鍵の内容を確認する
openssl rsa -in private.key -text
# RSA形式の公開鍵の内容を確認する
openssl rsa -publin -in pubkey.key -text
# openssl rsautl はRSAを利用したデータの暗号化/復号化を行う
# 公開鍵を用いたテキストの暗号化
openssl rsautl -encrypt -pubin -inkey pubkey.key -in sample.txt -out sample.txt.enc
# 秘密鍵を用いてテキストの復号
openssl rsautl -decrypt -inkey private.key -in sample.txt.enc -out sample.key
# openssl req はCSRを生成する
# 公開鍵の作成
openssl req -utf8 -new -key <key_filename> -x509 -days <cert-lifespan> -out <cert_filename> -set_serial 0
# X.509形式のCSRの新規作成
openssl req -new -key <priv_key.pem> -out <output.csr>
# openssl ca は認証局の証明書を管理する
# サーバ証明書の発行
openssl ca -out newcert.pem -days 365 -keyfile private.pem -infiles newcsr.pem
# 証明書の失効
openssl ca -revoke newcert.pem
# CSRにCAとして署名する
openssl ca -in <CSR> -out <crt>
# 証明書情報の確認
openssl x509 -in <cert_filename.crt> -text -nout | less
# PEM形式の証明書をDER形式に変換する
openssl x509 -inform PEM -outform DER -in newcert.pem -out newcert.der
OpenSSLによる証明書の作成と操作
openssl
コマンドにより秘密鍵/証明書などを作成できる。
使用例は以下の通り。
# 秘密鍵の生成
openssl genrsa -<algorithm> -out <key_filename> <key_size>
openssl genrsa -aes128 -out mykey.pem 2048
# 自己証明書(オレオレ認証)の生成
openssl req -utf8 -new -key <key_filename> -x509 -days <cert_lifespan> -out <cert_filename>
#認証の表示
openssl x509 -in mycert.crt -text -noout
#CSR(証明書失効リスト)の作成
openssl req -new -key <priv_key.pem> -out <output.csr>
OpenSSLによるX.509証明書形式の変換
#DERをPEMに変換する
openssl x509 -inform der -in certificate.cer -out certificate.pem
#PEMをDERに変換する
openssl x509 -outform der -in certificate.pem -out certificate.der
#p7b/pkcs#7をPEMに変換する
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.pem.
#PEMをp7b/pkcs#7に変換する
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
OpenSSLによるトラブルシューティング
## セキュアなコネクションの確立
openssl s_client -connect <host>:<port>
## トラストチェーンの検証
openssl verify -verbose <certificate>
## CAチェーンのすべての証明書を確認する
openssl s_client -connect <host>:<port> -showcerts
## 証明書の詳細を見る
openssl x509 —text <cert_file>
6.2.2. Genkey
genkeyはOpensslの互換ツールでRedHat系OSで使用できるもの。 コマンドはOpenSSLより単純で、TUIが使用できる。
6.2.3. X.509証明書
X.509証明書
X.509証明書は公開鍵基盤の標準規格であるX.509により定義された公開鍵証明書のこと。
X.509とはITU-T(国際通信連合(ITU)の電気通信標準化部門)の規格であり、公開鍵暗号方式に基づいて認証局によって発行される公開鍵証明書の標準形式などを定めてたもの。
Webサービスやメールなどで使用されている。
X.509証明書にはいくつかのエンコードタイプがあるが、代表的なものにPEMとDERがある。
- PEM
- DERをBase64でテキスト化したもの
- サーバー証明書、中間証明書、および秘密キーを1つのファイル内に含めることができる
- テキスト エディタで開くことができる
- OpenSSLデフォルトのファイル形式
- DER
- JavaベースのWebサーバーに使用される
- Binary形式
- PKCS#7
- 証明書のみを保存する
- 秘密キーは保存できない
- PKCS#10
- PKCS#12
- Windowsプラットフォームで使用される
- サーバー証明書、中間証明書、および秘密キーをパスワードで保護された単一の
.pfx
ファイル内に保存できる
また、それぞれの特徴を表にまとめると以下の通り。
フォーマット | エンコード | ファイルフォーマット |
---|---|---|
PEM | Base64 ASCII | .crt、.pem、.cer、.key |
DER | Binary | .der または .cer |
PKCS#7 | Base64 ASCII | |
PKCS#12 | Binary | .pfx、 .p12 |
X.509証明書のライフサイクル
公開鍵証明書には、発行。使用、更新、破棄といったライフサイクルが存在する。
公開鍵基盤では証明書のライフサイクルを管理する仕組みがあり、認証局がそれを行う。
X.509証明書のフィールド
フィールド1 | フィールド2 | 説明 |
---|---|---|
署名前証明書(tbsCertificate) | 証明書の基本情報と公開鍵の情報 | |
バージョン(version) | X.509証明書のバージョン X509v3では3(0x2) | |
シリアル番号(serialNumber) | 証明書の識別番号 | |
署名(signature) | CAが証明書に署名する際のアルゴリズム | |
発行者(issuer) | CAの名前 | |
有効期間(validity) | 証明書の有効期間 | |
サブジェクト(subject) | 証明書の所有者の名前 | |
サブジェクト公開情報(subjectPublicKeyInfo) | 証明書所有者の公開鍵に関する情報 | |
証明書拡張(extentions) | 拡張領域。X.503v3にて追加 | |
署名アルゴリズム(signatureAlogorithm) | 証明書の署名アルゴリズム | |
署名値(signatureValue) | デジタル署名 |
X.509証明書v3の拡張フィールド
拡張フィールド | 説明 |
---|---|
basicConstraints(基本制約) | 基本制約。証明書がCAのものである、証明書のパスの深さなどを指定 |
authorityKeyIdentifier(認証局鍵識別子) | 認証局鍵識別子 |
subjectKeyIdentifier(サブジェクト識別子) | サブジェクト識別子 |
KeyUsaga(鍵の用途) | 鍵の用途 |
extendedKeyUsage(拡張鍵用途) | 鍵の用途を限定 |
certificatePolicies(証明書ポリシ) | 証明書の目的や発行時情報 |
subjectAltName(所有者別名) | サブジェクトの代替名 |
cRLDistributionPoints(CRL配布ポイント) | CRLの配布ポイント |
authorityInfoAccess(機関情報アクセス) | 認証局に関する追加情報へアクセス |
6.2.4. Let’s Encrypt
Let’s EncryptとはX.509証明書を無料で発行している認証局(CA)のこと。
すべてのWebサイトの暗号化を目指す非営利団体ISRG(Internet Security Research Group)によって運営されている。
SSLサーバ証明書の種類
SSLサーバ証明書には認証する内容によっていくつかの種類がある。
- DV(Domain Validation:ドメイン認証)
- ドメイン名の所有者であることを証明する
- OV(Organization Validation:企業認証)
- ドメイン名の所有者であること、ドメイン名に登録されている企業が法的に実在していることを証明する
- EV(Extended Validation:拡張検証)
- ドメイン名の所有者であること、ドメイン名に登録されている企業が物理的・法的に実在していることを証明する(電話による在籍確認など、OVよりも厳しい審査が行われる)
このうちLet’s Encryptが発行しているのはDVタイプのサーバ証明書となる。
ACME
Let’s Encryptは、ACME(Automatic Certificate Management Environment:自動証明書管理環境)という証明書の管理を自動化するプロトコルを用いている。
ACMEプロトコルは、通常、証明書の発行に必要な鍵の作成、CSRの作成とCAへの送信、証明書の設定や更新などの手続きを自動化する。
Let’s Encryptが推奨するACMEクライアントにCertBotがある。
6.2.5. CFSSL
CFSSLはOpenSSLよりも簡単に証明書や認証局を作成できるコマンドでCloudFlareが公開している。
JSON形式の設定ファイルを用いて一連の作業を自動化し、証明書管理を簡素化が可能。
CFSSLの使い方
CFSSLを使用して証明書を作成するのは以下の手順の通り。
- CA(認証局)の作成
- CAの生成
- サーバ証明書の生成
まずはCAの作成のためCAの設定ファイルとCSRをjsonで作成する。
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"server": {
"usages": [
"signing",
"key encipherment",
"server auth"
],
"expiry": "8760h"
},
"client": {
"usages": [
"signing",
"key encipherment",
"client auth"
],
"expiry": "8760h"
}
}
}
}
{
"CN": "My CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "JP",
"L": "Tokyo",
"O": "My Company",
"OU": "My CA Unit",
"ST": "Tokyo"
}
]
}
設定ファイルと署名要求ファイルができたら、cfsslとcfssljsonコマンドを組み合わせてCAの鍵と証明書を生成する。
cfssl genkey -initca ca-csr.json | cfssljson -bare ca
このコマンドを実行すると、ca.pem(CA証明書)、ca-key.pem(CA秘密鍵)、ca.csr(CAのCSR)が生成される。
次に作成したCAを使ってサーバー証明書を発行する。
server-csr.json
{
"CN": "example.com",
"hosts": [
"example.com",
"www.example.com",
"127.0.0.1"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "JP",
"L": "Tokyo",
"O": "My Company",
"OU": "Web Server",
"ST": "Tokyo"
}
]
}
CAの秘密鍵と証明書、そしてサーバー証明書のCSRを使って、サーバー証明書を生成する。
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare server
このコマンドを実行すると、server.pem(サーバー証明書)とserver-key.pem(サーバーの秘密鍵)が生成される。
6.3. 暗号化/署名および認証のX.509証明書
6.3.1. SSL/TLS
SSL(Secure Sockets Layer)/TLS(Transport Layer Security)はトランスポート層の暗号化プロトコルでWebトランザクションを保護するために開発されたが、トランスポート層でTCPを利用するあらゆる種類のネットワークトラフィックの保護にも使用できる。
TLSとしてIETFによってRFC化され、SSL3.0からTLSが派生した。SSL3.1がTLS1.0に該当する。一般的名称として、SSLという言葉が広く普及しているため、SSL/TLSと呼ばれている。
現在、SSLは脆弱性が発見されているため使用は非推奨となっており、TLSの使用が推奨されている。暗号強度等ではTLS1.2、もしくは2018年3月にIETFに承認されたTLS1.3が良い。
項目 | SSL | TLS |
---|---|---|
正式名称 | Secure Sockets Layer | Transport Layer Security |
プロトコル | Web トラフィックを保護するために使用されていたプロトコル | TLS プロトコルは、SSLv3 に代わる TLS 1.0 から始まる SSL の後継プロトコル |
状況 | 最新バージョンは SSLV3 だが、これは非推奨 | 現在の標準は TLS 1.2 。ただし、TLS 1.3 はインターネット標準として目的とされている |
TLS/SSLのハンドシェイクプロセス
TLS は、データを安全に送信する際のパフォーマンスとセキュリティの間で適切な妥協点を提供するため、公開鍵暗号方式と共通鍵暗号方式を組み合わせて使用する。 手順は以下の通り。
- 各TLS証明書は、公開キーと秘密キーで構成されるキーペアで構成される。これらのキーは、Web サイトのトランザクション中に相互作用する。
- Web サイトにアクセスするたびに、クライアント サーバーと Web ブラウザが通信して、安全な TLS/SSL 暗号化接続が確立されていることを確認する。
- Web ブラウザ (またはクライアント) がセキュリティで保護された Web サイトにアクセスすると、Web サイト サーバーは TLS/SSL 証明書とその公開キーをクライアントと共有して、安全な接続と一意のセッション キーを確立する。
- ブラウザは、SSL 証明書の発行者または認証局を認識し、信頼していることを確認する。また、ブラウザは、TLS/SSL 証明書の有効期限が切れていないこと、取り消されていないこと、および信頼できることを確認する。
- ブラウザは対称セッションキーを送り返し、サーバーは秘密キーを使用して対称セッションキーを復号化する。次に、サーバーはセッションキーで暗号化された確認応答を送り返し、暗号化されたセッションを開始する。
- サーバーとブラウザは、送信されるすべてのデータをセッションキーで暗号化するようになる。これらは、メッセージのプライバシー、メッセージの整合性、およびサーバーのセキュリティを保護する安全なセッションを開始することを意味する。
トランスポート層のセキュリティ
SSL と TLS はどちらも以下のセキュリティ要件を満たす。
- 交換されるデータを安全に暗号化する
- 少なくとも1人の当事者を認証する
- データの整合性を確保する
- リプレイ攻撃を防ぐ
トランスポート層のセキュリティは、PKI と一般的な暗号化の使用を通じてこれを実現する。
SSLに対する中間者攻撃
- POODLE攻撃の脆弱性
- POODLE攻撃(CVE-2014-3566) はSSLセッション内の選択されたコンテンツを復号化できる中間者(MITM) エクスプロイトのこと。
- BEAST攻撃の脆弱性
- BEAST攻撃(CVE-2011-3389)はSSL/TLS 暗号ブロック チェーン (CBC) の弱点を悪用し、中間者攻撃者が Cookie データなどの特定のセッション情報を何からでも回復できるようにする。
ApacheのHTTPSの設定(SSL/TLSを使ったHTTP)
HTTPSと呼ばれるプロトコルはWebのプロトコルであるHTTPをSSL/TLSでセキュアなプロトコルとして通信させるもの。 代表的なWebサーバ(httpd)であるApacheもSSL/TLSに対応しており、パッチまたはモジュール(mod_ssl)での対応が可能となっている。
Apacheの基本的な動作設定は/etc/httpd/conf/httpd.conf
にて行う。
SSLの設定も同ファイルに記述できるが、デフォルトでは/etc/httpd/conf.d/ssl.conf
が用意されており、ここに記述するのが一般的となる。
<VirtualHost 192.168.0.1:443>
ServerName test-server1.com
DOCUMENTRoot /var/www/html/ssl_test-server1
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!SHA1
SSLCertificateFile /etc/pki/tls/certs/server1_cert.pem
SSLCertificateKeyFile /etc/pki/tls/private/server1_key.pem
SSLCertificateChainFile /etc/pki/tls/certs/cacert.pem
ErrorLog logs/ssl_test-server1_error_log
CustomLog logs/ssl_test-server1_access_log combined env=!no_log
</VirtualHost>
サーバ認証関連のディレクティブ | 説明 |
---|---|
SSLEngine on/off | SSL/TLSプロトコルを使用するかどうかの設定 |
SSLProtocol SSLv3/TLSv1/TLSv1.2 | SSL/TLSのバージョン指定 |
SSLCipherSuite !AAA/-AAA/+AAA | 使用する暗号化スイートの指定 |
SSLCertificateFile | サーバ証明書の指定 |
SSLCertificateKeyFile | サーバの秘密鍵を指定 |
SSLCertificateChainFile | 中間認証局(CA)の証明書を指定 |
SNI
SNI(Server Name Indication)は1つのWebサーバで複数のドメインのSSL/TLS証明書を利用できる仕組み。 名前ベースのVirtualHostであってもSSLに対応できるようにしたSSL/TLSの拡張仕様ともいえる。
SNIでは、コネクション確立時にクライアントからサーバへアクセスしたいホスト名を渡すことにより、適切なサーバ証明書を返すことができる仕様とした。 これにより、コネクション前にホスト名を確認することが可能となり、名前ベースの仮想ホストを使用可能となった。
SNI関連のディレクティブ | 説明 |
---|---|
SSLStrictSNIVhostCheck on/off | 非SNIクライアントの挙動設定 |
HSTS
HSTS(HTTP Strict Transport Security)はWebセキュリティの仕組みの一つでウェブサイトがHTTPSを使用することを強制するための仕組みのこと。
HSTSはウェブブラウザに対して、特定の期間内でHTTPSを使用するように指示する。
HSTSの主な目的はMITM攻撃を防ぐことにある。 通常、攻撃者はHTTP通信を盗聴し、変更することができるが、HTTPSを使用すると通信が暗号化され、改ざんや盗聴が難しくなる。 HSTSは、ウェブサイトがHTTPSを使用するように強制し、ユーザーが暗号化された通信を確実に得ることを支援する。 クライアントが一度HTTPSでアクセスしたサイトがHSTSを強制するようクライアントに指示した場合、以後一定の有効期間内はクライアント側からはHTTPSで通信を行うようになる。
また、初回のHTTPSアクセスまでの脅威に対応するため、予め「このドメインはHSTSに対応している」という情報をブラウザ側に知らせておく「プリロードHSTS(Preload HSTS)」という仕組みも提唱されてきている。
<VirtualHost 192.168.0.1:443>
ServerName test-server1.com
DOCUMENTRoot /var/www/html/ssl_test-server1
:
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>
Apacheのクライアントアクセス制御
SSL/TLSを利用したApacheでは、クライアントの証明書を使ってアクセス制御を行うことができる。 この仕組みを使うことで許可されたユーザのみにWebサーバへのアクセスを可能にできる。
「ssl.conf」では設定項目SSLVerifyClient
により、クライアントに対して証明書を提示させるよう指定することができる。
<VirtualHost 192.168.0.1:443>
:
SSLCACerificateFile /etc/pki/tls/certs/cacert.pem
SSLCARevocationFile /etc/pki/tls/certs.crl.pem
SSLVerifyClient require
SSLVerifyDepth 1
:
</VirtualHost>
クライアント認証関連のディレクティブ | 説明 |
---|---|
SSLCACertificateFile | クライアント証明書を発行したCAの証明書を指定 |
SSLCARevocationFile | クライアント証明書のCRLファイルを指定 |
SSLVerifyClient | クライアントの認証レベルの指定(none,optional,require,optional_no_ca) |
SSLVerifyDepth | 有効なクライアント証明書を確認する深さを指定 |
OCSP Stapling
OCSPはクライアントがOCSPサーバ(OCSPレスポンダ)へ問い合わせを行い、証明書の失効確認を行うためのプロトコル。
しかし、レスポンダとの通信次第で問い合わせに遅延が発生し、確認手続きが失敗するなどの弊害もあった。これに対応する方法としてOCSPを拡張したものが、OCSP stapling(OCSPステープリング)となる。 クライアントが行っていたOCSPレスポンダへの問い合わせを証明書提供側のサーバが行うことにより、クライアントが確認手続きで失敗するリスクをなくす。
「ssl.conf」では設定項目SSLUseStapling
にて有効化するか否かを選択できる。
#OCSP Stapling:
SSLUseStapling On
SSLStaplingResponderTimeiut 5
SSLStaplingReturnResponseErrors off
SSLStaplingCache "shmcb:logs/ssl_stapling(32 768)"
OCSP stapling関連のディレクティブ | 説明 |
---|---|
SSLUseStapling on/off | OCSP staplingの有効/無効 |
SSLStaplingResponderTimeiut | OCSP staplingの応答タイムアウト |
SSLStaplingReturnResponseErrors on/off | OCSP staplingのエラーをクライアントに送信するかどうか |
SSLStaplingCache | OCSP staplingのキャッシュに使用するストレージタイプ |
CipherSuite
CipherSuiteは暗号化の組み合わせのことを指す。 SSL/TLSで使用できる暗号化には様々な種類があり、暗号といっても、目的によって使用できる暗号技術が異なる。
SSL/TLSの動作は複数の暗号技術の組み合わせで成り立っており、通信の開始から終了までの間に数種類の暗号技術を使用する。
この組み合わせは暗号スイートと呼ばれ、OpenSSLではopenssl chipers
コマンドで使用できる暗号スイートを確認できる。
SSL/TLSのクライアントとサーバでのテスト使用
opensslではSSL/TLSクライアント/Webサーバとしててテスト動作可能。
openssl s_server
コマンドでSSL/TLSのWebサーバとして動作openssl s_client
コマンドでSSL/TLSクライアントとして動作
# 証明書/秘密鍵/中間CA証明書を指定しWebサーバとして動作
openssl s_server -cert newcert.pem -key newkey.pem -XAfile cacert.pem -WWW
# SSL/TLSで192.168.0.1の1443ポートへ接続する
openssl s_client -connect 192.168.0.1:1443 -CAfile cacert.pem
6.4. 暗号化ファイルシステム
6.4.1. ディスク暗号化の基礎
ディスク全体の暗号化は盗難や偶発的な紛失の場合にディスクを保護する。 ディスク全体の暗号化では、スワップファイル、システムファイル、休止状態ファイルを含むディスク全体が暗号化される。 暗号化されたディスクが紛失、盗難された場合でも、ドライブの暗号化状態は変更されず、許可されたユーザーのみがその内容にアクセスできる。
ファイルの暗号化では起動中にシステムにログインし、その後コンピュータを放置した場合、権限のないユーザーはディスク上の任意のファイルを開くことができないようにできる。
またファイルシステムの暗号化は以下の方法がある。
- ブロックデバイス
- ディスクまたはパーティションの暗号化
- ファイルシステムレベル
- ファイルシステムや特定のディレクトリの暗号化
ディスク暗号化ツール
ディスクを暗号化するためのツールは以下のようなものがある。
- ブロックデバイスの暗号化
- dm-encryptとLUKS (通常は連携して使用する)
- cryptmount (エンドユーザーがデータを暗号化するのに役立つ)
- ファイルシステムレベルの暗号化
- eCryptfs (ファイルシステムレベルの暗号化)
- EncFS (eCryptfs互換)
6.4.2. ブロックデバイスとファイルシステムの暗号化
dm-cryptとLUKS
dm-cryptsはブロックデバイスの暗号化を行う暗号化の方法の1つ。 dm、すなわちdevice-mapper(デバイスマッパー:物理デバイスと論理デバイスをマッピングするLinuxカーネルの標準機能)の暗号化機能を使ってデバイス全体に対する暗号化を行う。
dm-cryptを扱うためのツールには以下の2つがある
cryptsetup
… 暗号化デバイスの作成・管理・各種操作cryptmount
… 暗号化ファイルシステムのマウント・アンマウントなど
cryptsetupコマンドでは、暗号化のタイプとしてplain(plain dm-crypt)モードとLUKSモードを選択することができる。
LUKS(Linux Unified Key Setup:ラックス)とはLinuxにおけるディスク暗号化の標準仕様で、dm-cryptを用いて実装されている。 ファイルシステムに依存しておらず、Linuxで一般的なファイルシステムのext3やext4、Brtfs、さらにSWAP領域を暗号化することも可能である。
/etc/crypttab
- cryptsetupで設定した暗号化ボリュームをOS起動時に自動的にマウントするためには、「/etc/crypttab」にエントリを追加する必要がある
- 「/etc/crypttab」は「/etc/fstab」より先に読み込まれるため、暗号化を解除した上で復号されたファイルシステムをマウントすることが可能になる
eCryptfs
eCryptfsはファイルシステムの暗号化を行う技術の一つで、ファイルやディレクトリを暗号化することができるもの。 dm-cryptと異なり、ブロックデバイスではなくファイルやディレクトリを暗号化する。 カーネルモードで動作し、各ファイルのヘッダに暗号化メタデータを持つことにより、ホスト間で暗号化ファイルをやり取りすることができる。 特にUbuntuにおけるホームディレクトリの暗号化の仕組みとして広く利用されている。
またecryptfsd
と呼ばれるデーモンによって制御が行われ、ecryptfs-*コマンドで各種操作を行う。
ENcFS
ファイルの暗号化のシステムとして、eCryptfsのほかにEncFS(Encrypted Filesystem)が知られている。
歴史はeCryptfsよりも古く、暗号化ファイルシステムとしては最も扱いやすいファイルシステムと言われている。FUSE(Filesystem in Userspace:カーネルを弄ることなくユーザ空間でファイルシステムを作成するソフトウェア)を用いているため制約もありますが、GUIや、WindowsやMacなどのOSもサポートされているのが特徴である。
6.4.3. dm-crypt
dm-cryptはブロックデバイスの暗号化を行うコマンド。 dm-cryptを扱うためのツールには以下の2つがある。
cryptsetup
… 暗号化デバイスの作成・管理・各種操作cryptmount
… 暗号化ファイルシステムのマウント・アンマウントなど
cryptsetupコマンド
ブロックデバイスまたはループバックデバイスに対して暗号化ファイルシステムの利用を行うコマンド。
cryptsetup <アクション> <アクションごとのオプション>
plainモードはLUKSなどの暗号化オプションを使用しない標準の利用方法。
アクション【plainモード】 | 説明 |
---|---|
open –type plain デバイス名 名称 | マッピング名とデバイスを指定して暗号化マッピングの作成 |
close 名前 / remove 名前 | 暗号化マッピングの削除 |
resize 名前 | 暗号化マッピングのサイズ変更 |
status 名前 | 暗号化マッピングの状態表示 |
LUKSモードはLinuxの標準暗号化規格のLUKSを使用したモード
アクション【LUKSモード】 | 説明 |
---|---|
luksFormat デバイス名 | デバイスをLUKSパーティションとして初期化 |
luksOpen デバイス名 名前 | デバイスとLUKSパーティション名を指定しLUKSパーティションを開く |
luksClose 名前 | Luksパーティションを閉じる |
luksAddkey デバイス名 キーファイル名 | LUKSパーティションにパスフレーズを追加 |
luksKillSlot デバイス名 キースロット番号 luksDelKey デバイス名 キースロット番号 | LUKSパーティションから設定したパスフレーズを削除 |
luksDump デバイス名 | LUKSパーティションの状態表示 |
isLuks デバイス名 | デバイスがLUKSパーティションの場合は真をそうでない場合は偽を返す |
# ===========================================
## LUKSモードを使用した暗号化パーティションの設定
# ===========================================
# 暗号化パーティションを初期化して作成
cryptsetup luksFormat /dev/sdb1
# 暗号化パーティションのヘッダー情報を確認
cryptsetup luksDump /dev/sdb1
# 暗号化済みパーティションを開く
cryptsetup luksOpen /dev/sdb1 lukstest
# ファイルシステムの作成/マウント
mkfs -t ext4 /dev/mapper/lukstest
mkdir /mnt/lukstest
mount /dev/mapper/lukstest /mnt/lukstest/
# ============================
# 暗号化パーティションを閉じる
# ============================
unmount /mnt/lukstest
cryptsetup luksClose lukstest
ls /dev/mapper # LuksCloseの確認
# ============================
# パスワードの追加
# ============================
cryptsetup luksAddKey /dev/sdb1
cryptsetup luksDump /dev/sdb1 # ヘッダ情報の確認
# ============================
# パスワードの削除
# ============================
cryptsetup luksKillSlot /dev/sdb1 0
cryptsetup luksDump /dev/sdb1 # ヘッダ情報の確認
# ===========================================
## 暗号化パーティションをOS起動時に自動マウント
# ===========================================
# キーファイルの作成とそれをパスワードの代わりに使用
dd bs=512 count=4 if=/dev/urandom of=/etc/lukstestkey
cryptsetup luksAddKey /dev/sdb1 /etc/lukkstestkey
# /etc/crypttabに以下のマウント情報を追加
lukstest /dev/sdb1 /etc/lukstestkey luks,timeout=180
# /etc/fstabにマウント情報を追加
/dev/mapper/lukstest /mnt/lukstest ext4 defaults 1 3
cryptmountコマンド
ブロックデバイスまたはループバックデバイスに対して暗号化ファイルシステムを作成するコマンド。
- ファイルシステムとSwap両方の暗号化が可能
- 暗号化されたファイルシステムは通常のファイルシステム同様にブロックデバイスに格納可能
- 暗号化領域の作成にはルート権限が必要、その後の利用は一般ユーザでも可能
cryptmount [オプション] [ターゲット]
オプション | 説明 |
---|---|
-m | ターゲットのマウント |
-u | ターゲットのアンマウント |
-S | ターゲットのマウント状況の表示 |
-l | 利用可能なターゲットの基本情報の表示 |
-s | ターゲットのスワップ領域の有効化 |
-x | ターゲットのスワップ領域の無効化 |
-p | ターゲットに対するデバイスの準備 |
-r | ターゲットから全デバイスの開放 |
-c | ターゲットのパスワード変更 |
-g | 復号キーの作成 |
# 暗号キーファイルの作成
cryptmount --generate-key 32 crypttest
# /dev/mapperにデバイスをマッピング
cryptmount --prepare crypttest
# ターゲットの基本情報の表示
cryptmount --list
# 暗号化ファイルシステムのマウント
cryptmount -m crypttest
cryptsetupによる暗号化デバイスの利用方法
cryptsetup
を用いて暗号化デバイス(パーティション)を利用する流れは以下の通り
- (LUKSモード利用時)luksFormatによるパーティションの初期化
cryptsetup luksFormal /dev/sdb2
- openまたはluksOpenによる暗号化マッピングの作成
cryptsetup open --type plain /devsdb1 dm01
cryptsetup luksOpen /dev/sdb2 dm02
- mkfsおよびパーティションのマウント
mkfs.ext4 /dev/mapper/dm02
mount /dev/mapper/dm02 /mnt/luks
なお利用終了時は、アンマウントし暗号化マッピングを削除する。
- パーティションのアンマウント
unmount /mnt/luks
- closeまたはluksCloseによる暗号化マッピングの削除
cryptsetup close dm01
cryptsetup luksClose dm02
6.4.4. eCryptfs
eCryptfsはファイルシステムの暗号化を行う技術の一つで、ファイルやディレクトリを暗号化することができるもの。 擬似ファイルシステムとも呼ばれ、マウントすることでeCryptfs層を通過させることにより復号を行う。
カーネルモードで動作し、各ファイルのヘッダに暗号化メタデータを持つことにより、ホスト間で暗号化ファイルをやり取りすることができる。
特にUbuntuにおけるホームディレクトリの暗号化の仕組みとして広く利用されている。
またecryptfsd
と呼ばれるデーモンによって制御が行われ、ecryptfs-*コマンドで各種操作を行う。
ecryptfsコマンド
ecryptfsコマンドはecryptfsの操作を行うコマンド。
mount.ecryptfs
, umount.ecryptfs
でも操作をおこ会う。
オプション | 説明 |
---|---|
ecryptfs-setup-private | 暗号化ディレクトリのセットアップ |
ecryptfs-migrate-home | ユーザディレクトリの暗号化 |
ecryptfs-mount-private | 暗号化ディレクトリのマウント |
ecryptfs-umount-private | 暗号化ディレクトリのアンマウント |
ecryptfs-unwrap-passphrase | パスフレーズの複合 |
# eCryptfsのセットアップを行う
ecryptfs-setup-private
# 暗号化ディレクトリのマウント、アンマウントを行う
ecryptfs-mount-private
ecryptfs-umount-private
# rootユーザが、一般ユーザのホームディレクトリ全体を暗号化するコマンド
ecryptfs-migrate-home
# 「wrapped-passphrase」を復号する
ecryptfs-unwrap-passphrase
なおファイルのマウントはmount -t encryptfs
コマンドでも可能となる。
また、マウントした状態(復号した状態)でバックアップを取ると、暗号化されていないデータもバックアップされることになるので注意する。
暗号化した状態のみにしたい場合はumountしてからバックアップを実施する。
eCryptfsのディレクトリ構造
ecryptfs-migrate-homeコマンドなどにより暗号化ディレクトリを作成すると、以下のようなファイルやディレクトリが作成される。
$HOME
├ Private/ ... 復号されたデータを含むマウントポイント
├ .ecryptfs/
│ ├ Private.mnt ... 暗号化ディレクトリのマウントポイントが書かれたファイル
│ ├ Private.sig ... 暗号化パスフレーズの署名ファイル
│ ├ wrapped-passphrase ... マウント用の暗号化パスフレーズ
│ ├ auto-mount ... 自動マウント用の空ファイル
│ └ auto-umount ... 自動アンマウント用の空ファイル
└ .Private/ ... 暗号化されたデータを含むディレクトリ
6.4.5. ENcFS
encfsパッケージは ecryptfs と同様の機能を提供するが、スーパーユーザー以外が使用するように設計されている。
6.4.6. NBDE
NBDE(Network Bound Disk Encryption)はネットワーク経由でディスクの暗号化と復号を行う技術のこと。
安全なネットワークを経由して専用のサーバーでパスフレーズを自動的に生成することにより、ディスクの暗号化・復号を自動化することができる。
NBDEは、LUKSによるディスクの暗号化を利用しつつ、ネットワークを介したパスフレーズの管理機能を提供する。
Clevis
ClevisはNBDEの実装でTangと呼ばれるサーバーを用いてパスフレーズを作成し、ディスクの暗号化を解除する。
またPin(ピン)と呼ばれるプラグインによって機能を拡張できる。
Clevisの代表的なPinは以下の通り。
- TPM2 … TPM2ポリシーを使用してディスクの暗号化を解除する。TPMとはTrusted Platform Moduleの略。
- Tang … ネットワークサーバーを使用してディスクの暗号化を解除する
6.5. DNSと暗号化
6.5.1. DNSの概要
DNSとは
DNSはIPアドレスやその他のデータを保存し、名前によるクエリを可能にする階層型の仕組みのこと。 DNS サーバーはドメイン名のデータベースを保存し、ネットワーク内のクライアントからの DNS クエリに基づいてドメイン名を処理する。
DNSサーバの種類
DNSサーバには以下の種類がある。
- マスタDNSサーバ(権威DNSサーバ)
- ゾーンファイルを所有するDNSサーバ
- A、AAAA、CNAME などのDNS名レコードを保持する
- スレーブDNSサーバ(キャッシュDNSサーバ)
- マスターDNSサーバのゾーン情報をコピーするDNSサーバ
- ドメインに対する以前のクエリに基づいてキャッシュファイルを構築している
再帰問い合わせと反復問い合わせ
ドメイン名とIPアドレス対応に関する問い合わせは再帰問い合わせ(Recursive query)と反復問い合わせ(Iterative query)の2種類がある。
- 再帰問い合わせ
- リゾルバからの問い合わせ要求を受けたDNSサーバが、他のDNSサーバに問い合わせを行い、その最終的な結果をリゾルバに応答する必要のある問い合わせ
- 反復問い合わせ
- リゾルバから再帰問い合わせを受けたキャッシュDNSサーバが、再帰問い合わせの結果を返すために、答えを得られるまで繰り返し他のDNSサーバへ行う問い合わせのこと
DNSゾーン
DNS構成はゾーンとリソースレコード で構成される。 ゾーンの種類は以下の通り。
- パブリックDNSゾーン * インターネットから参照できるゾーン * パブリックゾーンに DNS レコードを作成して、インターネット上にサービスを公開できる
- プライベートDNSゾーン * パブリックインターネット経由でクエリできないゾーンのこと
- サブゾーン
* ゾーンの所有者が NS レコードを使用してサブドメインを別のネーム サーバーに委任できるもの
*
example.com
の場合、aaa.example.com
やbbb.example.com
作成し、親ドメインのゾーンから見つけられるようにする(委任)するもの
スプリットビューDNS(スプリットホライズンDNS)
スプリットホライズンDNSを使用すると、要求に応じて同じ名前に対して異なる回答 (異なるリソースレコードセット) を提供できる。
この機能は、クエリが開発ネットワークから送信された場合はアプリの開発/ステージング バージョンを提供し、クエリがパブリックインターネットから送信された場合はアプリの運用/公開バージョンを提供するといったことに利用できる。
リソースレコード
リソースレコードはドメイン名と IP アドレスに関するデータを保存するために使用されるもの。 DNSゾーンのデータベースは、リソース レコードのコレクションで構成される。 各リソース レコードは、特定のオブジェクトに関する情報を指定する。
リソースレコードタイプ | 説明 |
---|---|
SOA | 管理情報の記述 |
NS | ゾーンを管理するDNSサーバを記述 |
MX | メールサーバを記述(正引きのみ) |
A | ホスト名に対するIPアドレスを記述(正引きのみ) |
AAAA | ホスト名に対するIPv6アドレスを記述(正引きのみ) |
CNAME | ホスト名の別名に対するホスト名を記述(正引きのみ) |
PTR | IPアドレスに対するホスト名を記述(逆引きのみ) |
TLSA | デジタル署名されたレコード。サーバ認証に使われる証明書や鍵の情報がドメイン名に対して関連付けられてDANE(DNSを使った認証の仕組み)で用いられる |
レコードセット
レコードセットは同じ名前と同じタイプで、データ値が異なるレコードのこと。 以下は同じ名前とタイプを持つ複数のレコードを含むレコードセットの例。
DNS名 | タイプ | TTL (秒) | データ |
---|---|---|---|
db-01.dev.gcp.example.com | A | 50 | 10.128.1.35 |
db-01.dev.gcp.example.com | A | 50 | 10.128.1.10 |
6.5.2. ドメインレジストラ
ドメインレジストラはパブリックゾーンのインターネットドメイン名の予約を管理する組織のこと。 レジストラは汎用トップレベル ドメイン (gTLD) レジストリまたは国コード トップレベル ドメイン (ccTLD) レジストリによって認定される必要がある。
6.5.3. SOAレコードのシリアル番号
SOAレコードのシリアル番号はDNSゾーンのバージョン番号のこと。 すべてのネームサーバーがゾーンの最新のバージョンであるためには、それらのネーム サーバーが同じSOAシリアル番号を持っている必要がある。
EDNS
EDNSはDNSの拡張プロトコルEDNS(Extension mechanism for DNS)のこと。 DNSでUDPを用いる場合、パケットサイズが512byteを超えることができないという制約を緩和するためのものともいえる。 EDNS の最も一般的な実装はDNSSECである。
また、EDNSは基本的なDNSプロトコルの枠組みは残したままで512byte以上の通信を可能にする。
DOビット/ADビット
EDNSによって拡張されたDNSパケットでは、DO bitという識別情報がやりとりされる。 DO=「DNSSEC OK」bitであり、このbitを識別できることがDNSSECを使用できる前提となる。つまりENDSを理解できない場合はDNSSECを利用といえる。
またDNSSECで認証確認が成立した場合は、DNS応答のAD(Authentic Data)ビットに1が格納される。
6.5.4. BINDの保護
TSIG
TSIGはトランザクション署名とも呼ばれるDNS メッセージを保護し、安全なサーバー間通信を提供するための仕組みのこと。BIND v8.2 以降で使用できる。 DNSサーバ同士でなりすましを防ぐために認証を行う仕組みともいえる。
TSIG は2つのDNS サーバー間の次のタイプのトランザクションを保護できる。 TSIG は、共有シークレットと一方向ハッシュ関数を使用して DNS メッセージを認証する。
chroot jailによるBIND実行
chrootは指定したディレクトリを新しいルートディレクトリとしてプロセスを制限できる機能のこと。 この機能によりディレクトリ内のソフトウェアが乗っ取られても、被害をソフトウェア内だけにとどめることができる。
/etc/named.confの主要なディレクティブ
CentOSにおける設定例は以下の通り。
options {
listen-on port 53 { 127.0.0.1; };
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
allow-query { localhost; };
recursion yes;
dnssec-enable yes;
dnssec-validation yes;
managed-keys-directory "/var/named/dynamic";
pid-file "/run/named/named.pid";
session-keyfile "/run/named/session.key";
/* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
include "/etc/crypto-policies/back-ends/bind.config";
};
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
ディレクティブ | 説明 |
---|---|
allow-query | ネームサーバーへのクエリを許可するホストを指定する |
allow-recursion | 再帰クエリに適用できる。デフォルトではすべてのホストがネームサーバー上で再帰的クエリを実行できる。 |
allow-transfer | ゾーンの情報の転送要求を許可するスレーブサーバーを指定する。デフォルトではすべての転送リクエストが許可される。 |
allow-update | ゾーン内の情報を動的に更新できるホストを指定する。デフォルトでは、すべての動的更新リクエストが拒否される。 |
Rndc
rndc (リモート ネーム デーモン コントロール)は、BIND にてローカルホストまたはリモートホストから指定されたデーモンをコマンドラインで管理できるようにするツール。BIND 9.0以降で使用できる。
rndcは、デジタル署名された名前付きコマンドを TCP 接続経由で送信する。
rndc の設定ファイルは/etc/rndc.conf
となる。
この構成ファイルには、接続するネームサーバーやデジタル署名に使用するキーなどの構成情報が保存される。
rndc ユーティリティは、初期化スクリプトを使用してnamedが開始されるときに開始される。
rndc.conf
ファイルはrndc-confgen
コマンドユーティリティを使用してランダムキーを使用して生成できる。
6.5.5. DNS関連のコマンド
digコマンド
dig(Domain Information Groper)コマンドはDNSにクエリを実行するためのコマンド。 DNS 問題の検証とトラブルシューティングに使用できる。
dig <ドメイン名>
digコマンド | 説明 |
---|---|
dig google.com MX | ドメインの MX レコードをクエリする |
dig google.com SOA | ドメインの SOA レコードをクエリする |
dig google.com TTL | ドメインの TTL レコードをクエリする |
dig @8.8.8.8 google.com | クエリに別の DNS サーバーを使用する |
dig | digコマンドのバージョンとルートDNS サーバーを表示します |
delvコマンド
delvコマンドはBIND 9.10以降のdigコマンドの後継ツール。
delv <オプション> ドメイン名
オプション | 説明 |
---|---|
+rtrace | クエリされたすべてのレコードリソースをリストするだけ。DNSSEC の詳細は含まれない |
+mtrace | rtrace と同じだが、すべてのレコードリソースの完全な内容が含まれる |
+vtrace | 多くの追加メモを含む検証プロセスの追跡 |
6.5.6. DNSSECによるDNSの保護
DNSSEC
DNSSECはDNSの応答にデジタル署名の機能を使って正当性を付与し、改ざんされていないこと、正当な管理者の管理しているレコードであることを保証する仕組みのこと。この仕組みはDNSキャッシュポイズニング攻撃への対策となる。
DNSはもともとルートサーバから始まる名前解決の木構造で、順に権限移譲しながら最終的な名前解決に辿り着くという仕組みとなる。 この際、自己の署名に対する公開鍵を上位DNSサーバへ登録することで、信頼される権威サーバであることを担保し、これによりその応答レコードも信頼される…という信頼の連鎖によって一覧のDNSレコードの信頼性を確保する。
DNSサーバは、ドメイン情報を保持・提供する権威DNSサーバと、権威DNSサーバに問い合わせをするキャッシュDNSサーバに分かれているが、DNSSECを使用するにはそれぞれがDNSSECに対応している必要がある。
DNSSECでは2種類の鍵を用いる
- ゾーンの署名鍵(ZSK:Zone Signing Key)… ゾーンに署名する
- 鍵の署名鍵(KSK: Key Signing Key)… ゾーンに署名した鍵に署名する
それぞれは公開鍵と秘密鍵のペアになっている。
DNSSECのBINDの設定
DNSSECを利用するためにはBINDの場合、設定ファイル/etc/named.conf
のoptions
セクションへ以下の二つの項目を設定する必要がある。
options {
dnssec-enable yes; # DNSSECの有効(yes)/無効(no)を設定する
dnssec-validation auto; # DNSSEC検証の有効/無効を設定する (auto または yes)
: # auto: DNSSEC検証を有効にし、トラストアンカー
: # yes: DNSSEC検証を有効にする。トラストアンカー(trusted-key)を手動で設定する必要がある
: # no : DNSSEC検証を無効にする
:(以下省略)
これらのパラメータは、BINDのバージョンによってデフォルト値が異なる。
BINDのバージョンを確認するには、BINDサーバ上で直接named -v
コマンドを実行するか、クライアントからBINDサーバへ向けて確認するには上述のdig
コマンドを使用できる。
named -v
# DNSSECによるDNS問い合わせ
dig @127.0.0.1 +dnssec [ドメイン]
セキュリティのためにバージョンを隠す場合は設定ファイル/etc/named.conf
のoptions
セクションに以下のように記載する。
options {
version "表示したい文字列";
:(以下省略)
DNSSEC認証サーバのリソースてコードと検証
DNSSECではZSK公開鍵(DNSKEY)に署名を行うKSK(Key-Signing Key)と残りのリソースコード(DNSレコード)に署名を行うZSK(Zone-Signing Key)が利用される。鍵をKSKとZSKに分けることにより鍵強度、更新頻度を役割別に分けられる。
なおKSKの公開鍵はDSレコードとして上位ゾーンに登録される必要がある。
【DNS権威サーバにおけるリソースレコードの署名】
- ZSK秘密鍵で各リソースレコードに署名をする
- KSK秘密鍵でZSK公開鍵の署名をする
- KSK公開鍵のハッシュ値(DSレコード)を生成し、上位ゾーンへ登録する
【DNSキャッシュサーバにおけるリソースレコードの検証】
- 上位のDNS権威サーバから取得したDSレコードとKSK公開鍵を比較して検証
- KSK公開鍵を用いてKSK秘密鍵で署名されたZSK公開鍵を検証
- ZSK公開鍵を用いてZSK秘密鍵で署名された各リソースレコードを検証
DNSのリソースレコード
DNSはIPアドレスとドメイン名とを紐づけるためのデータベースをリソースレコードと呼ばれる形で保持する。 DNSSECで使用されるリソースレコードは以下の通り。
リソースレコード | 説明 |
---|---|
DS | KSK公開鍵のハッシュ値を含む情報 上位ゾーンに登録すると信頼の連鎖を構築する |
DNSKEY | 公開鍵の情報 キャッシュDNSサーバが署名を検証するために公開鍵を使用する |
RRSIG | 各リソースレコードへのデジタル署名 キャッシュDNSサーバが権威DNSサーバからの応答に対する正当性を検証するために使用 |
NSEC | 存在しないサーバへ問い合わせがあった際に不在証明のため辞書順で並べた際に次の位置するゾーン情報を示す |
NSEC3 | NSECを改良したもの。直接のゾーン名ではなくハッシュ化されたゾーン名を示す |
NSEC3PARAM | 権威DNSサーバがNSEC3を生成する際に必要な情報 |
TLSA | DANEにおいて用いられるレコード(ドメイン名にX.509証明書情報の紐づけ) |
TLSAレコードを除き、基本的には署名を行うと署名や公開鍵を含んだレコード(ゾーンファイル)が作成される。 DNSKEYリソースレコードには上述の通りKSK・ZSKの公開鍵が含まれ、これらは各リソースレコードの検証に使用される。
BINDのDNSSEC関連ユーティリティ
DNSサーバソフトウェアであるBINDには、サーバやKSK、ZSKの生成・管理などを行うための以下のようなコマンドユーティリティがある。
コマンド | 機能 |
---|---|
dnssec-keygen | DNSSECのZSK/KSKを生成する |
dnssec-signzone | ゾーンファイルへの署名を行う(NSEC, NSEC3, RRSIG, DNSKEYなどの生成) |
dnssec-settime | 鍵ファイルのメタデータである時間の表示/変更 |
dnssec-dsfromkey | 鍵ファイルから上位サーバに登録するDSレコード生成する |
openssl | TLSAレコードの検証を行う |
rndc | BIND 9.0以降の制御設定ツール |
delv | BIND 9.10以降の検証/解析ツール |
6.5.7. DNSSECの設定
dnssec-keygenコマンド
dnssec-keygenはDNSSECのキーを生成することができるコマンド。 具体的にはZSKとKSKの作成が行える。
dnssec-keygen -a RSASHA256 -b 512 -n ZONE -f KSK myzone.
オプション | 説明 |
---|---|
-a | アルゴリズムの指定 |
-b | キーサイズ |
-n | nametype |
-f | 指定されたフラグをKEY/DNSKEYレコードのフラグフィールドに設定する |
dnssec には、ゾーンに署名するための ZSK キーのペアも必要となる。
# KSKの作成
dnssec-keygen -f KSK -r /dev/urandom -a RSASHA256 -b 2048 -K /var/named/keys -n zone test.local
# ZSKの作成
dnssec-keygen -r /dev/urandom -a RSASHA256 -b 1024 -K /va/named/keys -n zone test.local
dnssec-signzoneコマンド
dnssec-signzone はゾーンに署名しゾーンの署名付きバージョンを生成するコマンド。
ZSK、KSKを用いてゾーンファイルに署名を行うのに使用する。
dnssec-signzone -o myzone. -S db.myzoneFetching ZSK 63075/RSASHA256 from key repository.
ファイル内部は以下のようになる。
; File written on Mon Apr 9 01:45:42 2018
; dnssec_signzone version 9.10.3-P4-Ubuntu
myzone. 604800 IN SOA myzone. root.myzone. (
51 ; serial
604800 ; refresh (1 week)
86400 ; retry (1 day)
2419200 ; expire (4 weeks)
604800 ; minimum (1 week)
)
604800 RRSIG SOA 8 1 604800 (
20180509074542 20180409074542 63075 myzone.
eHu3B0s9AcclEMfkaXK+zUcqnhYTRXO2BBoR
s4z9DGxbwcTXoy8MbIACkuVOhkM6+tQ8r7pr
clIKoUALm4I4mQ== )
オプション | 説明 |
---|---|
-3 [ソルト値] | NSEC3生成のためのソルト(16進数)を指定 |
-a | 署名の整合性を確認 |
-e [日時] | 署名の有効期限の設定、(指定しない場合は30日) |
-f [ゾーンファイル] | 生成される署名済みゾーンファイルを指定 |
-o [ゾーン名] | ゾーン名を指定 |
-x | DNSKEYに対しKSKのみで署名 |
-K [ディレクトリ] | ZSK,KSKの格納場所を指定 |
-S | スマート署名の利用 |
# ゾーンファイルの署名
dnssec-signzone -a -S -x -3 1234 -K /var/named/keys -o test.local /va/named/test.local.db
dnssec-dsfromkeyコマンド
特定の KSK の DSレコード を生成するために使用されるコマンド。
dnssec-dsformkey [オプション] <キーファイル>
オプション | 説明 |
---|---|
-1 | ハッシュ地生成アルゴリズムにSHA-1を使用 |
-2 | ハッシュ値生成アルゴリズムにSHA-256を使用 |
-a [アルゴリズム] | ハッシュ値を生成するアルゴリズムを指定 |
# DSレコードの作成
dnssec-dsformkey Ktest.local.+008+42526.key
dnssec-settimeコマンド
指定されたキーの有効期間を管理するコマンド。
dnssec-settime [オプション] <キーファイル>
オプション | 説明 |
---|---|
-p [確認対象] | C/P/A/R/I/D/allのいずれかを指定し、設定内容の表示 |
-A [日時] | 鍵が有効となる日時の指定 |
-D [日時] | 署名をゾーンから削除する日時の指定 |
-I [日時] | 再署名する前提なしで鍵を取り消す日時の指定 |
-P [日時] | 鍵の公開日時の指定 |
-R [日時] | 再署名する前提で鍵を取り消す日時の指定 |
# ZSKの公開日時と有効化する日時の変更
dnssec-settime -P 20241001000000 -A 20241001000000
6.5.8. DANE
DANEはDNSSECの技術を応用した認証の仕組みのこと。 DNSSECの導入により、DNSサーバの応答の正当性が検証できるようになった。
具体的には認証局が発行する証明書認証の代わりにDNSを利用して通信相手の認証を行える仕組み。 DNSSECが持つトラストチェーンを用いて証明書の信頼性を担保する。
DANEで用いられるリソースレコードをTLSAレコードと呼ぶ。
TLSAレコード
TLSAレコードはTLS サーバー証明書または公開キーを、レコードが見つかったドメイン名に関連付けるために使用される。 TLSAにはTLS証明書、証明書の種類、ハッシュアルゴリズムなどの認証情報が保存される。
# TLSAリソースレコードの例
_443._tcp.www.example.com. IN TLSA {
1 1 2 92000ba5188dc892890d72687e282980e
1b2572ec2829d279820a2829db2928c45
8c9827f682766dfe2528ac67cbc1718bc
}
6.5.9 TSIG
TSIGはDNSサーバとクライアント、DNSサーバ間でDNS情報を通信する際に使われる仕組み。 メッセージ認証と呼ばれる認証方式を利用する。この方式は共有する秘密鍵とDNSメッセージを元にハッシュ関数から生成したMACを比較することにより、サーバ間の認証と通信内容の完全性を保証する。
Dynamic DNS(DDNS)やDNSスレーブサーバのDNS情報の更新の手段として用いられる。
# ============================================
## マスターサーバ/スレーブサーバ間のゾーン転送にTSIGを設定する例(BIND)
# ============================================
# 共有鍵の作成
dnssec-keygen -a hmac-sha256 -b 128 -K /va/named/keys -n HOST test.local.key
# 使用する共有鍵の確認
cat Ktest.local.key.+163+43780.private
# マスターサーバ/スレーブサーバにおけるnamed.confの設定
vim /etc/named.conf
:
key "test.local.key" {
alogorithm hmac-sha256;
secret "i8Tsy16TsDmNWhnKs3hfQ==";
};
:
# スレーブサーバにおけるnamed.confの設定
vim /etc/named.conf
:
server 192.168.1.1 {
keys "test.local.key";
};
:
# ゾーン転送要求の確認
dig @192.168.1.1 -y hmac-sha256:test.local.key:i8Tsy16TsDmNWhnKs3hfQ== test.local axfr