Skip to content

v0.4.18

Choose a tag to compare

@github-actions github-actions released this 26 Oct 03:22
· 7 commits to master since this release
f2518ec

修正(セキュリティ)

  • API のルールで、ほかの持ち主の鍵・秘密のファイルを使えないようにしました(#323)。ほかの持ち主のルールが指す鍵・秘密のファイル(証明書の鍵・クライアント証明書の鍵・users_file・OIDC の秘密)を、admin でないトークンが指すと 409 file_in_use になります。ルールやポートに絞ったトークンが、別のチームのルールの鍵で TLS を終端してそのサイトになりすますことができなくなります。証明書・チェーン・CA のファイルは今までどおり共有できます。
  • UDP の tls.mode: sni で、DTLS の ClientHello の断片を組み立てるときに、小さな入力で大きな CPU・メモリを使えたのを直しました(#332)。
    • 受け取ったバイトだけを持つ形に作り直し、上限を付けました(1 セッションの断片 512、すき間の後の部分 128、DTLS の確保 64 KiB)。超えたら名前のないものとして扱います。
    • 名前を 1 つのデータグラムで読めず続きを待つセッションの枠(1 ポート 4096)は、1 つの送信元のプレフィックス(IPv4 /24・IPv6 /48)で 64 までにしました。超えたらその網のいちばん古いものをあきらめます。1 つの網からの洪水で、ほかの網のクライアントが通れなくなることはありません。
  • HTTP のヘッダとミドルウェアまわりの低い指摘を直しました(#333)。
    • forward_auth(HTTP・gRPC)の問い合わせに、クライアントが送った X-Real-IP が残っていたのを直し、rproxy の見たクライアントの IP を付けるようにしました。
    • クライアントの Connection ヘッダで、認証のミドルウェアが付けた身元のヘッダや rproxy の付けるヘッダを消せたのを直しました。
    • DNS-01 の REST テンプレートで、DNS から得た名前をエスケープせずに URL・本文に入れていたのを直しました。
    • ルールが FIFO などを指したときにワーカーが止まることがあったのを直し、通常のファイルだけを使うようにしました。
    • basic_auth で、存在しないユーザーかどうかが応答の時間で分かったのを直しました(ファイルのハッシュの形式とコストがそろっているとき。同じコストの bcrypt を勧めます)。
    • gRPC の ext_authz でも、trust_forward_header がなければクライアントの X-Forwarded-*・X-Real-IP・Forwarded を捨て、rproxy の値を付けるようにしました(HTTP の forward_auth と同じ)。

追加

  • UDP のセッション数の既定の上限 RPROXY_UDP_MAX_SESSIONS(--udp-max-sessions)(#332)。既定は 1 つの udp のルールで 16384、0 で上限なし。ルールに limits.max_connections があればそちらを使います。断ったものは stats.limited と rproxy_rule_limited_total に数えます。v0.4.18 から使えます。
  • DB から戻すときに検証で落ちたルールを、GET /rules に failed として出すようにしました(#327)。これまでは一覧から消えていました。/metrics の rproxy_rules{state="failed"} にも数えます。同じキーのルールセットのルールがあればそちらを残し、restore.conflict を出します。

変更(更新の前に確かめてください)

  • UDP のセッション数に既定の上限(1 つのルールで 16384)が付きます。 今までは上限がありませんでした。多くのクライアントを受ける udp のルールは、limits.max_connections か RPROXY_UDP_MAX_SESSIONS で上げてください。上限は送信元ごとに分けていないので、送信元を偽った洪水で埋まると、udp_idle_secs のあいだ正しいクライアントも断られることがあります。
  • クライアントが送った RFC 7239 の Forwarded を、global.trusted_proxies の範囲の接続元からでなければ転送先に渡しません。
  • h2c(HTTP/2)への Upgrade を中継せず、普通の HTTP/1.1 のリクエストとして転送します(WebSocket などは今までどおり)。
  • Connection に Authorization や Cookie を書いたクライアントの値は、basic_auth・oidc・forward_auth にも届きません(v0.4.17 までは転送先にだけ届きませんでした)。
  • oidc のログアウト(logout_path)は POST でだけログアウトします。GET はログアウトのボタンのページを返し、ほかのサイトからの POST は 403 です。
  • rate_limit の source: ip で、IPv6 のクライアントを /64 ごとに数えます。header:<名前> の長い値は SHA-256 で覚えます。
  • ルールが指すファイルの誤りは、制御 API の答えでは理由を出さず、ログ(config.file)と --check-config に出します。
  • gRPC の ext_authz の CheckRequest のヘッダは、request_headers を書けばその名前だけになります(content-length は Envoy と同じく含めます)。
  • DNS-01 の REST テンプレートで Content-Type を書かない本文は、形で判断してエスケープします。= や & を含む JSON・form 以外の本文(XML など)は Content-Type を書いてください。
  • 前の版で作られ、ほかの持ち主のルールと同じ鍵・秘密のファイルを指しているルールは、止めずに動かし rule.shared_file(warn)を出します。新しくファイルを足す変更は断られます。

UI: TCP-UDP-rproxy-ui v0.4.10 · Kubernetes: rproxy-gateway v0.4.17


Fixed (security)

  • API rules can no longer use key and secret files owned by another token's rules (#323). A non-admin token pointing a rule at a key or secret file (certificate key, client certificate key, users_file, OIDC secrets) that another owner's rule uses gets 409 file_in_use, so a token limited to some rules or ports can't terminate TLS with another team's key and impersonate its site. Certificate, chain and CA files can still be shared.
  • UDP tls.mode: sni could be made to use a lot of CPU and memory with small DTLS ClientHello fragments (#332).
    • The reassembly now holds only the bytes received and has limits (512 fragments per session, 128 runs past a gap, 64 KiB allocated per DTLS session); beyond them the session counts as one without a name.
    • Of the 4096 slots per port for sessions waiting for the rest of a name, one source prefix (IPv4 /24, IPv6 /48) holds at most 64; past that the oldest of that network is given up. A flood from one network no longer blocks clients elsewhere.
  • Low findings around HTTP headers and middlewares (#333).
    • forward_auth requests (HTTP and gRPC) no longer carry the client's own X-Real-IP; rproxy sets the client IP it sees.
    • A client's Connection header can no longer remove identity headers set by authentication middlewares or headers rproxy adds.
    • DNS-01 REST templates now escape DNS-derived names for the URL and body.
    • Rules naming a FIFO or other non-regular file are refused instead of blocking a worker.
    • basic_auth no longer reveals through timing whether a user exists (when all hashes in the file share a scheme and cost; bcrypt with one cost is recommended).
    • gRPC ext_authz now drops the client's X-Forwarded-*, X-Real-IP and Forwarded without trust_forward_header and adds rproxy's values, as HTTP forward_auth does.

Added

  • A default UDP session cap, RPROXY_UDP_MAX_SESSIONS (--udp-max-sessions) (#332): 16384 per udp rule by default, 0 for none; a rule's limits.max_connections takes precedence. Refused sessions count in stats.limited and rproxy_rule_limited_total. Available from v0.4.18.
  • Rules that fail validation when restored from the DB are listed in GET /rules as failed (#327) instead of disappearing, and counted in rproxy_rules{state="failed"}. A rule set's rule with the same key wins and restore.conflict is logged.

Changed (check before updating)

  • UDP sessions now have a default cap (16384 per rule). There was no cap before. Raise it with limits.max_connections or RPROXY_UDP_MAX_SESSIONS for udp rules with many clients. The cap is not split per source, so a spoofed flood that fills it can refuse legitimate clients for udp_idle_secs.
  • The Forwarded header (RFC 7239) from clients outside global.trusted_proxies is no longer passed to backends.
  • Upgrades to h2c (HTTP/2) are no longer relayed; such requests are forwarded as plain HTTP/1.1 (WebSocket and other upgrades are unchanged).
  • A client's Authorization or Cookie named in Connection no longer reaches basic_auth, oidc or forward_auth either (up to v0.4.17 it was removed only before the backend).
  • oidc logout (logout_path) now signs out only on POST; GET shows a page with a sign-out button, and POSTs from other sites get 403.
  • rate_limit with source: ip now counts IPv6 clients per /64; long header:<name> values are kept as their SHA-256.
  • Errors about files named by rules no longer reveal details in control API answers; the reason is logged (config.file) and shown by --check-config.
  • gRPC ext_authz CheckRequest headers are limited to request_headers when it is set (content-length is included, as with Envoy).
  • DNS-01 REST template bodies without a Content-Type are escaped by their shape; set a Content-Type for bodies that are neither JSON nor a form (e.g. XML) and contain = or &.
  • Rules from earlier releases that already share key or secret files with another owner's rule keep running and log rule.shared_file (warn); changes that add such a file are refused.