pusuke0418’s diary

異常にマルチタスクな社内SEのブログ

OpenSSLで1つのOS上で複数の認証局作って検証したいとき

証明書を使うシステムを検証してるときに少しずつ証明書の設定を変えながら行いたいときがある。1つのOS上でCAを増やしながらOpenSSLでなんとなくこうやるという記録。環境はCentos6.5, openssl-1.0.1e-30.el6_6.5.x86_64。

そしてこの情報もまた参考です。証明書関連のお取扱いは慎重に、ご注意をください。

今回は2つ。まず、認証局ディレクトリを2つ作って、openssl.cnfをそれぞれ配備する。

# mkdir /opt/ca01
# mkdir /opt/ca02
# cp /etc/pki/tls/openssl.cnf /opt/ca01/openssl.cnf
# cp /etc/pki/tls/openssl.cnf /opt/ca02/openssl.cnf

で、それぞれのファイルを編集する。今回下記のあたりのみ。"dir="部分にてディレクトリをそれぞれの場所に合わせ、共通の部分では、policy_matchをoptionalとして、CAと証明書要求で違うと怒られないようにする。最後に、clientAuthの拡張用途を指定している。

/opt/ca01/openssl.cnfの書き換え
(省略)…
[ CA_default ]
dir= /opt/ca01/# CHANGED Where everything is kept
…(省略)

/opt/ca02/openssl.cnfの書き換え
(省略)…
[ CA_default ]
dir= /opt/ca02/# CHANGED Where everything is kept
…(省略)

↓共通の書き換え
(省略)…
# For the CA policy
[ policy_match ]
countryName= optional #CHANGED
stateOrProvinceName= optional #CHANGED
organizationName= optional #CHANGED
…(省略)
↓末尾に追加
#####################added#######################
[ clientAuth ]
extendedKeyUsage = clientAuth
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer

で、openssl.cnfで指定しているディレクトリやファイルをそれぞれ/opt/ca01, ca02ディレクトリの下につらつら作る。両ディレクトリ以下共通の作業

# mkdir certs
# mkdir crl
# mkdir newcerts
# touch index.txt
# echo '01' >> serial
# echo '00' >> crlnumber

そして、CAの準備。利用したコマンドのみで途中の国とかの入力や出力は省略。

# openssl genrsa -aes256 -out /opt/ca01/private/cakey.pem 2048
# openssl req -new -key -x509 -key /opt/ca01/private/cakey.pem -out /opt/ca01/cacert.pem

# openssl genrsa -aes256 -out /opt/ca02/private/cakey.pem 2048
# openssl req -new -key -x509 -key /opt/ca02/private/cakey.pem -out /opt/ca02/cacert.pem

証明書要求を作っておく。newcerts以下に作成していることに特に意味はナシ。コマンドのみで国とかの入力や出力とかは省く。

# openssl genrsa -aes256 -out /opt/ca01/newcerts/01_user.pem 2048
# openssl genrsa -aes256 -out /opt/ca02/newcerts/02_user.pem 2048

そして証明書を発行。コマンドのみ記載
ca01では01_user.csrを、ca02では02_user.csrを作成している。

# openssl ca -config /opt/ca01/openssl.cnf -keyfile /opt/ca01/private/cakey.pem -extensions clientAuth -out /opt/ca01/newcerts/01_user.cer -infiles /opt/ca01/newcerts/01_user.csr
# openssl ca -config /opt/ca02/openssl.cnf -keyfile /opt/ca02/private/cakey.pem -extensions clientAuth -out /opt/ca02/newcerts/02_user.cer -infiles /opt/ca02/newcerts/02_user.csr

OpenSSLのcaオプションのオプションで、"-config"にて使うopenssl.cnfを、"-keyfile"にて発行に利用する秘密鍵を指定している。あとは、拡張用途"-extensions"でclientAuthを呼んでいる。

発行された証明書の中身を確認してみる。CA証明書のSubject Key Identifierと、発行された証明書のAuthority Key Identifierを比較して確認することで、どのCA/認証局から発行されたかがわかる。

それぞれのCA
# openssl x509 -in /opt/ca01/cacert.pem -text
…(省略)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                21:E5:6B:54:47:1A:CB:79:F2:BE:CD:A7:E2:6C:97:23:F8:7B:1C:21
            X509v3 Authority Key Identifier: 
                keyid:21:E5:6B:54:47:1A:CB:79:F2:BE:CD:A7:E2:6C:97:23:F8:7B:1C:21
…(省略)

# openssl x509 -in /opt/ca02/cacert.pem -text
…(省略)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                8E:27:FA:9B:A6:71:11:46:B5:44:FC:71:6C:83:D4:B1:EF:CF:55:BA
            X509v3 Authority Key Identifier: 
                keyid:8E:27:FA:9B:A6:71:11:46:B5:44:FC:71:6C:83:D4:B1:EF:CF:55:BA
…(省略)

それぞれ発行した証明書

# openssl x509 -in /opt/ca01/newcerts/01_user.cer -text
…(省略)
        X509v3 extensions:
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Key Encipherment
            X509v3 Subject Key Identifier: 
                1B:DF:71:BF:39:0E:B4:11:37:BA:71:A6:57:85:96:7F:CB:00:4C:A7
            X509v3 Authority Key Identifier: 
                keyid:21:E5:6B:54:47:1A:CB:79:F2:BE:CD:A7:E2:6C:97:23:F8:7B:1C:21
…(省略)

# openssl x509 -in /opt/ca02/newcerts/02_user.cer -text
…(省略)
        X509v3 extensions:
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Key Encipherment
            X509v3 Subject Key Identifier: 
                62:2E:E3:88:6F:96:05:26:E5:FB:47:BD:E1:F0:45:45:00:22:F8:8C
            X509v3 Authority Key Identifier: 
                keyid:8E:27:FA:9B:A6:71:11:46:B5:44:FC:71:6C:83:D4:B1:EF:CF:55:BA
…(省略)

Linux Network Namespaceで使う/etc以下のファイル

Linux Network Namespaceは、基本的に「ネットワーク」の名前空間。仮想的な。最初は簡単に何でもかんでも独立させられるのかと思って勘違いしていたけど。

ip netns execコマンドでネームスペース上で何かコマンドを実行できる。manコマンドでip netnsを見てみると、"applications that are aware of network namespaces, the convention is to look for global network configuration files first in /etc/netns/NAME/ then in /etc/."とまず記載がある。

ネットワークに関わるものは、どのコマンド or applicationまでなのかは正確にわからなくて調べているけれども、/etc/netns/[name]/以下に設定ファイルを置けば優先して読み込むようだ。ちょっと少しhostsファイルをいじってためしてみる。環境はUbuntu14.04にて、カーネルは3.13.0-45。

まず、ネームスペースの準備。alphaとbetaというものを作る。

$ sudo ip netns add alpha
$ sudo ip netns add beta

作っただけではネットワークインタフェースはダウンしているので、上げておく。因みに作った段階ではループバックしか存在しませんものね。今回は気にしない。

$ sudo ip netns exec alpha ip link set lo up
$ sudo ip netns exec beta ip link set lo up

そして、それぞれのネームスペースが使うetc以下を作成。その下に/etc/hostsをコピーしておく。

$ sudo mkdir -p /etc/netns/alpha
$ sudo mkdir /etc/netns/beta
$ sudo cp /etc/hosts /etc/netns/alpha/
$ sudo cp /etc/hosts /etc/netns/beta/

下記のような形でそれぞれのhostsファイルを編集。それぞれのネームスペースでは自分の名前のみループバックに投げるようにすることが目的。

[/etc/netns/alpha/hosts]
127.0.0.1       localhost
127.0.1.1       alpha

[/etc/netns/beta/hosts]
127.0.0.1       localhost
127.0.1.1       beta

この状態で各々ping打ってみる。ネームスペースalphaではalphaは解決できるが、betaは解決できないことが、ネームスペースbetaではbetaは解決できるが~、と各々のhostsを読んでいることがわかる。

[alpha]
$ sudo ip netns exec alpha ping alpha
PING alpha (127.0.1.1) 56(84) bytes of data.
64 bytes from alpha (127.0.1.1): icmp_seq=1 ttl=64 time=0.041 ms
64 bytes from alpha (127.0.1.1): icmp_seq=2 ttl=64 time=0.037 ms
64 bytes from alpha (127.0.1.1): icmp_seq=3 ttl=64 time=0.035 ms
64 bytes from alpha (127.0.1.1): icmp_seq=4 ttl=64 time=0.039 ms
^C
 --- alpha ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2997ms
rtt min/avg/max/mdev = 0.035/0.038/0.041/0.002 ms
$
$ sudo ip netns exec alpha ping beta
ping: unknown host beta

[beta]
$ sudo ip netns exec beta ping beta
PING beta (127.0.1.1) 56(84) bytes of data.
64 bytes from beta (127.0.1.1): icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from beta (127.0.1.1): icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from beta (127.0.1.1): icmp_seq=3 ttl=64 time=0.037 ms
64 bytes from beta (127.0.1.1): icmp_seq=4 ttl=64 time=0.040 ms
^C
 --- beta ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2997ms
rtt min/avg/max/mdev = 0.036/0.043/0.060/0.010 ms
$ 
$ sudo ip netns exec beta ping alpha
ping: unknown host alpha

Open FlowのReserved Portと設計のなぞ

Open Flowは、コントローラへの通信は、その空っぽのスイッチはどうやってやるんだろうとふと疑問に思った。実は実装を知っているような機器もあるのだけれども、なんとなく単純にOpen FlowのSpecificationをかいつまんで読んでみた。

たとえばv1.3.4を読むと、p.13 にReserved Portなるものがあった。1.3.4を読んでみたのは、実装されているもので新しいものは1.3.xが多いのかなという思い込みと、その系で新しそうだったから。

引用すると

"They specify generic forwarding actions such as sending to the controller, flooding, or forwarding using non-OpenFlow methods, such as “normal” switch processing.A switch is not required to support all reserved"

いわゆる普通のスイッチングのようにOpen Flowではない方法を使うものっぽい。その中に、CONTROLLERという種類のものがある。

"Represents the control channel with the OpenFlow controllers. Can be used as an ingress port or as an output port. When used as an output port, encapsulate the packet in a packet-in message and send it using the OpenFlow switch protocol (see 7.4.1). When used as an ingress port, this identifies a packet originating from the controller."

私にはポエムのようにしか見えないのだけれども、コントローラとの通信に使われるようだ。ingressまたはoutputのポートとして使われるとか、ingressとして使われる場合は、というような部分がよくわからないんだけれども(別にポートが2つ要るとかじゃないよね)。

さしあたって、「ふつうの通信」するポートでコントローラと通信しているのかな。それなら、フロー情報無くてもコントローラと通信できるということは理解できる。

ただし、その場合、Open Flowで形成されるネットワークとは別に、コントローラ接続用のネットワークの系が必要になることになるということか。線新しく引いたりする必要が出てきたりするのかな。その場合、そこも冗長取りたくなるわけで、そうしたら、その部分ではメーカーの実装に依ったりして、冗長プロトコルを動かせるのだろうか。華々しい?Open Flowの実際の全体の設計イメージとして、特に使うこともなさそうな寂しい私ですが、なんとなくもやもやしてます。