Repository navigation
v0.4.18
修正(セキュリティ)
- 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-
admintoken pointing a rule at a key or secret file (certificate key, client certificate key,users_file, OIDC secrets) that another owner's rule uses gets409 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: snicould 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_authrequests (HTTP and gRPC) no longer carry the client's ownX-Real-IP; rproxy sets the client IP it sees.- A client's
Connectionheader 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_authno 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-IPandForwardedwithouttrust_forward_headerand adds rproxy's values, as HTTPforward_authdoes.
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'slimits.max_connectionstakes precedence. Refused sessions count instats.limitedandrproxy_rule_limited_total. Available from v0.4.18. - Rules that fail validation when restored from the DB are listed in
GET /rulesasfailed(#327) instead of disappearing, and counted inrproxy_rules{state="failed"}. A rule set's rule with the same key wins andrestore.conflictis 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_connectionsorRPROXY_UDP_MAX_SESSIONSfor udp rules with many clients. The cap is not split per source, so a spoofed flood that fills it can refuse legitimate clients forudp_idle_secs. - The
Forwardedheader (RFC 7239) from clients outsideglobal.trusted_proxiesis 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
AuthorizationorCookienamed inConnectionno longer reachesbasic_auth,oidcorforward_autheither (up to v0.4.17 it was removed only before the backend). oidclogout (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_limitwithsource: ipnow counts IPv6 clients per /64; longheader:<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
CheckRequestheaders are limited torequest_headerswhen it is set (content-lengthis included, as with Envoy). - DNS-01 REST template bodies without a
Content-Typeare escaped by their shape; set aContent-Typefor 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.