1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-07-15 01:44:22 +02:00

Implements --real-client-ip-header option. (#503)

* Implements -real-client-ip-header option.

* The -real-client-ip-header determines what HTTP header is used for
  determining the "real client IP" of the remote client.
* The -real-client-ip-header option supports the following headers:
  X-Forwarded-For X-ProxyUser-IP and X-Real-IP (default).
* Introduces new realClientIPParser interface to allow for multiple
  polymorphic classes to decide how to determine the real client IP.
* TODO: implement the more standard, but more complex `Forwarded` HTTP
  header.

* Corrected order of expected/actual in test cases

* Improved error message in getRemoteIP

* Add tests for getRemoteIP and getClientString

* Add comment explaining splitting of header

* Update documentation on -real-client-ip-header w/o -reverse-proxy

* Add PR number in changelog.

* Fix typo repeated word: "it"

Co-Authored-By: Joel Speed <Joel.speed@hotmail.co.uk>

* Update extended configuration language

* Simplify the language around dependance on -reverse-proxy

Co-Authored-By: Joel Speed <Joel.speed@hotmail.co.uk>

* Added completions

* Reorder real client IP header options

* Update CHANGELOG.md

* Apply suggestions from code review

Co-authored-by: Isabelle COWAN-BERGMAN <Izzette@users.noreply.github.com>

Co-authored-by: Joel Speed <Joel.speed@hotmail.co.uk>
Co-authored-by: Henry Jenkins <henry@henryjenkins.name>
This commit is contained in:
Isabelle COWAN-BERGMAN
2020-05-12 19:41:25 +02:00
committed by GitHub
parent d0cfca4b73
commit 111d17efde
10 changed files with 371 additions and 52 deletions

View File

@ -3,7 +3,6 @@ package logger
import (
"fmt"
"io"
"net"
"net/http"
"net/url"
"os"
@ -76,6 +75,9 @@ type reqLogMessageData struct {
Username string
}
// Returns the apparent "real client IP" as a string.
type GetClientFunc = func(r *http.Request) string
// A Logger represents an active logging object that generates lines of
// output to an io.Writer passed through a formatter. Each logging
// operation makes a single call to the Writer's Write method. A Logger
@ -88,7 +90,7 @@ type Logger struct {
stdEnabled bool
authEnabled bool
reqEnabled bool
reverseProxy bool
getClientFunc GetClientFunc
excludePaths map[string]struct{}
stdLogTemplate *template.Template
authTemplate *template.Template
@ -103,7 +105,7 @@ func New(flag int) *Logger {
stdEnabled: true,
authEnabled: true,
reqEnabled: true,
reverseProxy: false,
getClientFunc: func(r *http.Request) string { return r.RemoteAddr },
excludePaths: nil,
stdLogTemplate: template.Must(template.New("std-log").Parse(DefaultStandardLoggingFormat)),
authTemplate: template.Must(template.New("auth-log").Parse(DefaultAuthLoggingFormat)),
@ -153,7 +155,7 @@ func (l *Logger) PrintAuthf(username string, req *http.Request, status AuthStatu
username = "-"
}
client := GetClient(req, l.reverseProxy)
client := l.getClientFunc(req)
l.mu.Lock()
defer l.mu.Unlock()
@ -201,7 +203,7 @@ func (l *Logger) PrintReq(username, upstream string, req *http.Request, url url.
}
}
client := GetClient(req, l.reverseProxy)
client := l.getClientFunc(req)
l.mu.Lock()
defer l.mu.Unlock()
@ -252,22 +254,6 @@ func (l *Logger) GetFileLineString(calldepth int) string {
return fmt.Sprintf("%s:%d", file, line)
}
// GetClient parses an HTTP request for the client/remote IP address.
func GetClient(req *http.Request, reverseProxy bool) string {
client := req.RemoteAddr
if reverseProxy {
if ip := req.Header.Get("X-Real-IP"); ip != "" {
client = ip
}
}
if c, _, err := net.SplitHostPort(client); err == nil {
client = c
}
return client
}
// FormatTimestamp returns a formatted timestamp.
func (l *Logger) FormatTimestamp(ts time.Time) string {
if l.flag&LUTC != 0 {
@ -312,11 +298,11 @@ func (l *Logger) SetReqEnabled(e bool) {
l.reqEnabled = e
}
// SetReverseProxy controls whether logging will trust headers that can be set by a reverse proxy.
func (l *Logger) SetReverseProxy(e bool) {
// SetGetClientFunc sets the function which determines the apparent "real client IP".
func (l *Logger) SetGetClientFunc(f GetClientFunc) {
l.mu.Lock()
defer l.mu.Unlock()
l.reverseProxy = e
l.getClientFunc = f
}
// SetExcludePaths sets the paths to exclude from logging.
@ -392,10 +378,10 @@ func SetReqEnabled(e bool) {
std.SetReqEnabled(e)
}
// SetReverseProxy controls whether logging will trust headers that can be set
// by a reverse proxy for the standard logger.
func SetReverseProxy(e bool) {
std.SetReverseProxy(e)
// SetGetClientFunc sets the function which determines the apparent IP address
// set by a reverse proxy for the standard logger.
func SetGetClientFunc(f GetClientFunc) {
std.SetGetClientFunc(f)
}
// SetExcludePaths sets the path to exclude from logging, eg: health checks