Mercurial > p > roundup > code
changeset 8169:627c5d6a0551
allow roundup-server to log real client IP behind reverse proxy
added -P flag to roundup-server to log client address from
X-Forwarded-For reverse proxy header rather than connecting
address. This logs the actual client address when roundup-server is
run behind a reverse proxy. It also appends a '+' sign to the logged
address/name.
This makes correlating reverse proxy logs to roundup logs much easier
by propagating the IP address.
Also added documentation for -D flag that was undocumented.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 01 Dec 2024 17:38:15 -0500 |
| parents | 3f0f4746dc7e |
| children | bf4a5bd5aa9f |
| files | CHANGES.txt roundup/scripts/roundup_server.py share/man/man1/roundup-server.1 |
| diffstat | 3 files changed, 51 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Tue Nov 26 17:11:13 2024 -0500 +++ b/CHANGES.txt Sun Dec 01 17:38:15 2024 -0500 @@ -47,6 +47,11 @@ filtering in the database. (Ralf Schlatterbeck) - issue2551370 - mark roundup session cookie with __Secure- prefix. (John Rouillard) +- add -P flag to roundup-server to log client address from + X-Forwarded-For reverse proxy header rather than connecting + address. This logs the actual client address when + roundup-server is run behind a reverse proxy. It also appends a + + sign to the logged address/name. (John Rouillard) 2024-07-13 2.4.0
--- a/roundup/scripts/roundup_server.py Tue Nov 26 17:11:13 2024 -0500 +++ b/roundup/scripts/roundup_server.py Sun Dec 01 17:38:15 2024 -0500 @@ -26,6 +26,7 @@ import io import logging import os +import re import socket import sys # modify sys.path when running in source tree import time @@ -534,11 +535,27 @@ tracker.Client(tracker, self, env).main() def address_string(self): + """Get IP address of client from: + left most element of X-Forwarded-For header element if set + client ip address otherwise. + if returned string is from X-Forwarded-For append + to string. + """ + from_forwarded_header="" + forwarded_for = None + if 'X-FORWARDED-FOR' in self.headers: + forwarded_for = re.split(r'[,\s]', + self.headers['X-FORWARDED-FOR'], + maxsplit=1)[0] + from_forwarded_header="+" if self.LOG_IPADDRESS: - return self.client_address[0] + return "%s%s" % (forwarded_for or self.client_address[0], + from_forwarded_header) else: - host, port = self.client_address - return socket.getfqdn(host) + if forwarded_for: + host = forwarded_for + else: + host, port = self.client_address + return "%s%s" % (socket.getfqdn(host), from_forwarded_header) def log_message(self, format, *args): ''' Try to *safely* log to stderr. @@ -547,7 +564,7 @@ logger = logging.getLogger('roundup.http') logger.info("%s - - [%s] %s" % - (self.client_address[0], + (self.address_string(), self.log_date_time_string(), format % args)) else: @@ -680,6 +697,11 @@ "If set to yes the python logging module is used with " "qualname\n'roundup.http'. Otherwise logging is done to " "stderr or the file\nspecified using the -l/logfile option."), + (configuration.BooleanOption, "log_proxy_header", "no", + "Use first element of reverse proxy header X-Forwarded-For " + "as client IP address.\nThis appends a '+' sign to the logged " + "host ip/name. Use only if server is\naccessible only via " + "trusted reverse proxy."), (configuration.NullableFilePathOption, "pidfile", "", "File to which the server records " "the process id of the daemon.\n" @@ -734,6 +756,7 @@ "multiprocess": "t:", "template": "i:", "loghttpvialogger": 'L', + "log_proxy_header": 'P', "ssl": "s", "pem": "e:", "include_headers": "I:", @@ -952,7 +975,8 @@ -g <GID> runs the Roundup web server as this GID -d <PIDfile> run the server in the background and write the server's PID to the file indicated by PIDfile. The -l option *must* be - specified if -d is used.''' + specified if -d is used. + -D run the server in the foreground even when -d is used.''' if message: message += '\n\n' print(_('''\n%(message)sUsage: roundup-server [options] [name=tracker home]* @@ -974,6 +998,9 @@ -m <children> maximum number of children to spawn in fork multiprocess mode -s enable SSL -L http request logging uses python logging (roundup.http) + -P log client address/name using reverse proxy X-Forwarded-For + header and not the connection IP (which is the reverse proxy). + Appends a '+' sign to the logged address/name. -e <fname> PEM file containing SSL key and certificate -t <mode> multiprocess mode (default: %(mp_def)s). Allowed values: %(mp_types)s.
--- a/share/man/man1/roundup-server.1 Tue Nov 26 17:11:13 2024 -0500 +++ b/share/man/man1/roundup-server.1 Sun Dec 01 17:38:15 2024 -0500 @@ -20,6 +20,9 @@ file indicated by PIDfile. The -l (or -L) option \fBmust\fP be specified if -d is used. .TP +\fB-D\fP +Run the server in the foreground even if -d is used. +.TP \fB-t\fP \fBfork|thread|debug|none\fP Control multi-process mode. \fBdebug\fP and \fBnone\fP are always available. If an invalid mode is specified the server starts in @@ -33,6 +36,17 @@ Sets a filename to log to (instead of stdout). This is required if the -d option is used. .TP +\fB-P\fP +If a reverse proxy is used in front of the roundup-server, the server +will log the ip address of the proxy, not the client browser. Using -P +logs the left most entry in the X-Forwarded-For http header as the +IP address of the client. This address will be logged or resolved to a +hostname (with \fB-N\fP) and a '+' character will be appended. +\fB-P\fP should only be used when the +roundup server is accessible only from trusted proxy hosts. See: +https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For +for details and warnings about using the X-Forwarded-For header. +.TP \fB-L\fP Have the server log using the Python logger with key roundup.http. .TP
