Skip to content

Commit b1f976c

Browse files
committed
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.
1 parent e5daacf commit b1f976c

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

CHANGES.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ Features:
4747
filtering in the database. (Ralf Schlatterbeck)
4848
- issue2551370 - mark roundup session cookie with __Secure-
4949
prefix. (John Rouillard)
50+
- add -P flag to roundup-server to log client address from
51+
X-Forwarded-For reverse proxy header rather than connecting
52+
address. This logs the actual client address when
53+
roundup-server is run behind a reverse proxy. It also appends a
54+
+ sign to the logged address/name. (John Rouillard)
5055

5156
2024-07-13 2.4.0
5257

roundup/scripts/roundup_server.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io
2727
import logging
2828
import os
29+
import re
2930
import socket
3031
import sys # modify sys.path when running in source tree
3132
import time
@@ -534,11 +535,27 @@ def inner_run_cgi(self):
534535
tracker.Client(tracker, self, env).main()
535536

536537
def address_string(self):
538+
"""Get IP address of client from:
539+
left most element of X-Forwarded-For header element if set
540+
client ip address otherwise.
541+
if returned string is from X-Forwarded-For append + to string.
542+
"""
543+
from_forwarded_header=""
544+
forwarded_for = None
545+
if 'X-FORWARDED-FOR' in self.headers:
546+
forwarded_for = re.split(r'[,\s]',
547+
self.headers['X-FORWARDED-FOR'],
548+
maxsplit=1)[0]
549+
from_forwarded_header="+"
537550
if self.LOG_IPADDRESS:
538-
return self.client_address[0]
551+
return "%s%s" % (forwarded_for or self.client_address[0],
552+
from_forwarded_header)
539553
else:
540-
host, port = self.client_address
541-
return socket.getfqdn(host)
554+
if forwarded_for:
555+
host = forwarded_for
556+
else:
557+
host, port = self.client_address
558+
return "%s%s" % (socket.getfqdn(host), from_forwarded_header)
542559

543560
def log_message(self, format, *args):
544561
''' Try to *safely* log to stderr.
@@ -547,7 +564,7 @@ def log_message(self, format, *args):
547564
logger = logging.getLogger('roundup.http')
548565

549566
logger.info("%s - - [%s] %s" %
550-
(self.client_address[0],
567+
(self.address_string(),
551568
self.log_date_time_string(),
552569
format % args))
553570
else:
@@ -680,6 +697,11 @@ class ServerConfig(configuration.Config):
680697
"If set to yes the python logging module is used with "
681698
"qualname\n'roundup.http'. Otherwise logging is done to "
682699
"stderr or the file\nspecified using the -l/logfile option."),
700+
(configuration.BooleanOption, "log_proxy_header", "no",
701+
"Use first element of reverse proxy header X-Forwarded-For "
702+
"as client IP address.\nThis appends a '+' sign to the logged "
703+
"host ip/name. Use only if server is\naccessible only via "
704+
"trusted reverse proxy."),
683705
(configuration.NullableFilePathOption, "pidfile", "",
684706
"File to which the server records "
685707
"the process id of the daemon.\n"
@@ -734,6 +756,7 @@ class ServerConfig(configuration.Config):
734756
"multiprocess": "t:",
735757
"template": "i:",
736758
"loghttpvialogger": 'L',
759+
"log_proxy_header": 'P',
737760
"ssl": "s",
738761
"pem": "e:",
739762
"include_headers": "I:",
@@ -952,7 +975,8 @@ def usage(message=''):
952975
-g <GID> runs the Roundup web server as this GID
953976
-d <PIDfile> run the server in the background and write the server's PID
954977
to the file indicated by PIDfile. The -l option *must* be
955-
specified if -d is used.'''
978+
specified if -d is used.
979+
-D run the server in the foreground even when -d is used.'''
956980
if message:
957981
message += '\n\n'
958982
print(_('''\n%(message)sUsage: roundup-server [options] [name=tracker home]*
@@ -974,6 +998,9 @@ def usage(message=''):
974998
-m <children> maximum number of children to spawn in fork multiprocess mode
975999
-s enable SSL
9761000
-L http request logging uses python logging (roundup.http)
1001+
-P log client address/name using reverse proxy X-Forwarded-For
1002+
header and not the connection IP (which is the reverse proxy).
1003+
Appends a '+' sign to the logged address/name.
9771004
-e <fname> PEM file containing SSL key and certificate
9781005
-t <mode> multiprocess mode (default: %(mp_def)s).
9791006
Allowed values: %(mp_types)s.

share/man/man1/roundup-server.1

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Run the server in the background and write the server's PID to the
2020
file indicated by PIDfile. The -l (or -L) option \fBmust\fP be
2121
specified if -d is used.
2222
.TP
23+
\fB-D\fP
24+
Run the server in the foreground even if -d is used.
25+
.TP
2326
\fB-t\fP \fBfork|thread|debug|none\fP
2427
Control multi-process mode. \fBdebug\fP and \fBnone\fP are always
2528
available. If an invalid mode is specified the server starts in
@@ -33,6 +36,17 @@ may need to be increased on a heavily loaded site. Default 40.
3336
Sets a filename to log to (instead of stdout). This is required if the -d
3437
option is used.
3538
.TP
39+
\fB-P\fP
40+
If a reverse proxy is used in front of the roundup-server, the server
41+
will log the ip address of the proxy, not the client browser. Using -P
42+
logs the left most entry in the X-Forwarded-For http header as the
43+
IP address of the client. This address will be logged or resolved to a
44+
hostname (with \fB-N\fP) and a '+' character will be appended.
45+
\fB-P\fP should only be used when the
46+
roundup server is accessible only from trusted proxy hosts. See:
47+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
48+
for details and warnings about using the X-Forwarded-For header.
49+
.TP
3650
\fB-L\fP
3751
Have the server log using the Python logger with key roundup.http.
3852
.TP

0 commit comments

Comments
 (0)