監視/モニタリングで抑えておきたい記事

あの記事どこだっけ?を避けるためのメモです.

監視やログ,可観測性の一般的な話からKubernetesでの話までわかりやすく解説しています.

Kubernetes & Observability 入門 – Speaker Deck

外形監視を入門する人におすすめな資料です.

より意味のある監視を目指して、外形監視の有効活用 – Speaker Deck

監視設計に入門する人におすすめな資料です.

Re: ゼロから始める監視設計

*書籍「入門監視」がおすすめです.

新たに技術を学ぶ時に意識していること

技術をキャッチアップするときに意識していることを言語化しておくとよさそうだと思ったので残しておきます.

技術の特徴やメリット・デメリット

どんな領域や場面で使うのか,どんな特徴があるのか理解するように心がけています.

例)アプリケーションのデバッグに使うツールで,関連するデータ自動的にトレースできる.ただし,適用できるプログラミング言語の種類が少ないことが課題にある.

技術の目的

その技術は何を達成するため(目標/目的)に存在するのかを意識しています.また,技術が標準化されるまでの歴史や経緯を知ることも目的を意識するときに役立ちます.

例)アプリケーション開発者がデスクトップアプリケーションのログとサーバサイドのログを一貫して追跡するためにある.

他の関連技術との違い

先にあげたメリットやデメリットと似ていますが,他の関連する技術での実装や実現と比較して何が優れているのか意識しています.

例)既存SaaSであるXは,新しいSaaSに比べスケーラビリィが優れているが,SSOへ対応がなくパスワードレスログインの要件を満たしていない.

用語や概念の定義

新たな単語や概念がある場合は,理解する前に定義を明らかにしておきます.これは,コンテクストによって単語が意味する内容が異なるためです.

例)日本語での「認証」と対応する英単語

NginxでCVE-2021-44228(Apache Log4j 2)を狙った攻撃を簡易的にブロック

Apache Log4j 2に深刻な脆弱性 CVE-2021-44228 が見つかりました.アクセスログから管理するサーバへもこの脆弱性を狙った攻撃を観測しました.

Log4jの深刻な脆弱性CVE-2021-44228についてまとめてみた – piyolog

今回はNginxで簡易的に攻撃をブロックしてみます.本質的にはペイロードを任意のヘッダへ追加された場合の対処にはならないため注意が必要です.

環境:

  • Nginx v1.20.1
  • Ubuntu 20.04.3 LTS (Focal Fossa)

設定例

以下は,設定を追加したNginxのConfigの抜粋です.mapを使い攻撃リクエストのペイロードが含まれるURLとUserAgentをパターンマッチでブロックしています.ブロックにはHTTPのステータスコード 444を使いました.

http {
    map $http_user_agent $block_ua_request {
        default 0;
        "~*\${jndi:" 1;
    }
    map $request_uri $block_request {
        default 0;
        "~*\$%7Bjndi:" 1;
    }

    server {
        if ($block_ua_request = 1) {
            return 444;
        }
        if ($block_request = 1) {
            return 444;
        }
    }
}

実際にcurlでリクエストを発行するとリクエストが拒否されていることがわかります.

$ curl "https://blog.koyama.me/$%7Bjndi:xx"
curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)

余談

Qiitaへ記事を投稿しようと試みたところ,WAFにブロックされました.

参考資料

過去のISUCONで知ったNginxのmapを活用できてよかったです.

2020年に買ってよかったもの3選

2020年も終わるので買ってよかったものを3つ紹介します.

会議用スピーカー・マイク

会議用スピーカー・マイクのJabra SPEAK 510です.オンラインでの授業やミーティングが多く重宝しました.特に集音性能に満足しています.Bluetoothに対応しているのでiPadと接続して使えるのも便利です.

ディスプレイアーム

Amazon Basicのディスプレイアームです.今までディスプレイアームを使ったことが無かったので試しに買ってみました.ディスプレイの位置を上下や前後に移動できるメリットを実感しています.立ちながら作業するときもアームがあると自由にディスプレイが移動でき最高です.

ディスプレイ

Dellの34インチ ウルトラワイドディスプレイ P3421Wです.Twitterでりっちゃさんがオススメしていたツイートで見つけました.割引率が高く欲しい条件(Type-C対応, 30インチ以上)が揃っていたので衝動でポチりました.ディスプレイアームと組み合わせて使っています.

Dell 34インチ曲面USB-Cモニター:P3421W | Dell 日本

予定では1/7の到着でしたが12/23に届きました.とにかく最高で進捗が爆上がりです.


今年はコロナもあり生産性を向上するためにデスク周りを強化しました.来年はM1搭載のMacBook Airを買う予定です.来年も素敵なガジェットに出会える1年でありますように~!!

.devドメインと.appドメインがHTTPSを強制する仕組み

トップレベルドメインの中に.devと.appがある.これらはHTTPS接続を強制するドメインとして知られている.この仕組みが気になっていたので調べてみた.

参考: グーグル、完全HTTPS接続で安全なアプリ用ドメイン「.app」–早期登録を受付開始 – CNET Japan

仕組み

結論: HSTSPreload Listという技術を使っている.

HSTS

HSTS(HTTP Strict Transport Security)はHTTPでアクセスしてきたユーザ(HTTPクライアント)にHTTPSでのアクセスを強制するための技術である.対応しているWebサイトでは,HTTPレスポンスのヘッダに Strict-Transport-Security: xxx が付与されている.Qiitaの場合はstrict-transport-security: max-age=2592000が設定されている.RFC 6797で定義されている.

参考: Strict-Transport-Security – HTTP | MDN

FacebookはHSTS Preloadがレスポンスヘッダに含まれている.
image.png

Preload List

Preload ListはRFC 6797の中で定義されている.サイトの管理者は事前に定義したHSTSポリシーをpre-loaded listとよばれるリストにもたせることができる.このリストは,ブラウザがルート認証局の証明書を持つのと同様に,ブラウザに埋め込まれている.これはBootstrap MITMの脆弱性(後述)からの保護に役立つ.

Preload Listに含まれているドメインは,初回にWebブラウザでHTTPアクセスした場合もHTTPSアクセスを強制される.これにより,初回からHTTPSでの通信を行える.

FacebookはブラウザからHTTPでアクセスすると,ブラウザの内部でHTTPSへリダイレクトが行われる.Status Codeは307 Internal Redirectになる.
image.png

以下は,MozillaのPreload Listの一部である.5/12の段階でファイル全体は95377行ある.

$ curl -s https://hg.mozilla.org/mozilla-central/raw-file/tip/security/manager/ssl/nsSTSPreloadList.inc | head -20
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*****************************************************************************/
/* This is an automatically generated file. If you're not                    */
/* nsSiteSecurityService.cpp, you shouldn't be #including it.                */
/*****************************************************************************/

#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1600956010611000);
%%
0--1.de, 1
0-1.party, 1
0-24.com, 1
0-24.net, 1
000321365.com, 1
0007552.com, 1
000a1.com, 1
000a2.com, 1

例えば,facebook が含まれているドメインの一覧は19件ある.

$ curl -s https://hg.mozilla.org/mozilla-central/raw-file/tip/security/manager/ssl/nsSTSPreloadList.inc | grep facebook
apps.facebook.com, 0
business.facebook.com, 0
code.facebook.com, 0
connect.facebook.net, 1
developers.facebook.com, 0
facebook-atom.appspot.com, 1
facebook.ax, 1
facebook.com, 0
m.facebook.com, 1
mbasic.facebook.com, 0
mtouch.facebook.com, 0
pixel.facebook.com, 0
research.facebook.com, 0
secure.facebook.com, 0
t.facebook.com, 0
tablet.facebook.com, 0
touch.facebook.com, 0
upload.facebook.com, 0
www.facebook.com, 0

ChromiumのPreload Listは5/22の段階で110787行ある.

$ curl -s https://raw.githubusercontent.com/chromium/chromium/master/net/http/transport_security_state_static.json | tail
    { "name": "briellenj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
    { "name": "blainecosheriff-ok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
    { "name": "almaarkansas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
    // END OF ETLD-OWNER REQUESTED ENTRIES

    // To avoid trailing comma changes from showing up in diffs, we place a
    // single entry at the end.
    { "name": "hstspreload.org", "policy": "custom", "include_subdomains": true, "mode": "force-https" }
  ]
}

Facebookを含むドメインは22件ある.よく見るとfacebooktsukaikataという文字列を含むドメインもある.

$ curl -s https://raw.githubusercontent.com/chromium/chromium/master/net/http/transport_security_state_static.json | grep 'facebook'
      "name": "facebook",
    // Facebook would like to have pinning enforced on (*.)facebook.com and
      "name": "facebook.com", "policy": "custom",
      "mode": "force-https", "pins": "facebook", "include_subdomains_for_pinning": true
    { "name": "www.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "m.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "tablet.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "secure.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "pixel.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "apps.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "upload.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "developers.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "touch.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "mbasic.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "code.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "t.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "mtouch.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "business.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "research.facebook.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
      "mode": "force-https", "pins": "facebook", "include_subdomains_for_pinning": true
    { "name": "www.messenger.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "facebook" },
    { "name": "facebook-atom.appspot.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
    { "name": "facebook.ax", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
    { "name": "facebooktsukaikata.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
    { "name": "connect.facebook.net", "policy": "custom", "mode": "force-https", "include_subdomains": true },

.appドメインと.devドメインはトップレベルドメインとして登録されている.

$ curl -s https://raw.githubusercontent.com/chromium/chromium/master/net/http/transport_security_state_static.json | egrep '("dev"|"app")'
    { "name": "app", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
    { "name": "dev", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },

どちらのPreload Listもソースコードと同封されていた.つまり,ユーザはビルド済みWebブラウザに内包されるPreload ListをもとにHSTSを利用していることになる.

Bootstrap MITMへの脆弱性

MITM(man-in-the-middle, 中間者攻撃)の説明は割愛する.RFCのBootstrap MITM Vulnerabilityに説明がある.

Bootstrap MITMの脆弱性は,未知のHSTSホスト(HSTSに対応したWebサーバ)へユーザーがhttpを使って,アドレスを入力してアクセスするか,リンクに従ってアクセスする場合に発生する.原因は,HTTPクライアント(Webブラウザやアプリケーション)が最初に接続先WebサーバとHTTPの通信を試みることにある.攻撃者によりHTTPの通信が改変された場合,ユーザは気づかないうちに攻撃者の用意した攻撃サイトへ誘導されてしまう.

HTTPS対応サイトでも初回にHTTPでアクセスされた場合(例: URLバーへアドレスを直接入力),ホスト(サーバ)までの経路は平文でやり取りされる.つまり,通信が暗号化により保護されない.よって,平文でやり取りされている通信は中間者攻撃により盗聴や改ざん,なりすましや否認の恐れがある.

ツール群の対応

curl

巨大なHSTS Preload Listを内包するのは,多くの使用者に好ましくないのでオプションでPreload Listを指定できる実装がすすめている.現段階ではメインストリームへマージされていない.curl 7.7.0でも確認済み.

wget

1.99.2でChromium用のHSTS Preload List用のオプションが追加された.

1.99.2をビルドしたところ以下のオプションが確認できた.

$ wget --help | grep hsts
      --hsts                Use HTTP Strict Transport Security (HSTS).
      --hsts-file           Set file for HSTS caching. (default: ~/.wget-hsts)
      --hsts-preload        Use HTTP Strict Transport Security (HSTS).
                              [Not built with libhsts, so not functional]
      --hsts-preload-file   Set name for the HSTS Preload file (DAFSA format).
                              [Not built with libhsts, so not functional]

HSTS Preload ListへWebサイトを追加

  • .devドメインや.appドメイン
    • 既にPreload Listに含まれている為,対処は不要
  • その他のドメイン

Preload Listに対応した主要サービス

  • Twitter(twitter.com)
  • Facebook(facebook.com)
  • GitHub(github.com)
  • YouTube(youtube.com)
  • Slack(slack.com)
  • WordPress.com(wordpress.com)
  • Tumblr(tumblr.com)
  • Cybozu(cybozu.com)

参考資料