26
26
import io
27
27
import logging
28
28
import os
29
+ import re
29
30
import socket
30
31
import sys # modify sys.path when running in source tree
31
32
import time
@@ -534,11 +535,27 @@ def inner_run_cgi(self):
534
535
tracker .Client (tracker , self , env ).main ()
535
536
536
537
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 = "+"
537
550
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 )
539
553
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 )
542
559
543
560
def log_message (self , format , * args ):
544
561
''' Try to *safely* log to stderr.
@@ -547,7 +564,7 @@ def log_message(self, format, *args):
547
564
logger = logging .getLogger ('roundup.http' )
548
565
549
566
logger .info ("%s - - [%s] %s" %
550
- (self .client_address [ 0 ] ,
567
+ (self .address_string () ,
551
568
self .log_date_time_string (),
552
569
format % args ))
553
570
else :
@@ -680,6 +697,11 @@ class ServerConfig(configuration.Config):
680
697
"If set to yes the python logging module is used with "
681
698
"qualname\n 'roundup.http'. Otherwise logging is done to "
682
699
"stderr or the file\n specified 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.\n This appends a '+' sign to the logged "
703
+ "host ip/name. Use only if server is\n accessible only via "
704
+ "trusted reverse proxy." ),
683
705
(configuration .NullableFilePathOption , "pidfile" , "" ,
684
706
"File to which the server records "
685
707
"the process id of the daemon.\n "
@@ -734,6 +756,7 @@ class ServerConfig(configuration.Config):
734
756
"multiprocess" : "t:" ,
735
757
"template" : "i:" ,
736
758
"loghttpvialogger" : 'L' ,
759
+ "log_proxy_header" : 'P' ,
737
760
"ssl" : "s" ,
738
761
"pem" : "e:" ,
739
762
"include_headers" : "I:" ,
@@ -952,7 +975,8 @@ def usage(message=''):
952
975
-g <GID> runs the Roundup web server as this GID
953
976
-d <PIDfile> run the server in the background and write the server's PID
954
977
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.'''
956
980
if message :
957
981
message += '\n \n '
958
982
print (_ ('''\n %(message)sUsage: roundup-server [options] [name=tracker home]*
@@ -974,6 +998,9 @@ def usage(message=''):
974
998
-m <children> maximum number of children to spawn in fork multiprocess mode
975
999
-s enable SSL
976
1000
-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.
977
1004
-e <fname> PEM file containing SSL key and certificate
978
1005
-t <mode> multiprocess mode (default: %(mp_def)s).
979
1006
Allowed values: %(mp_types)s.
0 commit comments