nginx で TLS 1.3 の Cipher Suites を設定するメモ
この記事の概要
nginx 1.17.5 で確認した話を書いています。今後の進展がある可能性があります。
ssl_ciphers では TLS 1.3 の ciphers を設定できない経緯
nginx の ssl_ciphers では TLS 1.3 の ciphers を設定できません。現時点では、TLS 1.3 の ciphers を設定する方法がnginx標準機能としてはありません。
経緯としては下記を見かけました。
#1529 の ざっくりとした概要としては、
- OpenSSL 1.1.1 pre4以降でTLS 1.3-Only Cipher を設定するための新しいAPI(https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html )が追加されている。このAPIを利用して TLS 1.3-Only Cipher を設定する計画はあるかどうか。(例 : apache の 新オプションのSSLCipherSuiteV1_3)
- このあたりまだ議論の余地があるところのようで、OpenSSLとしてのアプローチが明確になるまでは、nginx としてはサポートしないようです。
- nginx を介さずに、TLS 1.3 の ciphers を設定したい場合は、OpenSSLの設定変更をして対応するというアプローチがある。
nginx + openssl で TLS 1.3 の Ciphers を設定してみる
nginx 1.17.5 ( built with OpenSSL 1.1.1 ) で、OpenSSLが動的リンクのnginxにて確認しました。
ciphers や ciphers order を確認するツールとしては、ssltest.sh が TLS 1.3 に対応していたため、こちらを利用しました。
1 . ssl_protocols に TLS 1.3 を追加する ( デフォルトの cipher 利用 )
ツールを使って nginx 接続の cipher order を取得すると下記になります。
TLSv1.3 の デフォルトの ciphers order は、
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_GCM_SHA256
の順番でした。(
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1/include/openssl/ssl.h#L174-L182
)
2. openssl.cnf にて Ciphersuites を定義する
Ubuntu 18.04 の場合は /etc/ssl/openssl.cnf でした。
[ new_oids ] の直前に下記を追加し、nginx を restart し、反映します。
ツールを使って nginx 接続の cipher order を取得すると下記になります。
TLSv1.3 の ciphers order を、
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
の順番に変更することができました。
蛇足
のように ssl_ciphers に TLS 1.3 の cipher suites を記入しても、nginx のconfig test(-t)はクリアしますが、設定として有効とはなりません。(これにより、わたしははじめこの件に気づけていませんでした。)
追記 ( 2020年7月7日 )
2020年7月7日に公開された IPAのTLS設定ガイドラインの参考資料「TLS暗号設定 暗号スイートの設定例」にて、現行のnginxバージョン(資料内では1.16.1と1.17.6)では、TLS1.3 の cipher suites が設定できない為、openssl.cnf で設定と記述されていることを確認しました。
bustedで、Luaのユニットテストを試してみる
この記事の概要
busted を使ったユニットテストを試したメモです。
まだ、使いこなせていないのですが、
簡易に実行する程度までには至ったため一旦書き留めておきます。
busted とは
Olivine-Labsによって公開されているLuaのユニットテストツールです。
MITライセンスです。
ドキュメント:
ソース:
実行環境のつくりかた
ドキュメントには、
busted works with lua >= 5.1, moonscript, terra, and LuaJIT >= 2.0.0.
と記載されていました。
Lua、LuaJITの実行環境を整えたのちに、
Ubuntu18.04、CentOS7の場合は下記でセットアップできました。
(環境によっては、途中で足りないパッケージがあり、コンパイル失敗したので、適宜インストールしました。)
簡易なユニットテストを用意する
今回は、テスト対象の関数のあるファイルと、別にテストシナリオだけを書いたファイルを分けてみました。
テストを実行してみる
sumタグを実行
⇒ 2シナリオとも sucess になりました。
matchタグ実行
⇒ どのブロックのどのシナリオで失敗しているか確認できます。
全件実行
⇒ 同上。
簡単な使い方のメモでした。
判定方法やエラー出力など柔軟にできるようですので、
使いこなせるようになった際には、別途紹介したいと思います。
nginx + lua-nginx-module で Basic認証時だけ 特定のCache-Controlヘッダの値を付与する処理の実装メモ
- この記事の概要
- 実装その1. nginx の ngx_http_auth_basic_module で Basic認証を実装するパターン
- 実装その2. nginx の プロキシ先のアプリケーションで Basic認証を実装するパターン
この記事の概要
下記の2パターンにて Basic認証時だけ 特定のCache-Controlヘッダの値を付与する処理を試しました。
- nginx の ngx_http_auth_basic_module で Basic認証を実装するパターン
- nginx の プロキシ先のアプリケーションで Basic認証を実装するパターン ( = nginx で リクエストヘッダ: Authorization 、レスポンスヘッダ: WWW-Authenticate を含む要求応答をプロキシする )
ユースケースとしては、前段(ブラウザ, CDN, キャッシュサーバ等) で、Basic認証対象のコンテンツだけはキャッシュさせたくないので、特定のCache-Controlの値を付与したいときを想定しています。
Cache-Controlの値によるキャッシュ制御の挙動は、各々(ブラウザ,CDN,キャッシュサーバ等)の仕様を確認してください。
今回は一例として、Basic認証時だけ no-store を付与するという内容で試しています。
実装その1. nginx の ngx_http_auth_basic_module で Basic認証を実装するパターン
このパターンでは nginx 自体で Basic認証対象のURLパス を指定しているため、その配下に ヘッダ付与を記述します。( auth_basic, auth_basic_user_file の記述方法については本題からそれるのでこの記事では省略しています。 )
デフォルトでは、ngx_http_headers_module の add_header では 一部のステータスコードにヘッダを付与することができない仕様です。
Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). Parameter value can contain variables.
なので、Basic認証のレスポンスの一部 : 401 Unauthorized のときには add_header ではヘッダ付与ができません。クライアントとサーバの中間(CDN,プロキシ) の仕様で 401 レスポンスを ネガティブキャッシュする可能性がある場合など、401 にも 明示的にヘッダ付与したいときには add_header の always パラメタを付与する必要があります。
1 - 1. add_header で 実装するパターン ( 401 は対象外 )
付与対象ステータスコードが、200, 204, 206, 301, 302, 303, 304(すべてのバージョン) または 201(1.3.10) または 307 (1.1.16, 1.0.13) または 308 (1.13.0) のみでよく、
401 レスポンスには付与しなくてよい場合に add_header で書くと下記のような記述ができます。
応答としては、下記になります。
1 - 2. add_header で 実装するパターン ( すべてのレスポンスコードが対象 )
If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.
401 レスポンスを含む、すべての ステータスコードに も付与したい場合には、add_header の always パラメタを付与する必要があります。( 2019/09/30 修正 : こちらは元々 lua-nginx-module で記述していましたが、alwaysパラメタで設定可能という内容を知り、修正しました。)
1.7.5 未満のバージョンのnginxで always が使えないが、lua-nginx-module は利用可能な場合は下記でも同様に全てのステータスコードに付与可能になります。
401 の 応答にも 付与ができるようになります。
実装その2. nginx の プロキシ先のアプリケーションで Basic認証を実装するパターン
このパターンでは nginx では Basic認証対象のURLパスを管理していません。要求応答ヘッダ(リクエストヘッダ: Authorization 、レスポンスヘッダ: WWW-Authenticate)の有無で判定して Cache-Control を付与する例です。
応答としては、下記になります。
Basic認証時 の Cache-Controlヘッダ付与についてのメモでした。
Apache Traffic Server の gold_tests をはじめて書いたときに試行錯誤したメモ
- はじめに
- 実行環境のつくりかた
- gold_tests での試行錯誤① Hierarchical Caching 構成にしたい
- gold_tests での試行錯誤② 同一URLへのリクエストに対してのオリジンからのレスポンスを、違うものにしたい
はじめに
Apache Traffic Server ( GitHub - apache/trafficserver: Apache Traffic Server ) の tests/gold_tests 配下にある 各テストを参考に はじめて gold_tests を作成するのを試みた際に、悩んだ点・気づいた点などを、覚えているうちに書き留めておきます。
実行環境のつくりかた
今回、私は、gold_tests 実行環境については hnakamur さんの記事を参考に Dockerにて作成しました。
また、追加の手順として、自分のつくったテストだけ実行したいときには、gold_tests ディレクトリ配下を autest-site と 自分の作成したテストディレクトリのみ にして実行するのがお手軽だったので、そちらの方法でやってました。
gold_tests での試行錯誤① Hierarchical Caching 構成にしたい
gold_tests での試行錯誤② 同一URLへのリクエストに対してのオリジンからのレスポンスを、違うものにしたい
例えば URI "/default" に対して 200 OK , 304 Not Modified の 2パターンを応答させるようにしたい、といったときのアプローチ方法です。
オリジンプロセスの作成 MakeOriginServer にて、lookup_key を指定しないときはデフォルトの lookup_key は PATH のみの挙動となっていました。
-
trafficserver/slice_error.test.py at master · apache/trafficserver · GitHub
-
trafficserver/remap_http.test.py at master · apache/trafficserver · GitHub
などをみていて、HTTPヘッダを lookup_key に使えそうだったので、フック用のダミーのヘッダ X-Update を用意してみました。
⇒ この場合 "GET /default HTTP/1.1" + "X-Update: no" でリクエストするとresponse_header1 が, "GET /default HTTP/1.1" + "X-Update: yes" でリクエストするとresponse_header2かえってくるという挙動をさせることができました。
同一URLに対してオリジンからのレスポンスを変えたいときはこの手の仕込みが必要そうでした。
PowerDNS ALIASレコード / TTL の 挙動確認
はじめに
先日、DNS ANAMEレコード / PowerDNS ALIASレコードについて下記の記事を投稿しました。本記事内で一部は専門用語などで記述していますが、それらの専門用語の説明は下記の記事にて確認していただけます。
本記事においては PowerDNS ALIASレコード の TTLについての挙動確認を記録しています。
ANAMEレコード の TTLについての 仕様確認
Internet Draft にて「Address-specific DNS aliases (ANAME)」として仕様提案されている TTL周りの仕様を、現時点での最新である draft-03 にて確認しました。
【5.3. TTLs】にて記述されている仕様は下記の内容でした。
- Sibling Address Record は、固定TTLを持つ権威サーバから提供される。
- 通常 Sibling Address Record のTTLは、Target Address Record のTTL (Target Address RecordのTTLが ANAMEのTTLより小さい場合は、ANAME の TTL)と同じであると予想される。
- ただし 正確なメカニズムは指定されていないため、 Sibling Address Record のTTLが小さくなる場合がある。
PowerDNS ALIASレコード の TTLについての動作確認
正確な挙動は、実際に試してみないと分からなさそうだったので確認しました。
何パターンか試してみた内容です。
① Sibling Address Record が Aレコード , ANAME's TTL > Sibling's TTL
② Sibling Address Record が Aレコード , ANAME's TTL < Sibling's TTL
③ Sibling Address Record が CNAMEレコード , ANAME's TTL > Sibling's TTL > Target's TTL
④ Sibling Address Record が CNAMEレコード , ANAME's TTL > Sibling's TTL < Target's TTL
PowerDNS ALIASレコード TTL関連の feature request の動向
現時点では未実装ではありますが、機能要望としては、下記の feature request がありました。
この request においては CDN RR の TTL が 1 などの短期間に設定されている場合においても、一定時間キャッシュさせたいなどのケースにおいて利用する、ALIASレコード側のTTLをつかってTTLを上書き(調整)するオプションが要望されていました。
PowerDNS ALIASレコード の TTL を確認してみた 紹介でした。
DNS ANAMEレコード (PowerDNS の ALIASレコード) を試してみる
DNS ANAMEレコード / PowerDNS ALIASレコード 関連記事
- はじめに
- CNAMEレコードの制約、ANAME レコードがなぜ必要なのか?
- ANAME レコード 表示形式 と 専門用語
- ANAMEレコードと、PowerDNS の ALIAS レコード について
- PowerDNS Authoritaive Server の ALIAS レコードを試してみる
はじめに
「Address-specific DNS aliases (ANAME) 」というDNS関連の Internet Draft が、2017年よりIETFに提出されており、つい先日 draft-03 が提出されました
- draft-00 ( 2017-03-24 提出, 2017-11-25 Expire )
- draft-01 ( 2018-01-11 提出, 2018-07-15 Expire )
- draft-02 ( 2018-10-15 提出, 2019-04-22 Expire )
- draft-03 ( 2019-04-15 提出, 2019-10-17 Expire ) ← NEW
普段DNS関連技術は触れていないのですが、諸用により ANAMEレコード関連の情報を確認したり、draft-03 を確認したりなどをしていたため、微々たる情報量ではありますが、得た情報をこちらに書き留めておきます。
PowerDNS では ANAMEレコードの一部の機能を「ALIASレコード」として実装しているため、この機能を試してみた内容と併せて紹介しておきます。
なお、この記事においては、ANAMEレコードについての情報の一部分の紹介になります。すべての情報は書いていませんので、障りとしての参考情報程度にしていただけたらと思います。
CNAMEレコードの制約、ANAME レコードがなぜ必要なのか?
CNAMEレコードの制約
DNSプロバイダの DNS Made Easy が作成されている ANAMEレコードの紹介動画 ( Introducing the ANAME Record - YouTube ) がとても分かりやすかったのでお勧めです。英語が問題ない方はこちらの動画を確認していただくと、4分程度でざっと雰囲気を把握できるかと思います。
DNSではCNAMEレコードを使ってドメイン名の別名を定義することができます。しかし、CNAMEレコードには仕様上の制約があり、下記のことができません。
① Zone Apex(別名: Root Domain / Naked Domain) では CNAMEレコードを 作成することができない
② CNAMEレコードはユニークでなければならない (同一の名前を他のレコードと共有することができない)
<NG その1> CNAMEを複数書いたりはできない
examle.1773.work. IN CNAME sv1.1773.work.
examle.1773.work. IN CNAME sv2.1773.work.
<NG その2> MXなど他のリソースレコードタイプと重複したりもできない
example.1773.work.
IN MX 10 mail.1773.work.
example.1773.work. IN CNAME origin.1773.work.
また、一般的なCNAMEレコードの参照では、DNS lookup を2度実行する必要があるため、参照速度が遅くなります。1度目のlookupでCNAMEレコードを見つけ、2度目のlookupで参照先のIPアドレスを見つけます。
これらの制約を解決するANAMEレコード
ANAMEレコードでは、CNAMEレコードのようにドメイン名の別名を定義できますが、上記のCNAMEレコードの仕様上の制約が取り除かれています。
ANAME レコード 表示形式 と 専門用語
draft-03 より確認した ANAMEレコードの表示形式 および 専門用語を紹介します。
表示形式
ANAMEレコードの表示形式はCNAMEレコードと同様です。
専門用語
Address Record : リソースレコードタイプが A または AAAA の DNSリソースレコード(名前やTTLなどを含むRRset全体)
Address Type : リソースレコードタイプ が A または AAAA のもの
Address Query : 任意の Address Type に対する DNSクエリ
Sibling Address Record : ANAMEと同じowner名のAddress Recordで、ANAMEの置き換えの対象
Target Address Record : ANAMEの最尾の対象 を解決して取得した Address Record
ANAMEレコードと、PowerDNS の ALIAS レコード について
PowerDNS は OSS の DNSサーバです。
Internet Draft 内 の Appendix では PowerDNS での実装について下記のように述べられています。
( Address-specific DNS aliases (ANAME) - draft-03 より抜粋)
PowerDNS Authoritaive Server の ALIAS レコードを試してみる
PowerDNS Authoritative Server ( 以降、PowerDNS と略 ) の 導入およびセットアップについては、公式ドキュメント を参考に実施しました。
PowerDNS での ALIASレコードの制御には pdns.conf に下記 3つのパラメタを記述しました。
- expand-alias=yes : ALIASレコード拡張を有効にする。(v4.1.0以降)
- resolver=(任意のアドレス):53 : ALIAS(と内部スタブリゾルバ)のリゾルバアドレス。(v4.1.0以降) 今回は自分の個人運用しているDNSサーバに向けています。
- outgoing-axfr-expand-alias=yes : AXFRでのALIASレコード拡張を有効にする。(この内容についてはまだ検証できていませんが、一旦投入しています)
DNSレコードの準備
PowerDNSではいくつかのバックエンドの選択があります。私は PostgreSQL を選択しましたので、そちらの形式でレコードを準備します。
今回問い合わせ対象の name を "example.1773.work" とします。
■ ALIAS(ANAME)レコードの準備 (DNS-1 にて準備)
ALIAS(ANAME)に利用するnameはSOA,NSと共用しており、CNAMEでは制限のため利用できないパターンになります。
■ Sibling Address Record の準備 (DNS-2 にて準備)
pdns.conf にてresolverとして指定したDNSサーバにレコードを準備します。こちらはNSDなので、その形式で準備しました。
DNS lookupの実行
この状態で DNS-1 に対して lookup を実行します。結果は下記のようになりました。
# dig example.1773.work
; <<>> DiG 9.11.3-1ubuntu1.5-Ubuntu <<>> example.1773.work
;; global
options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35817
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.1773.work. IN A
;; ANSWER SECTION:
example.1773.work. 358 IN A 10.20.100.10
;; Query time: 190 msec
;; SERVER: (問い合わせ先)#53(問い合わせ先)
;; WHEN: Thu Apr 26 01:32:03 JST 2019
;; MSG SIZE rcvd: 59
ANSWER SECTION にて 解決された Target Address Record が参照できることを確認しました。
DNS ANAMEレコード (PowerDNS ALIASレコード) を試してみた 紹介でした。
TimescaleDB + Grafana で 時系列データを可視化する
TimescaleDB と Grafana
TimescaleDB とは?
- PostgreSQL の EXTENSION の 時系列データベース
- Apache License v2 で公開されているOSS
Grafana とは?
TimescaleDB と Grafana の組み合わせ
Grafana v5.3 で TimescaleDB への対応が機能追加されました。
この機能追加により TimescaleDB に格納した時系列データを Grafana を使って可視化できるようになりました。
こちらの内容を触ってみたので、書き留めておきます。
TimescaleDB、Grafana の セットアップログ
TimescaleDB/Grafanaともに、公式ドキュメントに、ディストリビューション毎のセットアップ手順が記載されていつので、そちらを確認してください。
私は Ubuntu Server 18.04 LTS 上にオールインワンで構築してみました。そのログを置いておきます。
(インストールバージョン)
※ 2018年10月頃にセットアップしたので、現在の最新バージョンより古め(TimescaleDBもv0.xx)です。手順は基本的には一緒だと思うのですが、正しくは公式ドキュメントを参照してください。
① PostgreSQL の インスト―ル
② TimescaleDB の インスト―ル
③ postgresql.conf の設定変更
④ postgresユーザのパスワード設定しておく ユーザ/postgresqlの両方
試用なので、postgresユーザ&パスワードpostgresで接続しています。
⑤ TimescaleDB用 の データベース 作成
⑥ Grafana のインストール
⑦ Grafana のセットアップ
- http://(対象サーバ):3000 にログイン
- http://(対象サーバ):3000/datasources よりデータソースを登録する
(設定例)
(標準)
Name: 任意のデータソース名、Default: お好みで設定、Type: PostgreSQL
(PostgreSQL接続)
Host: サーバ+ポート、Database: 対象のDB名、User: 接続ユーザ、Password: 接続ユーザのパスワード、SSL Mode: 接続時のSSL利用
(PostgreSQL詳細)
Version: PostgreSQLのバージョン、TimescaleDB: チェックする、Min time interval: お好みで設定
TimescaleDB に デモ用のログを投入
Webサーバへのアクセスログを想定したデモ用のログを生成してみます。
(保有カラム)
- time: 日時
- http_host: { first.com, second.com, third.com }
- schema: { http, https }
- http_status: { 1xx, 2xx, 3xx, 4xx, 5xx }
TimescaleDB用のテーブルの作成
データ投入するテーブルを作成します。
HyperTableを作成します。(テーブルが空でないと作成できません)
デモ用ログ投入実行
雑にランダムなデータを作成 して 投入しました。
テーブルに格納されたログを確認
Grafanaで可視化
ダッシュボード の Edit で 登録します。デフォルトのMetricではGUIベースで登録できます。
SQLで記述する場合 Toggle Edit Mode を選択します。
上記は、通常の関数countを使っています。こちらでグラフを描画すると、下記のようになりした。
TimescaleDBの関数を用いて可視化
TimescaleDBには強力な関数が複数存在します。その一部を試してみます。
① 時系列最後尾のデータを取得
② 丸め時間 15分で集計
TimescaleDB と Grafana を組わせて使う紹介でした。