Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for proxy provided nonce in chttpd #4993

Open
chewbranca opened this issue Feb 26, 2024 · 4 comments
Open

Allow for proxy provided nonce in chttpd #4993

chewbranca opened this issue Feb 26, 2024 · 4 comments

Comments

@chewbranca
Copy link
Contributor

Summary

As mentioned in #4990, when using a load balancer or proxy in front of CouchDB, the proxy will not receive the chosen nonce value from CouchDB until the response headers are sent, which, in the event of long running _find queries that return no data, can be a considerable amount of time longer than typical proxy timeouts.

The result is that the Mango reports are logged with the nonce value but the proxy timed out the request before getting any response headers so it was never able to retrieve the nonce for logging and connecting the proxy logs with the mango report. This is exacerbated by chttpd:maybe_log typically being set to false when using a proxy alongside a CouchDB cluster.

I was going to suggest modifying chttpd:maybe_log to be configurable based on error types, but @rnewson had a much simpler suggestion of allowing the proxy to provide the nonce, thereby establishing the connection from the get go.

I suggest we stick with the existing naming and allow for a request header named X-Couch-Request-ID, following https://github.com/apache/couchdb/blob/main/src/chttpd/src/chttpd.erl#L1368.

Desired Behaviour

A frontend proxy load balancer to a CouchDB cluster may supply an X-Couch-Request-ID to utilize as the nonce value instead of randomly generating one here: https://github.com/apache/couchdb/blob/main/src/chttpd/src/chttpd.erl#L297-L317

Possible Solution

diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index ab8e1e9a3..6912115c1 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -294,7 +294,12 @@ handle_request_int(MochiReq) ->
             Other -> Other
         end,
 
-    Nonce = couch_util:to_hex(crypto:strong_rand_bytes(5)),
+    Nonce = case MochiReq:get_header_value("x-couch-request-id") of
+        undefined ->
+            couch_util:to_hex(crypto:strong_rand_bytes(5));
+        Nonce0 ->
+            Nonce0
+    end,
 
     HttpReq0 = #httpd{
         mochi_req = MochiReq,

Additional context

#4990

@rnewson
Copy link
Member

rnewson commented Feb 26, 2024

good idea, but let's protect ourselves from client input. rejecting an x-couch-request-id that's above a certain length, say.

@nickva
Copy link
Contributor

nickva commented Feb 26, 2024

+1 to check the length and maybe also ensure it has only alphanumeric characters, no escapes, slashes, semicolons, etc.

@rnewson
Copy link
Member

rnewson commented Feb 27, 2024

agreed on those extra checks, nick.

@rnewson
Copy link
Member

rnewson commented Feb 27, 2024

and a 400 bad request if those checks aren't met, rather than silently ignoring the header or stripping it of invalid chars, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants