zkat’s diary

技術ブログ

Influxdbでpercentileを計算する

組み込みの関数、percentileがinfluxdbに存在するので簡単に計算することができます。

docs.influxdata.com

適当なデータを積んで、計算してみます。 あるサーバーへのRTTを測定していることを想定し、以下のようなデータを適当に作りました。

insert testdb,server=target1,addr=v4,proto=tcp measured=98.4236389454876
insert testdb,server=target1,addr=v4,proto=tcp measured=49.02986276817023
insert testdb,server=target1,addr=v4,proto=tcp measured=73.68319133987919
insert testdb,server=target1,addr=v4,proto=udp measured=14.515447132468166
insert testdb,server=target1,addr=v4,proto=udp measured=10.153058203214846
insert testdb,server=target1,addr=v4,proto=udp measured=13.858574248282208
insert testdb,server=target1,addr=v6,proto=tcp measured=37.193169776622106
insert testdb,server=target1,addr=v6,proto=tcp measured=75.22886073245671
insert testdb,server=target1,addr=v6,proto=tcp measured=6.350597491749054
insert testdb,server=target1,addr=v6,proto=udp measured=9.58538941785223
insert testdb,server=target1,addr=v6,proto=udp measured=14.100650500638428
insert testdb,server=target1,addr=v6,proto=udp measured=15.64195452574981

20パーセンタイルと50パーセンタイルを計算してみます。

> select percentile(measured, 20) from testdb group by proto
name: testdb
tags: proto=tcp
time                percentile
----                ----------
1577766044022027112 6.350597491749054

name: testdb
tags: proto=udp
time                percentile
----                ----------
1577766044050092539 9.58538941785223


> select percentile(measured, 50) from testdb group by proto
name: testdb
tags: proto=tcp
time                percentile
----                ----------
1577766043809580444 49.02986276817023

name: testdb
tags: proto=udp
time                percentile
----                ----------
1577766043931028528 13.858574248282208

10パーセンタイルで計算して結果をgnuplotで図示してみます。横軸はlogスケールで示しています。

f:id:zkat:20191231133754p:plain
influxdb-percentile

CT(Certificate Transparency)ログサーバーに書き込める証明書

結論

RFC 6962によれば、ルートに信頼の連鎖がある証明書を登録することができるようです。
1. Informal Introduction

In order to avoid logs being spammed into uselessness, it is required that each chain is rooted in a known CA certificate.

3.1. Log Entries

Each submitted certificate MUST be accompanied by all additional certificates required to verify the certificate chain up to an accepted root certificate

ログサーバーへの証明書の書き込みは認証局以外も実施することができますが、以上の制約がある為、 悪意ある人が自己署名証明書を作成して、CTログサーバーに登録しまくるようなことはできません。

概要

適当なCTログサーバー(今回はあえてTesttubeというログサーバーにします)について、どんなルートにチェーンする証明書の登録を 許可しているか確認してみます。

Testtubeについての説明は、以下に記載される通りでテスト目的で運用されているログサーバーとなります。

www.certificate-transparency.org

These logs are intended for testing purposes only and will only log certificates that chain to a test root explicitly added to it.

調査

CTログサーバーが受け付ける、ルートの一覧は、次にアクセスすることで取得することができます: https://<log server>/ct/v1/get-roots
Testtubeであれば、https://ct.googleapis.com/testtube/ct/v1/get-rootsです。 アクセスすると、証明書のPEMデータがJSONで取得できるのでIssuer部分を表示してみます。

239件ありましたが、数件挙げてみます。

Issuer
C=AE,O=TEST UAE Government,CN=TEST UAE Global Root CA G4 E2
C=AE,ST=Dubai,L=Dubai,O=Dubai Government,OU=DESC,CN=Dubai Root CA TEST
C=AT,O=A-Trust Ges. fur Sicherheitssysteme im elektr. Datenverkehr GmbH,OU=A-Trust-Test-nQual-04,CN=A-Trust-Test-nQual-04
C=AT,O=Bundesrechenzentrum GmbH,OU=BRZ CA,CN=Test BRZ CA Root 2017
C=AT,ST=Wien,L=Wien,O=e-commerce monitoring GmbH,OU=GLOBALTRUST Certification Service,CN=ECM TEST 2015
C=AU,ST=ACT,L=Lyneham,O=Verizon,OU=IAM Operations,CN=TEST ROOT CA
C=BE,O=GlobalSign nv-sa,CN=GlobalSign Non-Public Root CA - R3 SIT
C=BE,O=GlobalSign nv-sa,CN=GlobalSign Root E46 - staging
C=BE,O=GlobalSign nv-sa,CN=GlobalSign Root R46 - staging

想定通り、ログサーバーからルート証明書を取得することができました。 なお、上述の通り、Testtube自体はテスト用のログサーバーなので、上記記載のルート証明書も広くクライアントが信頼しているようなものではありません。

TLDのZSKでよく使われている署名アルゴリズム

はじめに

DNSSECで使われる署名鍵はKSK(Key Signing Key)とZSK(Zone Signing Key)の2種類があります。

TLDゾーンのZSKについて、どの署名アルゴリズムがよく使わええているか、調べました。

調べ方

まず、TLDの一覧をIANAから取得します。

https://data.iana.org/TLD/tlds-alpha-by-domain.txt

それぞれのTLDに対して、digでDNSKEYレコードを引きます。

DNSKEYリリースレコードのフラグが、256のものがZSKなので、そのアルゴリズム番号を確認します。

記載の番号が具体的になんのアルゴリズムであるかは、以下に記載のとおりです。

www.iana.org

例えば、よく使われる番号8であればRSASHA256であることを表します。

結果

2019年11月25日時点の結果で以下の通りとなりました。 ZSKは、ロールオバーの都合などを理由にあるゾーンで複数存在し得るので、 件数の総数はTLDの数より多くなっています。

二モニック アルゴリズム番号 ZSKの件数
RSASHA256 8 1568
RSASHA1-NSEC3-SHA1 7 488
RSASHA512 10 35
RSASHA1 5 32
ECDSAP256SHA256 13 8

RSASHA256を使用しているTLDが圧倒的でした。 今後普及してくるかもしれない、アルゴリズム番号13のECDSAを使っているTLDは具体的には以下でした。 全て、ccTLDでした。

アルゴリズム番号13のTLD
BR.
CZ.
LI.
NU.
SK.
UA.

Google Chromeで表示されるCertificate TransparencyのLog IDがKnown Logsに存在するか確認する方法

はじめに

Google Chromeでは、デベロッパーツールにて以下のように、閲覧しているウェブサイトの証明書がどのCTログサーバーに登録されているのか表示することができます。 例えば、google.comにて表示しています。

f:id:zkat:20191123144155j:plain
certificate-transparency-google.com

Google Chromeが自身のCTポリシーに準拠していると判断した対象のCTログサーバーのリスト(Known Logs)は、次の通りjsonにて公開されています。 www.certificate-transparency.org

確認方法

Chromeにて表示したgoogle.comのLog IDに注目すると、以下のようになっています。

Log name Log ID
Google 'Argon2020' log B2 1E 05 CC 8B A2 CD 8A 20 4E 87 66 F9 2B B9 8A 25 20 67 6B DA FA 70 E7 B2 49 53 2D EF 8B 90 5E
Cloudflare 'Nimbus2020' Log 5E A7 73 F9 DF 56 C0 E7 B5 36 48 7D D0 49 E0 32 7A 91 9A 0C 84 A1 12 12 84 18 75 96 81 71 45 58

Known Logsのjsonをみると、log_id部分がbase64にてエンコードされていますので、16進数をbase64に変換しましょう

$ echo -en "\xB2\x1E\x05\xCC\x8B\xA2\xCD\x8A\x20\x4E\x87\x66\xF9\x2B\xB9\x8A\x25\x20\x67\x6B\xDA\xFA\x70\xE7\xB2\x49\x53\x2D\xEF\x8B\x90\x5E" | base64
sh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+LkF4=
$ echo -en "\x5E\xA7\x73\xF9\xDF\x56\xC0\xE7\xB5\x36\x48\x7D\xD0\x49\xE0\x32\x7A\x91\x9A\x0C\x84\xA1\x12\x12\x84\x18\x75\x96\x81\x71\x45\x58" | base64
Xqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1loFxRVg=

以下の通り、Known Logsに記載されていることを確認できました。

{
          "description": "Google 'Argon2020' log",
          "log_id": "sh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+LkF4=",
          "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6Tx2p1yKY4015NyIYvdrk36es0uAc1zA4PQ+TGRY+3ZjUTIYY9Wyu+3q/147JG4vNVKLtDWarZwVqGkg6lAYzA==",
          "url": "https://ct.googleapis.com/logs/argon2020/",
          "mmd": 86400,
          "state": {
            "usable": {
              "timestamp": "2018-06-15T02:30:13Z"
            }
          },
          "temporal_interval": {
            "start_inclusive": "2020-01-01T00:00:00Z",
            "end_exclusive": "2021-01-01T00:00:00Z"
          }
        },
略
        {
          "description": "Cloudflare 'Nimbus2020' Log",
          "log_id": "Xqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1loFxRVg=",
          "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01EAhx4o0zPQrXTcYjgCt4MVFsT0Pwjzb1RwrM0lhWDlxAYPP6/gyMCXNkOn/7KFsjL7rwk78tHMpY8rXn8AYg==",
          "url": "https://ct.cloudflare.com/logs/nimbus2020/",
          "mmd": 86400,
          "state": {
            "usable": {
              "timestamp": "2018-06-15T02:30:13Z"
            }
          },
          "temporal_interval": {
            "start_inclusive": "2020-01-01T00:00:00Z",
            "end_exclusive": "2021-01-01T00:00:00Z"
          }
        },

dnspythonで非再帰問い合わせする

dnspythonのサンプルコードをさらします。 dnspythonで非再帰問い合わせをしつつ、ついでにNSIDも取得してます。

NSIDは、EDNSオプションで使うことのできるもので、実際に応答をした権威DNSサーバー(IP Anycastなどで負荷分散されているDNSサーバーへの問い合わせはどこに吸い込まれたか容易には分からないので)を特定することができます。
但し、NSIDは全ての権威DNSサーバーが対応しているオプションではありません。

以下、MルートサーバーにルートゾーンのSOAを問い合わせるサンプルです。

自分の環境では以下のような結果になりました。

$ ./sample.py
M-NRT-JPNAP-3
a.root-servers.net.
nstld.verisign-grs.com.
2019111100

CAAにissuewildのセミコロンが指定されているときの証明書の発行

はじめに

証明書を発行しようとする認証局は、必ず対象のドメインについてCAAレコードをチェックする必要があります。

Before issuing a certificate, a compliant CA MUST check for publication of a relevant CAA Resource Record set.

tools.ietf.org

ドメインexample.comissuewildプロパティに;が指定されている場合、 *.example.comは発行できないはずですが、example.comの証明書は発行することができるのか気になりましたので調べてみました。

しらべてみた

CAAレコードを設定して証明書を発行してみます。ドメインmtcq.jpを使います。

$ dig +norec +short @ns2.mtcq.jp mtcq.jp CAA
128 issuewild "\;"
$ sudo letsencrypt certonly --standalone -d mtcq.jp

無事発行することができました。

crt.sh

そもそも、ワイルドカードでない証明書を発行するときは、issuewildを無視する必要があること 記載されていました。 セミコロン;が指定されていても一元的に発行できなくなるわけではない(プロパティを正しく解釈する必要がある)ということですね。

issuewild properties MUST be ignored when processing a request for a domain that is not a wildcard domain.

tools.ietf.org

Plotly DashアプリをuWSGI+Nginxで動かす簡単なサンプル

Nginxをリバースプロキシにして、Plotly Dashで作ったサンプルアプリを動かしてみます。
uWSGIとNginxは、Unixドメインソケットでつないでみます。

dash.DashインスタンスからFlaskのアプリをapp.serverとして取り出しています。

以下、コマンドラインからのuWSGIアプリの起動。

$ uwsgi --socket /tmp/unix-domain.sock \
        --mount "/=sample-uwsgi:server" \
        --chmod-socket=777

以下、Nginxの設定抜粋。

location / {
        try_files $uri @wsgiapp;
}

location @wsgiapp {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/unix-domain.sock;
}