生茶にはデカフェ版があるのですが、これ普通の生茶より美味しい気がしているんですよね。
お茶の旨味はしっかりと残っているんだけど、渋みが減っていてすっきり飲みやすい。
夏におすすめの一品です。
店頭で並んでいることがほとんどないので、流行ったらおいてくれるようになるかな???
店頭に並ぶことを期待してブログに書いてみました。
ほぼすべてのコンピューターには、内蔵されている水晶発振器によって時刻を計算しています。
水晶は安定した周波数の電気信号を発振するため、振動子として広く使われています。
パソコンの電源が切れたり、充電が切れたりしても、マザーボードに内蔵されているCMOSバッテリーにより水晶は時刻を計算し続けれます。
この水晶発振器は個体ごとに誤差があるため、異なるコンピューターでは全て同じ周波数で動作はしません。
(月で±15秒とか)
上記の通り、複数台のコンピューターがあると、徐々に時間はずれていき、読み出したときに異なる時刻を示すようになります。
これはclock skewと呼ばれます。
手動で時刻を合わせても発振器の誤差の影響などですぐに時刻がずれてしまうので、手動ではなく自動的にコンピュータの時刻同期ができれば、これらの問題を解決することができます。
これを実現するために用いられるのが時刻を同期させるプロトコルがNTPです。
NTP は、正確な運針をもつ NTP サーバに一致させ、その後時刻を一定の誤差範囲内で維持する仕組みになっています。
つまり、NTP サーバの時刻変更に対して、NTP クライアントの時刻がこれに同期するというものではありません。
NTP プロトコルは、下記 3つで構成されています。
NTPはネットワークを介して時刻同期を行います。
単純に相手のサーバが通知してきた時刻を信頼するだけでは、 ネットワークの遅延により時刻のずれが発生してしまいます。
そのため、NTPではサーバ・クライアント間の通信において、 NTPメッセージを送信した時刻、受信した時刻を、 サーバ・クライアントそれぞれがメッセージの中に含めており、これらを使ってネットワークでの遅延時間を推測し、ずれの少ない時刻同期を図っています。
下記シーケンスを元に考えてみます。
クライアントとサーバーは時刻はずれているとします。
パケットの往復時間(ラウンドトリップ)Δは下記になります。
Δ = (Tc2- Tc1) - (Ts2 - Ts1)
また、時刻差(タイムオフセット) θ はNTPサーバーの時刻と往復時間の半分(パケットの片道は往復の1/2として固定している) と NTPクライアントの時刻の差となります。
θ = (Ts2 + Δ / 2) - Tc2 = Ts2 + ((Tc2- Tc1) - (Ts2 - Ts1)/2) - Tc2 = (Ts2 + Ts1) / 2 - (Tc2 + Tc2) / 2
θ に基づいてNTPクライアントの時刻を調整します。
NTP以外にも時刻同期をする仕組みはあります。
その一つにBerkeleyアルゴリズムを用いるものがあります。
NTPはクライアントが定期的にNTPサーバー(タイムサーバー)に通信して時刻を同期しているのに対して、Berkeleyアルゴリズムではタイムサーバーが全てのマシンに対して定期的にポーリングし、応答に基づいてメッセージの往復時間を計算し、現在の時間を平均化し、ローカルクロックを調整する必要があることをクライアントに通知します。
クロックスキューの問題などで、物理クロックの完全な同期は現実的には難しいです。
しかし、例えばシステム中のイベントのタイムラインにおいて、イベントの相対順序を決めるためには時刻の絶対値は必ずしも必要ありません。
イベントAがイベントBの前に起こることを知る必要がある場合、Ta=2、Tb=6でも、Ta=4、Tb=10であっても、Ta < Tbが満たされていれば問題ありません。
このようなシチュエーションにおいてはインクリメントされるカウンタに基づいてイベントの順序付けを行うほうが安全性が高いです。
物理クロックではなく、インクリメントされるカウンタに基づくものを論理クロックと呼びます。
Lamportの論文( https://www.microsoft.com/en-us/research/uploads/prod/2016/12/Time-Clocks-and-the-Ordering-of-Events-in-a-Distributed-System.pdf ) では、 クロックの同期は必要だが、絶対値的なものである必要はないことを示しました。
2つのプロセスが相互作用しない場合(並行な場合)、クロックを同期させる必要はなく同期していないことは観測できないため、問題にはならない、さらに通常重要なのは、すべてのプロセスが正確な時間に合意することではなく、イベントが発生する 順序 に合意することであると述べています。
論理クロックの同期のために、happens-before
関係を定義しています。
happens-before
関係 →
は 以下の3つの条件を満たしている最小の関係としています。(happens-before
は日本語では事前発生と訳されます。データ指向アプリケーションデザイン p 199参照)
また、a ↛ b かつ b ↛ a で、aとbのイベントが異なるイベントは concurrent(並行) と呼びます。
つまり、a bのどちらも先に行われていない、互いに相手を知らないのであれば、これらは並行していることになります。
全てのイベントに対して、全てのプロセスが合意する時間の値、論理クロックを定義します。
ここでは、論理クロックは下記のように定義します。
Ci<a>
を割り当てる関数であるC<a>
を割り当てる関数 C とする。
C<b> = Cj<b>
となる つまり、C はすべてのプロセスが合意する時間の数値を割り当てるその上で、この論理クロックがイベントの発生する順序に基づいて正しく振る舞うための条件は、 あるイベント aが他のイベント bよりも先に発生した場合、a は b よりも早い時間に発生すべき ということになります。
これは、
イベントaとbにおいて、 a → b であれば C<a> < C<b>
となります。
これは 、前述の happens-beforeの関係を考えると、
プロセスPiのイベントaとbにおいて、aがbの前に発生した場合、 Ci<a> < Ci<b>
プロセスPiのメッセージ 送信 a で プロセスPjでのメッセージの受信 b の場合 Ci<a> < Cj<b>
の2つの条件を満たすことになります。
これらの条件を満たす実装のルールは下記の通りです。
各プロセスPiは連続する2つのイベントの間にCiを増加させる。つまりa → b であれば bのイベントの前にCiを増加させる
2-a. イベントaは プロセスPiで mというメッセージ送信のイベントだとすると、メッセージ m にはタイムスタンプ Tm = Ci <a> が含まれている
2-b. Piとは別のプロセスPjがメッセージ mを受信すると、PjはCjの値を現在の値以上かつ、Tmの値より大きい値をセットする
イベントaがプロセスPiで Ci<a>
に発生すると、システム全体の論理クロック C<a>
= Ci<a>
に割り当てることで分散した環境での論理クロックが構築できます。
www.distributed-systems.net CHAPTER6. COORDINATIONあたり
www.slideshare.net
この論文では、大規模な分散システムでは、まれなパフォーマンスの低下であっても、全リクエストのかなりの部分に影響を与えるとあります。
つまり大規模な分散システムではテールレイテンシの影響が大きくなります。
テールレイテンシは大きなパーセンタイルのレスポンス値のことです。(大きいというのがp99なのかp99.9なのかは文脈次第です)
パーセンタイルの例としては、99 パーセンタイルのレスポンスタイムが 100 msとすると、平均して 100 リクエスト中の 99リクエストには 100 ms未満しかかからず、1 リクエストには 100 ms以上かかることを意味します。
例えば、各サーバが通常10msで応答し、99%のレイテンシーが1秒であるシステムを考えてみると、ユーザーのリクエストがそのようなサーバー1台だけで処理された場合、1/100の確率でユーザーのリクエストが遅く(1秒かかる)なります。
このサーバー群に対して、ユーザーのリクエストが100台のサーバーから並行してレスポンスを収集しなければならない場合、ユーザーのリクエストの63%が1秒以上かかることになります。
1台のサーバレベルで1秒以上の遅延が発生するのが1万件に1件のサービスであっても、そのようなサーバが2,000台あるサービスでは、5件に1件の割合(18%)で1秒以上の遅延が発生することになります。
これはテールレイテンシの増幅と呼ばれます。(データ指向アプリケーションデザインp 17のコラム参照)
Googleような大規模な分散システムではテールレイテンシが全体のパフォーマンスに大きく影響します。
マシンの共有リソースの競合( CPUとか )、バックグランド処理などいろいろな要因で高いテールレイテンシが発生します。
大規模システムにおいて、レイテンシの変動の要因をすべて排除することは現実的ではないですが、この論文では、突発的、一時的な遅延を隠蔽したり、回避するすることでテールレイテンシを改善する手法を紹介しています。
多くのWebサービスでは、データアイテムの複数のレプリカを配置することで、スループットを向上させ、障害が発生しても可用性を維持しています。
この対応では、レプリカを使って、1つの高レベルのリクエスト内のレイテンシーの変動を抑えます。
遅延のばらつきを抑える簡単な方法は、 同じ リクエストを複数のレプリカに発行し、いずれかのレプリカが先に応答した結果を使用することです。
クライアントは、最初の結果を受け取ると、残りの未処理のリクエストをキャンセルします。
このようなリクエストは Hedged requests
と呼ばれています。
(この Hedged
は金融用語の意味での両掛けから引用していると思っています)
この技術をnaiveに実装すると、通常は許容できないほどの負荷が追加されますが、負荷の増加をわずかに抑えながら、ほとんどの遅延削減効果を得られる多くのバリエーションが存在します。
アプローチの1つに、最初のリクエストが、このクラスのリクエストに対する95パーセンタイルの予想待ち時間を超えて未処理になるまで、2番目のリクエストの送信を遅らせるというものがあります。
この方法では、追加の負荷を約5%に抑えつつ、レイテンシーテールを大幅に短縮することができます。
この技術が有効なのは、レイテンシーの原因が特定のリクエストに固有のものではなく、他のなんらかの形態の干渉によるものであることが多いためです。
論文内では、100台の異なるサーバに分散しているBigTableのテーブルに格納された 1000個のキーの値を読み取るGoogleベンチマークが紹介されていました。
10msの遅延後にヘッジ付きリクエストを送信すると、わずか2%のリクエスト数の増加で、1000個の値をすべて取得する際の 99.9%タイルの遅延が 1,800ms から 74msに短縮されたとありました。
Hedged requestsのオーバーヘッドは,プライマリリクエストよりも優先度の低いリクエストとしてタグ付けすることで,さらに低減することができます。
Hedged requests
には、複数のサーバが同じリクエストを不必要に実行してしまうという脆弱な側面があります。
この余分な作業はは上記で紹介したような方法で緩和はできますが、この方法ではメリットが得られるのはごく一部のリクエストに限られてしまいます。
適切なリソースの消費で Hedged requests
のより積極的な利用を可能にするには、リクエストをより速くキャンセルする必要があります。
一般的なレイテンシの変動要因は、リクエストが実行を開始する前のサーバでのキューイングの遅延です。
多くのサービスでは、リクエストが実際にスケジューリングされ、実行がはじまれば、その実行の完了時間のばらつきは大幅に減少します。
そこでGoogleでは、同時に複数のサーバにリクエストのコピーをエンキューし、サーバがこれらのコピーのステータスに関する更新情報を相互に通信できるようにしました。
サーバがサーバ間でステータスの更新を行うリクエストのことは Tied request
と呼ばれています。
Tied request
の最も単純な形式は、クライアントが2つの異なるサーバーにリクエストを送信し、それぞれのサーバーにもう一方のサーバーがタグ付けされます(結びつけられた tied)。
あるリクエストが実行を開始すると、そのリクエストは相手にキャンセルメッセージを送ります。 キャンセルメッセージに対応するリクエストは、もう一方のサーバーにまだキューが残っているときは、直ちに中止するか、大幅に優先順位を下げます。
Googleはこの手法をクラスタレベルの分散ファイルシステムに実装しており、中央値と末尾値の両方の遅延を減らすのに効果的であることを紹介しています。
その中では、サーバー間のキャンセルを行う Tied request
は、レイテンシーの中央値(50パーセンタイル)を16%削減し、レイテンシー分布の末尾に向かうにしたがって効果が増していき、99.9パーセンタイルのレイテンシーで40%近い削減を達成したとありました。
多くのシステムでは、各パーティションのコストが等しくなるようにデータを分割しようとしますが、各マシンに単一のパーティションを静的に割り当てることは、下記から実際には十分ではありません。
不均衡に対処するために、Googleのシステムの多くは、サービス内のマシンの数よりも 多く のパーティションを生成し、これらのパーティションを特定のマシンに動的に割り当ててロードバランシングを行います。
ロードバランシングする側は、これらの小さなパーティションの1つをあるマシンから別のマシンに移すことに対しての責務があります。
マイクロパーティション方式の拡張機能として、負荷の不均衡を引き起こす可能性の高い特定のアイテムを検出、あるいは予測し、そのアイテムのレプリカを追加作成することができるようにします。
追加のレプリカを使用して、実際にマイクロパーティションを移動させることなく、これらのホットなマイクロパーティションの負荷を複数のマシンに分散させることができます。
中間サーバは、システム内の様々なマシンからの応答の遅延分布を観測し、特に遅いマシンを除外したり、検証を行うことでシステムのパフォーマンスが向上できる状況を検出することがあります。
遅延の原因は、無関係なネットワーク・トラフィックによる干渉や、そのマシン上の別のジョブのためのCPU動作の急増など一時的な現象であることが多く、システムの負荷が高いときに速度低下に気が付きやすいです。
システムの負荷が高いときであっても、システムはこれらの除外されたサーバーにシャドーリクエストを発行し続け、そのレイテンシーの統計を取り、問題が解決したときに再びサービスに組み込むことができるようにします。
最良ではないわずかに不完全な("good-enough")結果で応答することで、エンド・ツー・エンドのレイテンシーが向上しユーザにとって最良のサービスとなる可能性があります。
ファンアウトが非常に大きいシステムで起こりうる一つの問題は、あるリクエストがテストされていないコードパスを実行してしまい、何千ものサーバで同時にクラッシュしたり、非常に長い遅延が発生したりすることです。
このような相関性のあるクラッシュシナリオを防ぐために、Googleの検索システムの一部では、カナリアリクエスト
と呼ばれる技術が採用されています。
これは、最初に何千ものリーフサーバにリクエストを送信するのではなく、ルートサーバがまず1つまたは2つのリーフサーバにリクエストを送信するというものです。
残りのサーバーは、ルートが適切な時間内にカナリアから成功した応答を得た場合にのみクエリが発行されるようになります。
カナリアリクエスト
の段階では,1台のサーバが応答するのを待たなければならないため,全体的な遅延はわずかであり,大規模なファンアウトリクエストに対してすべてのサーバが応答するのを待たなければならない場合に比べて,変動ははるかに小さくなります。
カナリアリクエスト
によってレイテンシーがわずかに増加するにもかかわらず、カナリアリクエスト
は安全性が高いため、Googleの大規模ファンアウト検索システムのすべてのリクエストに使用される傾向があります。
パフォーマンスの変動の対応についてはAuroraにも応用されていることが言及されています。
テールレイテンシへの対応を見ていると、これらを担うコンポーネントはサービスメッシュだよなあと思っています。
Hedge requestなどはenvoyでも実装がありそうです。
マイクロパーティションのロードバランシング、カナリアなどもサービスメッシュが担う部分かと思います。
また、サーバーの切り離し、シャドーリクエストなどもサービスメッシュの範疇かなと思います。
https://static.googleusercontent.com/media/research.google.com/ja//pubs/archive/44875.pdf
https://drkp.net/papers/latency-socc14.pdf
https://pdfs.semanticscholar.org/dede/f157ad3b5b4df21a6515b1b70ed8ad698422.pdf
まずは証明書周りについての整理
証明書は電子文書。
証明書の中には、公開鍵やそれに紐づく情報と証明書の発行元のデジタル署名が含まれています。
現在の公開鍵基盤として広く使われているX.509では、証明書の構造は ASN.1 という記法で定義されています。
ASN.1で定義された内容をネットワーク経由で送るには、これをビット列に符号化する必要があり、この符号化ルールの一つがDistinguished Encoding Rules (DER) 。
DERでエンコードされ更にbase64エンコードしたものがPEMとなります。
証明書でよく見かけるのはこのPEM形式です。
opensslは1.1.1以降であればEd25519が使えるようになっているので、これを使ってみます。
今回手元で確認するだけなので、秘密鍵の内容も記載していますが、本来であれば絶対に記載してはいけない内容です。
% openssl version OpenSSL 1.1.1g 21 Apr 2020
% openssl genpkey -algorithm ed25519 -out private.pem % openssl asn1parse -in private.pem 0:d=0 hl=2 l= 46 cons: SEQUENCE 2:d=1 hl=2 l= 1 prim: INTEGER :00 5:d=1 hl=2 l= 5 cons: SEQUENCE 7:d=2 hl=2 l= 3 prim: OBJECT :ED25519 12:d=1 hl=2 l= 34 prim: OCTET STRING [HEX DUMP]:042034E86A39818F82B908DB25D3C64ED4053ED47A7855C2CA9303B9866F193C82BE % openssl pkey -in private.pem -outform DER | od -An -tx1 30 2e 02 01 00 30 05 06 03 2b 65 70 04 22 04 20 34 e8 6a 39 81 8f 82 b9 08 db 25 d3 c6 4e d4 05 3e d4 7a 78 55 c2 ca 93 03 b9 86 6f 19 3c 82 be
秘密鍵を生成後にASN.1フォーマットを確認しています。
さらにバイナリにして確認しています。
id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
なので、hexにすると 01 03 65 70
なんですが、なんか微妙に合わないけど、なんかまあ判別できそうな感じはします。
次に証明書への署名をCAにリクエストするCSRを生成します。
% openssl req -new -out example.csr -key private.pem % openssl asn1parse -in example.csr 0:d=0 hl=3 l= 221 cons: SEQUENCE 3:d=1 hl=3 l= 144 cons: SEQUENCE 6:d=2 hl=2 l= 1 prim: INTEGER :00 9:d=2 hl=2 l= 93 cons: SEQUENCE 11:d=3 hl=2 l= 11 cons: SET 13:d=4 hl=2 l= 9 cons: SEQUENCE 15:d=5 hl=2 l= 3 prim: OBJECT :countryName 20:d=5 hl=2 l= 2 prim: PRINTABLESTRING :JA 24:d=3 hl=2 l= 14 cons: SET 26:d=4 hl=2 l= 12 cons: SEQUENCE 28:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName 33:d=5 hl=2 l= 5 prim: UTF8STRING :Tokyo 40:d=3 hl=2 l= 16 cons: SET 42:d=4 hl=2 l= 14 cons: SEQUENCE 44:d=5 hl=2 l= 3 prim: OBJECT :localityName 49:d=5 hl=2 l= 7 prim: UTF8STRING :Shibuya 58:d=3 hl=2 l= 12 cons: SET 60:d=4 hl=2 l= 10 cons: SEQUENCE 62:d=5 hl=2 l= 3 prim: OBJECT :organizationName 67:d=5 hl=2 l= 3 prim: UTF8STRING :Foo 72:d=3 hl=2 l= 12 cons: SET 74:d=4 hl=2 l= 10 cons: SEQUENCE 76:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName 81:d=5 hl=2 l= 3 prim: UTF8STRING :Bar 86:d=3 hl=2 l= 16 cons: SET 88:d=4 hl=2 l= 14 cons: SEQUENCE 90:d=5 hl=2 l= 3 prim: OBJECT :commonName 95:d=5 hl=2 l= 7 prim: UTF8STRING :footest 104:d=2 hl=2 l= 42 cons: SEQUENCE 106:d=3 hl=2 l= 5 cons: SEQUENCE 108:d=4 hl=2 l= 3 prim: OBJECT :ED25519 113:d=3 hl=2 l= 33 prim: BIT STRING 148:d=2 hl=2 l= 0 cons: cont [ 0 ] 150:d=1 hl=2 l= 5 cons: SEQUENCE 152:d=2 hl=2 l= 3 prim: OBJECT :ED25519 157:d=1 hl=2 l= 65 prim: BIT STRING % openssl req -text -in example.csr Certificate Request: Data: Version: 1 (0x0) Subject: C = JA, ST = Tokyo, L = Shibuya, O = Foo, OU = Bar, CN = footest Subject Public Key Info: Public Key Algorithm: ED25519 ED25519 Public-Key: pub: 4d:85:35:84:30:4b:78:27:e6:57:2b:cc:3c:e2:55: f5:79:52:ec:53:7e:fa:2a:96:6a:bd:f3:39:1b:28: 6c:74 Attributes: a0:00 Signature Algorithm: ED25519 3d:cb:8e:d1:83:11:b4:54:3e:e4:a8:a1:42:70:67:ce:bc:21: eb:e4:82:57:74:24:03:94:51:e1:bc:b9:06:e2:7d:9c:7e:4f: 09:3a:c1:1f:7b:30:3d:01:16:f3:13:e1:78:b1:47:39:4c:7a: a8:95:a0:89:22:b7:0d:b2:58:03 -----BEGIN CERTIFICATE REQUEST----- MIHdMIGQAgEAMF0xCzAJBgNVBAYTAkpBMQ4wDAYDVQQIDAVUb2t5bzEQMA4GA1UE BwwHU2hpYnV5YTEMMAoGA1UECgwDRm9vMQwwCgYDVQQLDANCYXIxEDAOBgNVBAMM B2Zvb3Rlc3QwKjAFBgMrZXADIQBNhTWEMEt4J+ZXK8w84lX1eVLsU376KpZqvfM5 GyhsdKAAMAUGAytlcANBAD3LjtGDEbRUPuSooUJwZ868Ievkgld0JAOUUeG8uQbi fZx+Twk6wR97MD0BFvMT4XixRzlMeqiVoIkitw2yWAM= -----END CERTIFICATE REQUEST-----
CSRには公開鍵が含まれています。(秘密鍵は含まれません。)
CSRを元に証明書を作成します。
下記は自分の秘密鍵で自己署名した自己署名証明書の作成の例です。(自己署名証明書であれば、秘密鍵だけでも作成可能です)
% openssl x509 -req -days 700 -in example.csr -signkey private.pem -out sample.crt % openssl x509 -text -in sample.crt Certificate: Data: Version: 1 (0x0) Serial Number: 6b:c9:75:4e:4a:96:00:a3:b7:cf:c9:81:f1:70:16:4f:ca:b4:e2:5b Signature Algorithm: ED25519 Issuer: C = JA, ST = Tokyo, L = Shibuya, O = Foo, OU = Bar, CN = footest Validity Not Before: Apr 28 07:13:16 2021 GMT Not After : Mar 29 07:13:16 2023 GMT Subject: C = JA, ST = Tokyo, L = Shibuya, O = Foo, OU = Bar, CN = footest Subject Public Key Info: Public Key Algorithm: ED25519 ED25519 Public-Key: pub: 4d:85:35:84:30:4b:78:27:e6:57:2b:cc:3c:e2:55: f5:79:52:ec:53:7e:fa:2a:96:6a:bd:f3:39:1b:28: 6c:74 Signature Algorithm: ED25519 bb:b6:68:cc:76:01:a4:38:7d:6c:4a:00:5e:c5:1f:f3:e8:f1: e8:0c:dc:62:03:bc:90:75:66:f0:d7:38:9a:cb:60:23:be:0a: b1:76:47:45:81:5a:5f:4c:0f:52:41:4a:9f:99:de:c5:1f:47: ac:75:44:3a:f4:8d:24:50:c1:00 -----BEGIN CERTIFICATE----- MIIBdTCCAScCFGvJdU5KlgCjt8/JgfFwFk/KtOJbMAUGAytlcDBdMQswCQYDVQQG EwJKQTEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB1NoaWJ1eWExDDAKBgNVBAoM A0ZvbzEMMAoGA1UECwwDQmFyMRAwDgYDVQQDDAdmb290ZXN0MB4XDTIxMDQyODA3 MTMxNloXDTIzMDMyOTA3MTMxNlowXTELMAkGA1UEBhMCSkExDjAMBgNVBAgMBVRv a3lvMRAwDgYDVQQHDAdTaGlidXlhMQwwCgYDVQQKDANGb28xDDAKBgNVBAsMA0Jh cjEQMA4GA1UEAwwHZm9vdGVzdDAqMAUGAytlcAMhAE2FNYQwS3gn5lcrzDziVfV5 UuxTfvoqlmq98zkbKGx0MAUGAytlcANBALu2aMx2AaQ4fWxKAF7FH/Po8egM3GID vJB1ZvDXOJrLYCO+CrF2R0WBWl9MD1JBSp+Z3sUfR6x1RDr0jSRQwQA= -----END CERTIFICATE-----
自己署名した証明書を検証してみます。
% openssl verify -CAfile sample.crt sample.crt sample.crt: OK
検証とは
基本的に証明書の発行はCA(認証局)が行います。
また、CSRに基づいて証明書の種類に応じた検証(本人確認など)を行います。
確認が終わったら、証明書を作成します。
証明書を作成する際は、証明書にデジタル署名します。
ここでのデジタル署名では、CAの秘密鍵を使って行います。
また、署名に使うハッシュ関数はCSRで指定できないので事前に確認が必要です。
よくある話ですが、自前でCAを作って証明書の発行をやってみます。
opensslにはCAを作るコマンドが同梱されています。
cnfは下記をコピーして使いました。
openssl/openssl.cnf at 4489655c23f1f7f412309e25a5b9fd7acf7db3f2 · openssl/openssl · GitHub
% OPENSSL=/Users/hoge/http_sample/openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl.cnf" ./CA.pl -newca CA certificate filename (or enter to create) Making CA certificate ... ==== /Users/haruyama.makoto/http_sample/openssl/apps/openssl req -config ./openssl.cnf -new -keyout ./demoCA/private/cakey.pem -out ./demoCA/careq.pem Generating a RSA private key .....+....+..+....+...+...+..+...+.............+.....+......+.+..+...+...+.......+..............+.........+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+..+...+....+..+......+....+...........+...+....+...+...+.....+..........+.....+.+..............+......+.+..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.........+.+...+..+.......+......+..+....+.....+....+............+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .....+.+.........+..+....+.....+..........+...........+...................+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+........+....+.....+.........+......+...+...+............+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Writing new private key to './demoCA/private/cakey.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]:JA State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Shibuya Organization Name (eg, company) [Internet Widgits Pty Ltd]:CaSample Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:ca-sample.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: ==> 0 ==== ==== /Users/hoge/http_sample/openssl/apps/openssl ca -config ./openssl.cnf -create_serial -out ./demoCA/cacert.pem -days 1095 -batch -keyfile ./demoCA/private/cakey.pem -selfsign -extensions v3_ca -infiles ./demoCA/careq.pem Using configuration from ./openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:89 Validity Not Before: Apr 30 17:38:14 2021 GMT Not After : Apr 29 17:38:14 2024 GMT Subject: countryName = JA stateOrProvinceName = Tokyo organizationName = CaSample commonName = ca-sample.com X509v3 extensions: X509v3 Subject Key Identifier: 70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2 X509v3 Authority Key Identifier: 70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2 X509v3 Basic Constraints: critical CA:TRUE Certificate is to be certified until Apr 29 17:38:14 2024 GMT (1095 days) Write out database with 1 new entries Data Base Updated ==> 0 ==== CA certificate is in ./demoCA/cacert.pem
CAの秘密鍵が demoCA/private/cakey.pem
に、CAの証明書は demoCA/cacert.pem
にできます。
この証明書は自己署名になります。
% ../openssl/apps/openssl asn1parse -in demoCA/private/cakey.pem 0:d=0 hl=4 l=1308 cons: SEQUENCE 4:d=1 hl=2 l= 78 cons: SEQUENCE 6:d=2 hl=2 l= 9 prim: OBJECT :PBES2 17:d=2 hl=2 l= 65 cons: SEQUENCE 19:d=3 hl=2 l= 41 cons: SEQUENCE 21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2 32:d=4 hl=2 l= 28 cons: SEQUENCE 34:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:F7989A7B8D8C5F94 44:d=5 hl=2 l= 2 prim: INTEGER :0800 48:d=5 hl=2 l= 12 cons: SEQUENCE 50:d=6 hl=2 l= 8 prim: OBJECT :hmacWithSHA256 60:d=6 hl=2 l= 0 prim: NULL 62:d=3 hl=2 l= 20 cons: SEQUENCE 64:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc 74:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:3F41FB1FBA7D297F 84:d=1 hl=4 l=1224 prim: OCTET STRING [HEX DUMP]:2B22E6FBC.... % ../openssl/apps/openssl x509 -text -noout -in demoCA/cacert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:89 Signature Algorithm: sha256WithRSAEncryption Issuer: C = JA, ST = Tokyo, O = CaSample, CN = ca-sample.com Validity Not Before: Apr 30 17:38:14 2021 GMT Not After : Apr 29 17:38:14 2024 GMT Subject: C = JA, ST = Tokyo, O = CaSample, CN = ca-sample.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:9d:28:b4:02:86:ad:d0:0f:79:6b:2a:81:a3:3b: fe:c9:97:80:fc:e1:e3:f7:8a:70:29:7b:55:99:e9: e7:6e:a5:d8:45:4c:10:3c:71:90:b4:12:2e:0f:0d: 45:09:43:5a:09:3e:b8:73:32:43:52:64:2a:60:81: 46:0f:2b:ba:8c:d4:b3:1d:24:7a:f6:fa:9b:13:a6: ce:f8:8e:45:54:64:39:48:43:18:c1:dd:ab:40:6e: 34:ab:39:1c:34:da:ae:06:82:5b:43:fc:7c:3d:99: 25:d7:96:11:94:3e:fa:52:42:7b:4c:eb:66:1a:c4: ca:e8:d1:76:85:e5:94:0d:e8:e5:3e:84:17:9c:c8: f3:96:91:1c:b1:38:e5:e6:d8:51:16:5f:ed:2c:38: 58:e9:d8:77:69:a8:ab:28:88:bc:c1:d7:36:8a:b5: 66:c5:1f:3f:93:94:48:de:a2:b0:90:e7:69:23:84: 66:e3:77:0b:ca:de:57:88:5c:b0:37:63:af:ee:51: 33:3e:ac:96:26:1c:58:2a:b7:91:35:85:34:cb:97: 6f:f4:6e:15:04:e7:36:03:8a:e8:86:c5:ae:cd:ea: 07:aa:48:c6:c5:2b:d6:6c:20:79:bf:5d:3d:b0:d6: 21:79:47:c6:6d:e6:89:c2:ec:20:72:46:13:52:11: ae:bd Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2 X509v3 Authority Key Identifier: 70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2 X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption Signature Value: 7d:85:dd:92:00:7a:28:f5:d2:68:2f:b2:ad:67:4b:89:af:b8: e4:a1:c8:bb:9c:2b:f2:d5:0d:4f:d8:b0:41:4e:f0:9b:f4:12: 76:3e:94:5c:ee:ff:97:eb:74:3c:c4:84:ba:bb:30:e4:94:a1: ed:ea:6e:45:cf:32:0b:ab:86:09:ae:44:3d:80:9d:e4:a7:60: 87:fa:4a:d2:59:ca:d5:9a:60:9e:2c:37:7f:3d:b2:b3:e5:b2: ec:74:a2:7f:f5:7b:0f:c3:10:d5:19:c5:07:8e:3f:6c:ea:60: 8b:b1:a1:55:3d:f0:58:46:0a:46:48:f3:92:7b:55:82:14:2c: ea:1d:7d:de:34:5a:df:2d:a6:b6:f4:5d:9c:d6:7b:16:fe:c7: 3b:31:f0:d9:b7:6a:59:eb:39:d5:4e:e6:02:b5:52:bd:7c:7d: b5:37:de:81:17:5b:8b:23:c7:a9:6f:fe:13:d6:a2:03:cb:33: f6:50:d5:65:a1:6e:51:8a:71:e4:16:9c:e4:d7:0c:9b:e5:93: c7:84:68:ba:48:84:38:d4:12:64:5d:1f:ca:00:37:96:5d:a3: 58:e4:f8:7f:79:dc:39:36:80:9e:76:e7:59:13:2a:85:c5:6d: b6:6f:f1:da:e0:e7:3c:d7:02:42:0f:e6:f9:9b:12:1a:50:00: 64:ff:4b:98
CA.plとopenssl.cnfを中間CA用に書き換えたものを用意します。
% diff openssl.cnf openssl_intermidiate.cnf 76c76 < dir = ./demoCA # Where everything is kept --- > dir = ./intermidiateCA # Where everything is kept % diff CA.pl CA_intermidiate.pl 33c33 < my $CATOP = "./demoCA"; --- > my $CATOP = "./intermidiateCA";
ルートCAに署名をリクエストします。
% OPENSSL=../openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl_intermidiate.cnf" ./CA_intermidiate.pl -newreq Use of uninitialized value $1 in concatenation (.) or string at ./CA_intermidiate.pl line 145. ==== ../openssl/apps/openssl req -config ./openssl_intermidiate.cnf -new -keyout newkey.pem -out newreq.pem -days 365 Ignoring -days without -x509; not generating a certificate Generating a RSA private key ......+.......+......+..+.......+..+...+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+.....+...+...+...................+...........+...+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+.....+...............+.+...........+...+.......+..+.......+...+..+....+..+.......+...+.....+....+........+..........+.....+.......+......+..+.+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ....+.........+...+.....+............+.+..+....+.........+.........+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+.+...........+.+...+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Writing new private key to 'newkey.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]:JA State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Shibuya Organization Name (eg, company) [Internet Widgits Pty Ltd]:IntermidiateCaSample Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:intermidiate.ca-sample.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: ==> 0 ==== Request is in newreq.pem, private key is in newkey.pem % openssl req -text -in newreq.pem Certificate Request: Data: Version: 1 (0x0) Subject: C = JA, ST = Tokyo, L = Shibuya, O = IntermidiateCaSample, CN = intermidiate.ca-sample.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:af:f7:18:b6:83:b2:55:97:49:a3:89:f0:38:74: a0:4c:23:9f:8b:5c:14:33:30:ca:9b:12:d0:6f:e8: 3d:27:42:0a:72:2a:4d:29:00:4b:55:2d:3d:fc:3f: aa:ad:8b:ce:90:02:f9:d4:e8:90:9b:bc:8d:6f:d0: cc:e1:77:42:ce:79:a5:55:db:ad:56:e3:86:bb:ce: 4d:c1:39:cd:b6:8b:74:86:e3:14:0d:fb:3a:69:21: 22:17:cb:c1:47:15:f8:fb:67:70:50:7e:48:95:71: 50:b9:3b:dc:70:b9:a1:d5:c6:b1:93:b4:32:24:5b: cf:46:e8:0b:09:7f:8d:3d:55:75:d8:9a:0c:9b:b9: 9c:be:74:9e:71:a7:d4:73:e0:0d:26:00:f1:69:fe: c3:d0:17:81:b4:a2:e8:82:46:8c:5e:66:90:92:70: ff:6d:c9:b0:a8:d1:21:dd:59:a3:e3:ad:64:5b:b4: b3:3f:fb:3f:f6:3e:f5:b2:8c:36:0b:e4:44:63:d1: 28:45:69:8e:79:98:56:d5:75:27:70:d2:db:e7:fe: 67:fb:d4:ff:96:cb:fe:98:60:db:67:2e:b9:37:74: 53:c2:f9:b7:6f:0e:a1:bd:93:ba:30:bb:0b:61:7d: da:85:a9:ed:4a:49:f2:67:93:65:c3:02:91:68:a4: b8:21 Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: sha256WithRSAEncryption 37:d6:ab:3f:14:fe:21:4a:d3:41:07:a3:81:43:7a:d2:37:83: be:c6:72:b5:65:31:34:a7:1c:be:b5:7b:27:33:d7:5e:60:1b: 6b:8e:22:20:b8:77:12:c9:8e:f8:fe:80:91:d0:68:97:84:04: a5:32:97:e8:9c:e9:ef:14:48:94:a4:ae:11:94:72:0f:61:5a: 97:16:56:87:73:f2:ba:62:24:3f:62:b0:7c:fd:89:80:eb:50: bb:3c:58:23:b3:2a:31:bc:75:04:87:b7:e3:9f:63:77:53:86: f0:c6:bb:ba:e0:d2:ba:34:ba:aa:3d:66:a7:94:f4:e9:b7:54: 0b:46:5e:00:67:6a:95:44:b1:e8:39:2c:db:9a:c3:ba:64:df: 30:3f:a4:0b:1b:62:fb:02:50:84:f2:42:91:61:e3:8c:a2:f9: dd:6e:b0:aa:1e:d2:7d:8c:ac:bd:bc:9a:a9:67:30:b1:69:e3: 6e:b6:65:9f:13:48:e2:e7:cb:73:e5:77:87:a4:71:e5:15:cf: 7b:91:dc:0b:db:e8:0c:73:7a:ba:b7:b3:7b:f0:17:ca:88:4c: 52:c8:8f:77:d1:2f:1a:60:5c:11:54:d7:ac:b9:b0:2d:70:db: db:db:9a:85:36:93:3b:93:80:f2:d9:97:28:cc:41:56:d5:0b: d3:db:94:25
できたCSRを元に、root CAが署名して証明書を作成します。
% OPENSSL=../openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl.cnf" ./CA.pl -signCA ==== ../openssl/apps/openssl ca -config ./openssl.cnf -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem Using configuration from ./openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:8a Validity Not Before: Apr 30 18:36:05 2021 GMT Not After : Apr 30 18:36:05 2022 GMT Subject: countryName = JA stateOrProvinceName = Tokyo localityName = Shibuya organizationName = IntermidiateCaSample commonName = intermidiate.ca-sample.com X509v3 extensions: X509v3 Subject Key Identifier: A9:C2:76:74:B1:39:64:63:66:CA:CB:32:7B:36:3D:B1:A5:56:1D:FA X509v3 Authority Key Identifier: 70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2 X509v3 Basic Constraints: critical CA:TRUE Certificate is to be certified until Apr 30 18:36:05 2022 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated ==> 0 ==== Signed CA certificate is in newcert.pem % openssl x509 -text -noout -in newcert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:8a Signature Algorithm: sha256WithRSAEncryption Issuer: C = JA, ST = Tokyo, O = CaSample, CN = ca-sample.com Validity Not Before: Apr 30 18:36:05 2021 GMT Not After : Apr 30 18:36:05 2022 GMT Subject: C = JA, ST = Tokyo, L = Shibuya, O = IntermidiateCaSample, CN = intermidiate.ca-sample.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:af:f7:18:b6:83:b2:55:97:49:a3:89:f0:38:74: a0:4c:23:9f:8b:5c:14:33:30:ca:9b:12:d0:6f:e8: 3d:27:42:0a:72:2a:4d:29:00:4b:55:2d:3d:fc:3f: aa:ad:8b:ce:90:02:f9:d4:e8:90:9b:bc:8d:6f:d0: cc:e1:77:42:ce:79:a5:55:db:ad:56:e3:86:bb:ce: 4d:c1:39:cd:b6:8b:74:86:e3:14:0d:fb:3a:69:21: 22:17:cb:c1:47:15:f8:fb:67:70:50:7e:48:95:71: 50:b9:3b:dc:70:b9:a1:d5:c6:b1:93:b4:32:24:5b: cf:46:e8:0b:09:7f:8d:3d:55:75:d8:9a:0c:9b:b9: 9c:be:74:9e:71:a7:d4:73:e0:0d:26:00:f1:69:fe: c3:d0:17:81:b4:a2:e8:82:46:8c:5e:66:90:92:70: ff:6d:c9:b0:a8:d1:21:dd:59:a3:e3:ad:64:5b:b4: b3:3f:fb:3f:f6:3e:f5:b2:8c:36:0b:e4:44:63:d1: 28:45:69:8e:79:98:56:d5:75:27:70:d2:db:e7:fe: 67:fb:d4:ff:96:cb:fe:98:60:db:67:2e:b9:37:74: 53:c2:f9:b7:6f:0e:a1:bd:93:ba:30:bb:0b:61:7d: da:85:a9:ed:4a:49:f2:67:93:65:c3:02:91:68:a4: b8:21 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: A9:C2:76:74:B1:39:64:63:66:CA:CB:32:7B:36:3D:B1:A5:56:1D:FA X509v3 Authority Key Identifier: keyid:70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2 X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption 25:b4:ef:8e:65:c7:6f:86:0c:91:63:f5:c4:3f:d0:3e:21:01: 92:64:89:5b:71:d3:7d:fa:fd:64:eb:09:db:34:97:b1:6d:38: 92:6f:8a:b4:c5:51:c0:85:c0:71:0d:ec:2b:71:50:77:6d:c0: f4:ca:3a:38:66:93:44:eb:aa:db:fa:07:22:14:5c:48:ab:18: b0:39:67:8a:80:59:b8:44:ac:84:3d:dd:aa:16:74:48:3d:aa: 71:d2:37:fe:38:b6:9f:37:6c:fd:d4:79:ce:3d:0a:ca:31:68: 4f:bb:19:c4:78:f0:32:1b:dd:5e:8f:42:e2:27:06:cb:b1:ff: c7:be:cf:3f:3b:84:d0:cd:c7:ba:e8:85:23:cc:1a:96:49:81: 0d:7b:b6:1d:91:c7:58:b4:7d:2f:2f:f2:88:b0:ed:ad:29:36: 14:43:1c:ee:c8:5c:37:29:df:dd:c4:38:e5:e0:70:5b:89:1b: a1:de:25:57:5e:c2:a6:fb:36:8a:e4:64:83:1e:e1:66:e3:a6: 01:91:ac:08:89:95:e7:6c:4f:de:e1:f2:eb:f5:35:87:b2:42: c7:11:fa:f2:85:7e:30:db:52:71:45:3b:a0:5a:5f:15:6c:b4: 98:81:f5:2c:ee:b5:fa:8a:63:fe:b9:8e:f9:ae:af:18:13:75: 4d:b1:2e:4c
この証明書を元に中間CAを作ります。
% mkdir intermidiateCA % mv new* intermidiateCA % OPENSSL=../openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl_intermidiate.cnf" ./CA_intermidiate.pl -newca Directory ./intermidiateCA exists at ./CA_intermidiate.pl line 157. CA certificate filename (or enter to create) /Users/path/to/intermidiateCA/newcert.pem % tree intermidiateCA intermidiateCA ├── cacert.pem ├── certs ├── crl ├── crlnumber ├── index.txt ├── newcert.pem ├── newcerts ├── newkey.pem ├── newreq.pem └── private └── cakey.pem # CAの作成時にうまく作成されないのでセットアップを自前でする # serialの発行はもっとうまくできそう cp intermidiateCA/newkey.pem intermidiateCA/private/cakey.pem echo 00 > ./intermidiateCA/serial
これで中間CAができました。
では実際に証明書を発行してみます。
% openssl genpkey -algorithm ed25519 -out server_key.pem % openssl req -new -out server_csr.pem -key server_key.pem
CSRの発行までは別でやってみて、署名した証明書を発行します。
% ../openssl/apps/openssl ca -config ./openssl_intermidiate.cnf -policy policy_anything -out server_certificate/server_crt.pem -extensions v3_ca -infiles server_certificate/server_csr.pem Using configuration from ./openssl_intermidiate.cnf Enter pass phrase for ./intermidiateCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: May 3 18:56:55 2021 GMT Not After : May 3 18:56:55 2022 GMT Subject: countryName = JA stateOrProvinceName = Tokyo localityName = Shibuya organizationName = ServerCaSample commonName = server.example.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: 36:B5:66:C2:18:A9:43:92:A3:34:64:84:1C:0F:9A:19:3E:52:6A:85 X509v3 Authority Key Identifier: A9:C2:76:74:B1:39:64:63:66:CA:CB:32:7B:36:3D:B1:A5:56:1D:FA Certificate is to be certified until May 3 18:56:55 2022 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
発行された証明書を検証してみます。
% openssl verify -CAfile demoCA/cacert.pem <(cat ./intermidiateCA/cacert.pem ./server_certificate/server_crt.pem) #でもいいし % cat intermidiateCA/cacert.pem server_certificate/server_crt.pem > crt.pem % openssl verify -CAfile demoCA/cacert.pem crt.pem crt.pem: OK
検証成功しました。
このあたりから読んでいけばよさそう
./Configure darwin64-x86_64-cc shared enable-ec_nistp_64_gcc_128 no-ssl2 no-ssl3 no-comp --openssldir=~/path/to/dir make depend make
makeだけであればバイナリがopensslのapps配下に作られれるので、それを使いました。
gist:2f51fa1bfa33f25d9c667db9d83c2412 · GitHub
OCamlと仮想化の勉強のためMirageOSを触ってみることにしました。
mirage.io 通りにやってみる
brew install opam opam init opam install mirage
git clone https://github.com/mirage/mirage-skeleton.git
% cd tutorial/noop % mirage configure -t unix % make depend % make % ls -l noop lrwxr-xr-x 1 foo 1522739515 18 4 28 01:29 noop -> _build/main.native % ./noop % echo $? 0
% cd tutorial/hello % mirage configure -t unix % make depend % make % ./hello 2021-04-28 01:39:04 +09:00: INF [application] hello 2021-04-28 01:39:05 +09:00: INF [application] hello 2021-04-28 01:39:06 +09:00: INF [application] hello 2021-04-28 01:39:07 +09:00: INF [application] hello %
4回helloがでるのは単純に loopが4回回ったら止まるからですね
https://www.eurosys2020.org/wp-content/uploads/2020/04/slides/159_kuo_slides.pdf
集合は波括弧 {...} を用いて集合の要素を明示的に列挙する。
一般に、条件 P(x) があったとき、それをみたす対象だけを全て集めた集合を、
と表記する。
a ∈ Aは aはAに属している、aはAの要素である。
∧ は論理積、AND
A ∧ Bは、Aであり、しかもBである。
集合 X1,..,Xnは、S1からSnまでの集合の各要素の組を要素する集合であり、これを S1,...,Snの直積集合と呼ぶ。
下記リレーションスキーマが与えられたとき、
リレーションをタプル tiの集合 rとして定義する。
各タプルtiは以下のような写像
かつ
という条件を満たすものとする。
http://www.aoni.waseda.jp/sadayosi/course/past/set05/section1.2.pdf
集合 A から集合 B への写像 f とは,A の任意の要素 a に対して B のある要素 b を対応させる規則のことであり,
で表す。 a に対応する要素 b は f(a) で表す。
A を f の定義域,B を f の値域という。
Aiは属性名(属性)で、Diは各属性のドメイン(定義域)。
A1からAnの属性名の集合が、D1からDnの和集合の写像であるとしている。
根本は アジャイル宣言の背後にある原則 になるかと思います。
顧客満足を最優先し、価値のあるソフトウェアを早く継続的に提供します。
Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
agilemanifesto.org から引用
書籍 継続的デリバリー でもこの部分を引用して本のタイトルをつけたと書いてあります。
さらにClean Agileからも引用してみます。
変更するたびに本番環境にコードをリリースするプラクティス
Clean Agile p88より
なるほど、わかりやすい。
Continuous Delivery Foundation (CDF)の定義も見てみます。
CD is a software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time.
CDは、チームが短いサイクルでソフトウェアを生産し、いつでも確実にソフトウェアをリリースできるようにするソフトウェアエンジニアリングのアプローチです。
コード、ソフトウェアという言葉が多く見受けられるが、データのリリースはどうなのだろうか?という疑問が若干わきます。
自分の中では価値を提供する変更のデリバリーであれば全部含むという認識でいるので、データのリリースも含めて考えます。
(ゲームでいうマスターデータとかの話)
継続的にという言葉の通り連続することが重要なのですが、それぞれの間隔を長くすることは無意味なので、デリバリーする間隔を短くするプラクティスということが暗黙的にあります。
コードの変更から本番環境へのリリースの間隔を短くしていく取り組みとも言えます。
リリースの間隔が短くリリース頻度が多いチームは逆のチームに比べて、平均修復時間が小さいこと、変更失敗率が低いことが調査でわかっています。
下記を参照のこと
www2.slideshare.net
LeanとDevOpsの科学
ここで注目したいのは、加速化を推進してもパフォーマンス改善以外の項目に対してトレードオフが発生しないということです。(LeanとDevOpsの科学 p27あたり)
リリースを頻繁に行うためには、下記の取り組みが必要になってきます。
これらの取り組みの結果、最終的にパフォーマンスがよくなります。
コードの変更、コードのpush、テスト、PR、マージ、deployのstepにおいて、どのような処理を行うのかなどを整理し、自動化をできるように整備します。
継続的にそして、素早くデリバリするために各ステップの自動化は必須です。
自動化としては下記が挙げられると思います。
継続的デリバリー p487 に成熟とのレベルの定義があるのでこれで分析してみましょう
レベル3 : 最適化 プロセスの改善に注力する
レベル2 : 定量的な管理 プロセスが計測可能で制御されている
レベル1 : 一貫している 自動化されたプロセスがアプリケーションのライフサイクルに適用される
レベル0 : 繰り返し可能 プロセスは文書化され、一部は自動化されている
レベル-1 : リグレッションエラー多発 プロセスは繰り返せず管理も貧弱、そして対処療法を行っている
これらを使って分析し、step by stepで対応していくのがよいでしょう。
自分のプロジェクトを分析した結果を残しておきます。
プラクティス | ビルド管理および 継続的インテグレーション |
テスト | データ管理 | 環境およびデプロイメント |
---|---|---|---|---|
レベル2 ビルドメトリクスを収集して可視化し、 それに基づいて作業する。 ビルドを壊れたままにしない |
レベル2くらい 本番環境への変更の取り消しは滅多に発生しない 問題があればすぐに見つかり、すぐに修正される。 非機能要件の定義は甘い 受け入れテストは自動化されていない。 |
レベル2くらい データベースの更新やロールバックはデプロイのたびにテストされる。 データベースのパフォーマンスを管理、最適化する。 |
レベル1くらい? 一部の環境ではデプロイを自動化する。 新しい環境は手軽に作成する。 全ての構成情報を外に出してバージョン管理できてる 全ての環境に対して同じ手順でデプロイする ボタンを押すだけでは完結していない。。 |
今できてないことは、受け入れテストの自動化、デプロイメントの自動化になります。
QAチームで今は手動テストを行っている。
シフトレフトしていきたいが取り組みとしては滞っている。
機能テストをよりリッチにしていくなども考えている。
受け入れテストの自動化ができていないことがデプロイの自動化に踏み込めない原因でもある
本番環境へのデプロイ環境への自動化はできていない。(検証環境はできている)
手順はこんな感じでやっている
自動化できていない原因は下記の通り
反映後の受け入れテストの自動テストが整備されていないため切り戻しが自動でできない。
DB schemaのアプライが同期的に実行できない場合もあるので、ここを順々に実行する方法を探している
だた、基本的には後方互換性を担保して開発しているので問題が起きにくい状態ではある。。
特に操作ログの保持が難しい。(改ざんをどう防ぐかとか)
このような分析をもとに次につなげていく。
大規模サービスにおいて、継続的デリバリをするのであれば、継続的デリバリの中からデータベースの管理は切り離さないとだめだと思う。
データベースのバージョン管理はしつつ、デリバリする際にバージョンが該当のものでなければ止めるという制御を入れる。
ALTERとかカラム追加で時間がダウンタイムが発生する場合、デリバリするタイミングで気がつくとそれはもう手遅れなので前もって気がつくのがいいが、デリバリを止められる仕組みさえあればいい。
と考えてみたが、継続的デリバリ12章に理想が書いてあった。。
受け入れテストまで整備するべきかどうかもあるけど、正直エラーがあったら切り戻すで割り切らないと多分一生できん気がする