Add reverse proxy configuration support for remote IP address (#14959)
* Add reverse proxy configuration support for remote IP address validation * Trust all IP addresses in containerized environments by default * Use single option to specify networks and proxy IP addresses. By default trust all loopback IPs Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
							parent
							
								
									6e423d5573
								
							
						
					
					
						commit
						044cd4d016
					
				
					 20 changed files with 464 additions and 2 deletions
				
			
		|  | @ -549,6 +549,10 @@ COOKIE_REMEMBER_NAME = gitea_incredible | ||||||
| ; Reverse proxy authentication header name of user name | ; Reverse proxy authentication header name of user name | ||||||
| REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER | REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER | ||||||
| REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL | REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL | ||||||
|  | ; Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request | ||||||
|  | REVERSE_PROXY_LIMIT = 1 | ||||||
|  | ; List of IP addresses and networks seperated by comma of trusted proxy servers. Use `*` to trust all. | ||||||
|  | REVERSE_PROXY_TRUSTED_PROXIES = 127.0.0.0/8,::1/128 | ||||||
| ; The minimum password length for new Users | ; The minimum password length for new Users | ||||||
| MIN_PASSWORD_LENGTH = 6 | MIN_PASSWORD_LENGTH = 6 | ||||||
| ; Set to true to allow users to import local server paths | ; Set to true to allow users to import local server paths | ||||||
|  |  | ||||||
|  | @ -53,6 +53,8 @@ ROOT_PATH = /data/gitea/log | ||||||
| [security] | [security] | ||||||
| INSTALL_LOCK = $INSTALL_LOCK | INSTALL_LOCK = $INSTALL_LOCK | ||||||
| SECRET_KEY   = $SECRET_KEY | SECRET_KEY   = $SECRET_KEY | ||||||
|  | REVERSE_PROXY_LIMIT = 1 | ||||||
|  | REVERSE_PROXY_TRUSTED_PROXIES = * | ||||||
| 
 | 
 | ||||||
| [service] | [service] | ||||||
| DISABLE_REGISTRATION = $DISABLE_REGISTRATION | DISABLE_REGISTRATION = $DISABLE_REGISTRATION | ||||||
|  |  | ||||||
|  | @ -49,6 +49,8 @@ ROOT_PATH = $GITEA_WORK_DIR/data/log | ||||||
| [security] | [security] | ||||||
| INSTALL_LOCK = $INSTALL_LOCK | INSTALL_LOCK = $INSTALL_LOCK | ||||||
| SECRET_KEY   = $SECRET_KEY | SECRET_KEY   = $SECRET_KEY | ||||||
|  | REVERSE_PROXY_LIMIT = 1 | ||||||
|  | REVERSE_PROXY_TRUSTED_PROXIES = * | ||||||
| 
 | 
 | ||||||
| [service] | [service] | ||||||
| DISABLE_REGISTRATION = $DISABLE_REGISTRATION | DISABLE_REGISTRATION = $DISABLE_REGISTRATION | ||||||
|  |  | ||||||
|  | @ -390,6 +390,9 @@ relation to port exhaustion. | ||||||
|    authentication. |    authentication. | ||||||
| - `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: Header name for reverse proxy | - `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: Header name for reverse proxy | ||||||
|    authentication provided email. |    authentication provided email. | ||||||
|  | - `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request. | ||||||
|  |    Number of trusted proxy count. Set to zero to not use these headers. | ||||||
|  | - `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all. | ||||||
| - `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with git hook privilege to create custom git hooks. | - `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with git hook privilege to create custom git hooks. | ||||||
|    WARNING: Custom git hooks can be used to perform arbitrary code execution on the host operating system. |    WARNING: Custom git hooks can be used to perform arbitrary code execution on the host operating system. | ||||||
|    This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service. |    This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service. | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							|  | @ -22,6 +22,7 @@ require ( | ||||||
| 	github.com/boombuler/barcode v1.0.1 // indirect | 	github.com/boombuler/barcode v1.0.1 // indirect | ||||||
| 	github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect | 	github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect | ||||||
| 	github.com/caddyserver/certmagic v0.12.0 | 	github.com/caddyserver/certmagic v0.12.0 | ||||||
|  | 	github.com/chi-middleware/proxy v1.1.1 | ||||||
| 	github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect | 	github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect | ||||||
| 	github.com/couchbase/gomemcached v0.1.2 // indirect | 	github.com/couchbase/gomemcached v0.1.2 // indirect | ||||||
| 	github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect | 	github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							|  | @ -194,6 +194,8 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= | ||||||
| github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= | ||||||
| github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= | github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= | ||||||
| github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||||
|  | github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ= | ||||||
|  | github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0= | ||||||
| github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= | github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= | ||||||
| github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= | github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= | ||||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||||
|  | @ -318,6 +320,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro | ||||||
| github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= | github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= | ||||||
| github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs= | github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs= | ||||||
| github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= | github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= | ||||||
|  | github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo= | ||||||
|  | github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= | ||||||
| github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw= | github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw= | ||||||
| github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I= | github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I= | ||||||
| github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0= | github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0= | ||||||
|  |  | ||||||
|  | @ -169,6 +169,8 @@ var ( | ||||||
| 	CookieRememberName                 string | 	CookieRememberName                 string | ||||||
| 	ReverseProxyAuthUser               string | 	ReverseProxyAuthUser               string | ||||||
| 	ReverseProxyAuthEmail              string | 	ReverseProxyAuthEmail              string | ||||||
|  | 	ReverseProxyLimit                  int | ||||||
|  | 	ReverseProxyTrustedProxies         []string | ||||||
| 	MinPasswordLength                  int | 	MinPasswordLength                  int | ||||||
| 	ImportLocalPaths                   bool | 	ImportLocalPaths                   bool | ||||||
| 	DisableGitHooks                    bool | 	DisableGitHooks                    bool | ||||||
|  | @ -819,8 +821,16 @@ func NewContext() { | ||||||
| 	LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt(7) | 	LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt(7) | ||||||
| 	CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome") | 	CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome") | ||||||
| 	CookieRememberName = sec.Key("COOKIE_REMEMBER_NAME").MustString("gitea_incredible") | 	CookieRememberName = sec.Key("COOKIE_REMEMBER_NAME").MustString("gitea_incredible") | ||||||
|  | 
 | ||||||
| 	ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") | 	ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") | ||||||
| 	ReverseProxyAuthEmail = sec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL") | 	ReverseProxyAuthEmail = sec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL") | ||||||
|  | 
 | ||||||
|  | 	ReverseProxyLimit = sec.Key("REVERSE_PROXY_LIMIT").MustInt(1) | ||||||
|  | 	ReverseProxyTrustedProxies = sec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",") | ||||||
|  | 	if len(ReverseProxyTrustedProxies) == 0 { | ||||||
|  | 		ReverseProxyTrustedProxies = []string{"127.0.0.0/8", "::1/128"} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6) | 	MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6) | ||||||
| 	ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false) | 	ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false) | ||||||
| 	DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(true) | 	DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(true) | ||||||
|  |  | ||||||
|  | @ -46,6 +46,7 @@ import ( | ||||||
| 	"gitea.com/go-chi/captcha" | 	"gitea.com/go-chi/captcha" | ||||||
| 	"gitea.com/go-chi/session" | 	"gitea.com/go-chi/session" | ||||||
| 	"github.com/NYTimes/gziphandler" | 	"github.com/NYTimes/gziphandler" | ||||||
|  | 	"github.com/chi-middleware/proxy" | ||||||
| 	"github.com/go-chi/chi/middleware" | 	"github.com/go-chi/chi/middleware" | ||||||
| 	"github.com/go-chi/cors" | 	"github.com/go-chi/cors" | ||||||
| 	"github.com/prometheus/client_golang/prometheus" | 	"github.com/prometheus/client_golang/prometheus" | ||||||
|  | @ -65,14 +66,30 @@ func commonMiddlewares() []func(http.Handler) http.Handler { | ||||||
| 				next.ServeHTTP(context.NewResponse(resp), req) | 				next.ServeHTTP(context.NewResponse(resp), req) | ||||||
| 			}) | 			}) | ||||||
| 		}, | 		}, | ||||||
| 		middleware.RealIP, |  | ||||||
| 		middleware.StripSlashes, |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if setting.ReverseProxyLimit > 0 { | ||||||
|  | 		opt := proxy.NewForwardedHeadersOptions(). | ||||||
|  | 			WithForwardLimit(setting.ReverseProxyLimit). | ||||||
|  | 			ClearTrustedProxies() | ||||||
|  | 		for _, n := range setting.ReverseProxyTrustedProxies { | ||||||
|  | 			if !strings.Contains(n, "/") { | ||||||
|  | 				opt.AddTrustedProxy(n) | ||||||
|  | 			} else { | ||||||
|  | 				opt.AddTrustedNetwork(n) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		handlers = append(handlers, proxy.ForwardedHeaders(opt)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	handlers = append(handlers, middleware.StripSlashes) | ||||||
|  | 
 | ||||||
| 	if !setting.DisableRouterLog && setting.RouterLogLevel != log.NONE { | 	if !setting.DisableRouterLog && setting.RouterLogLevel != log.NONE { | ||||||
| 		if log.GetLogger("router").GetLevel() <= setting.RouterLogLevel { | 		if log.GetLogger("router").GetLevel() <= setting.RouterLogLevel { | ||||||
| 			handlers = append(handlers, LoggerHandler(setting.RouterLogLevel)) | 			handlers = append(handlers, LoggerHandler(setting.RouterLogLevel)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	handlers = append(handlers, func(next http.Handler) http.Handler { | 	handlers = append(handlers, func(next http.Handler) http.Handler { | ||||||
| 		return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { | 		return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { | ||||||
| 			// Why we need this? The Recovery() will try to render a beautiful
 | 			// Why we need this? The Recovery() will try to render a beautiful
 | ||||||
|  |  | ||||||
							
								
								
									
										42
									
								
								vendor/github.com/chi-middleware/proxy/.drone.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/chi-middleware/proxy/.drone.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | --- | ||||||
|  | kind: pipeline | ||||||
|  | name: compliance | ||||||
|  | 
 | ||||||
|  | platform: | ||||||
|  |   os: linux | ||||||
|  |   arch: amd64 | ||||||
|  | 
 | ||||||
|  | steps: | ||||||
|  |   - name: lint | ||||||
|  |     pull: always | ||||||
|  |     image: golang:1.14 | ||||||
|  |     commands: | ||||||
|  |       - make fmt-check | ||||||
|  |       - make misspell-check | ||||||
|  |       - make lint | ||||||
|  | 
 | ||||||
|  |   - name: test | ||||||
|  |     pull: always | ||||||
|  |     image: golang:1.14 | ||||||
|  |     commands: | ||||||
|  |       - make test | ||||||
|  |     depends_on: | ||||||
|  |       - lint | ||||||
|  | 
 | ||||||
|  |   - name: coverage | ||||||
|  |     pull: always | ||||||
|  |     image: robertstettner/drone-codecov | ||||||
|  |     settings: | ||||||
|  |       files: | ||||||
|  |         - coverage.out | ||||||
|  |     environment: | ||||||
|  |       CODECOV_TOKEN: | ||||||
|  |         from_secret: codecov_token | ||||||
|  |     depends_on: | ||||||
|  |       - test | ||||||
|  |     when: | ||||||
|  |       branch: | ||||||
|  |         - master | ||||||
|  |       event: | ||||||
|  |         - push | ||||||
|  |         - pull_request | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/chi-middleware/proxy/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/chi-middleware/proxy/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | vendor/ | ||||||
|  | coverage.out | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/chi-middleware/proxy/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/chi-middleware/proxy/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | run: | ||||||
|  |     timeout: 3m | ||||||
|  | 
 | ||||||
|  | issues: | ||||||
|  |   exclude-rules: | ||||||
|  |     # Exclude some linters from running on tests files. | ||||||
|  |     - path: _test\.go | ||||||
|  |       linters: | ||||||
|  |         - errcheck | ||||||
							
								
								
									
										25
									
								
								vendor/github.com/chi-middleware/proxy/.revive.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/chi-middleware/proxy/.revive.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | ignoreGeneratedHeader = false | ||||||
|  | severity = "warning" | ||||||
|  | confidence = 0.8 | ||||||
|  | errorCode = 1 | ||||||
|  | warningCode = 1 | ||||||
|  | 
 | ||||||
|  | [rule.blank-imports] | ||||||
|  | [rule.context-as-argument] | ||||||
|  | [rule.context-keys-type] | ||||||
|  | [rule.dot-imports] | ||||||
|  | [rule.error-return] | ||||||
|  | [rule.error-strings] | ||||||
|  | [rule.error-naming] | ||||||
|  | [rule.exported] | ||||||
|  | [rule.if-return] | ||||||
|  | [rule.increment-decrement] | ||||||
|  | [rule.var-naming] | ||||||
|  | [rule.var-declaration] | ||||||
|  | [rule.package-comments] | ||||||
|  | [rule.range] | ||||||
|  | [rule.receiver-naming] | ||||||
|  | [rule.time-naming] | ||||||
|  | [rule.unexported-return] | ||||||
|  | [rule.indent-error-flow] | ||||||
|  | [rule.errorf] | ||||||
							
								
								
									
										19
									
								
								vendor/github.com/chi-middleware/proxy/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/chi-middleware/proxy/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | Copyright (c) 2020 Lauris BH | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | in the Software without restriction, including without limitation the rights | ||||||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | copies of the Software, and to permit persons to whom the Software is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in | ||||||
|  | all copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | THE SOFTWARE. | ||||||
							
								
								
									
										59
									
								
								vendor/github.com/chi-middleware/proxy/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/chi-middleware/proxy/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | ||||||
|  | GO ?= go | ||||||
|  | HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) | ||||||
|  | ifeq ($(HAS_GO), GO) | ||||||
|  | 	GOPATH ?= $(shell $(GO) env GOPATH) | ||||||
|  | 	export PATH := $(GOPATH)/bin:$(PATH) | ||||||
|  | endif | ||||||
|  | 
 | ||||||
|  | GOFMT ?= gofmt -s | ||||||
|  | 
 | ||||||
|  | ifneq ($(RACE_ENABLED),) | ||||||
|  | 	GOTESTFLAGS ?= -race | ||||||
|  | endif | ||||||
|  | 
 | ||||||
|  | GO_SOURCES := $(wildcard *.go) | ||||||
|  | GO_SOURCES_OWN := $(filter-out vendor/%, $(GO_SOURCES)) | ||||||
|  | GO_PACKAGES ?= $(shell $(GO) list ./... | grep -v /vendor/) | ||||||
|  | 
 | ||||||
|  | .PHONY: revive | ||||||
|  | revive: | ||||||
|  | 	@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
 | ||||||
|  | 		$(GO) get -u github.com/mgechev/revive; \
 | ||||||
|  | 	fi | ||||||
|  | 	revive -config .revive.toml -exclude=./vendor/... ./... || exit 1 | ||||||
|  | 
 | ||||||
|  | .PHONY: golangci-lint | ||||||
|  | golangci-lint: | ||||||
|  | 	@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
 | ||||||
|  | 		export BINARY="golangci-lint"; \
 | ||||||
|  | 		curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.26.0; \
 | ||||||
|  | 	fi | ||||||
|  | 	golangci-lint run --timeout 5m | ||||||
|  | 
 | ||||||
|  | .PHONY: lint | ||||||
|  | lint: golangci-lint revive | ||||||
|  | 
 | ||||||
|  | .PHONY: fmt | ||||||
|  | fmt: | ||||||
|  | 	$(GOFMT) -w $(GO_SOURCES_OWN) | ||||||
|  | 
 | ||||||
|  | .PHONY: fmt-check | ||||||
|  | fmt-check: | ||||||
|  | 	# get all go files and run go fmt on them | ||||||
|  | 	@diff=$$($(GOFMT) -d $(GO_SOURCES_OWN)); \
 | ||||||
|  | 	if [ -n "$$diff" ]; then \
 | ||||||
|  | 		echo "Please run 'make fmt' and commit the result:"; \
 | ||||||
|  | 		echo "$${diff}"; \
 | ||||||
|  | 		exit 1; \
 | ||||||
|  | 	fi; | ||||||
|  | 
 | ||||||
|  | .PHONY: misspell-check | ||||||
|  | misspell-check: | ||||||
|  | 	@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
 | ||||||
|  | 		$(GO) get -u github.com/client9/misspell/cmd/misspell; \
 | ||||||
|  | 	fi | ||||||
|  | 	misspell -error $(GO_SOURCES_OWN) | ||||||
|  | 
 | ||||||
|  | .PHONY: test | ||||||
|  | test: | ||||||
|  | 	$(GO) test -cover -coverprofile coverage.out $(GOTESTFLAGS) $(GO_PACKAGES) | ||||||
							
								
								
									
										46
									
								
								vendor/github.com/chi-middleware/proxy/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/chi-middleware/proxy/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | # [Chi](https://github.com/go-chi/chi) proxy middleware | ||||||
|  | 
 | ||||||
|  | Forwarded headers middleware to use if application is run behind reverse proxy. | ||||||
|  | 
 | ||||||
|  | [](https://pkg.go.dev/github.com/chi-middleware/proxy) | ||||||
|  | [](https://codecov.io/gh/chi-middleware/proxy) | ||||||
|  | [](https://goreportcard.com/report/github.com/chi-middleware/proxy) | ||||||
|  | [](https://cloud.drone.io/chi-middleware/proxy) | ||||||
|  | 
 | ||||||
|  | ## Usage | ||||||
|  | 
 | ||||||
|  | Import using: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | import "github.com/chi-middleware/proxy" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Use middleware with default options (trusted from proxy `127.0.0.1` and trusts only last IP address provided in header): | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  |     r := chi.NewRouter() | ||||||
|  |     r.Use(proxy.ForwardedHeaders()) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Extend default options: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  |     r := chi.NewRouter() | ||||||
|  |     r.Use(proxy.ForwardedHeaders( | ||||||
|  |         proxy.NewForwardedHeadersOptions(). | ||||||
|  |             WithForwardLimit(2). | ||||||
|  |             ClearTrustedProxies().AddTrustedProxy("10.0.0.1"), | ||||||
|  |     )) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Provide custom options: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  |     r := chi.NewRouter() | ||||||
|  |     r.Use(proxy.ForwardedHeaders(&ForwardedHeadersOptions{ | ||||||
|  |         ForwardLimit: 1, | ||||||
|  |         TrustedProxies: []net.IP{ | ||||||
|  |             net.IPv4(10, 0, 0, 1), | ||||||
|  |         }, | ||||||
|  |     })) | ||||||
|  | ``` | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/chi-middleware/proxy/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/chi-middleware/proxy/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | module github.com/chi-middleware/proxy | ||||||
|  | 
 | ||||||
|  | go 1.14 | ||||||
|  | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/go-chi/chi/v5 v5.0.1 | ||||||
|  | 	github.com/stretchr/testify v1.7.0 | ||||||
|  | ) | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/chi-middleware/proxy/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/chi-middleware/proxy/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||||||
|  | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
|  | github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo= | ||||||
|  | github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
|  | github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= | ||||||
|  | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
|  | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||||||
|  | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
							
								
								
									
										77
									
								
								vendor/github.com/chi-middleware/proxy/middleware.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								vendor/github.com/chi-middleware/proxy/middleware.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | ||||||
|  | // Copyright 2020 Lauris BH. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package proxy | ||||||
|  | 
 | ||||||
|  | // Ported from Goji's middleware, source:
 | ||||||
|  | // https://github.com/zenazn/goji/tree/master/web/middleware
 | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | 	"net/http" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For") | ||||||
|  | var xRealIP = http.CanonicalHeaderKey("X-Real-IP") | ||||||
|  | 
 | ||||||
|  | // ForwardedHeaders is a middleware that sets a http.Request's RemoteAddr to the results
 | ||||||
|  | // of parsing either the X-Real-IP header or the X-Forwarded-For header (in that
 | ||||||
|  | // order).
 | ||||||
|  | func ForwardedHeaders(options ...*ForwardedHeadersOptions) func(h http.Handler) http.Handler { | ||||||
|  | 	opt := defaultOptions | ||||||
|  | 	if len(options) > 0 { | ||||||
|  | 		opt = options[0] | ||||||
|  | 	} | ||||||
|  | 	return func(h http.Handler) http.Handler { | ||||||
|  | 		fn := func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 			// Treat unix socket as 127.0.0.1
 | ||||||
|  | 			if r.RemoteAddr == "@" { | ||||||
|  | 				r.RemoteAddr = "127.0.0.1:0" | ||||||
|  | 			} | ||||||
|  | 			if rip := realIP(r, opt); len(rip) > 0 { | ||||||
|  | 				r.RemoteAddr = net.JoinHostPort(rip, "0") | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			h.ServeHTTP(w, r) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return http.HandlerFunc(fn) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func realIP(r *http.Request, options *ForwardedHeadersOptions) string { | ||||||
|  | 	host, _, err := net.SplitHostPort(r.RemoteAddr) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !options.isTrustedProxy(net.ParseIP(host)) { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ip string | ||||||
|  | 
 | ||||||
|  | 	if xrip := r.Header.Get(xRealIP); xrip != "" { | ||||||
|  | 		ip = xrip | ||||||
|  | 	} else if xff := r.Header.Get(xForwardedFor); xff != "" { | ||||||
|  | 		p := 0 | ||||||
|  | 		for i := options.ForwardLimit; i > 0; i-- { | ||||||
|  | 			if p > 0 { | ||||||
|  | 				xff = xff[:p-2] | ||||||
|  | 			} | ||||||
|  | 			p = strings.LastIndex(xff, ", ") | ||||||
|  | 			if p < 0 { | ||||||
|  | 				p = 0 | ||||||
|  | 				break | ||||||
|  | 			} else { | ||||||
|  | 				p += 2 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ip = xff[p:] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ip | ||||||
|  | } | ||||||
							
								
								
									
										115
									
								
								vendor/github.com/chi-middleware/proxy/options.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								vendor/github.com/chi-middleware/proxy/options.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,115 @@ | ||||||
|  | // Copyright 2020 Lauris BH. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package proxy | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ForwardedHeadersOptions represents options for forwarded header middleware
 | ||||||
|  | type ForwardedHeadersOptions struct { | ||||||
|  | 	// ForwardLimit limits the number of entries in the headers that will be processed.
 | ||||||
|  | 	// The default value is 1. Set to 0 to disable the limit.
 | ||||||
|  | 	ForwardLimit int | ||||||
|  | 	// TrustingAllProxies option sets to trust all proxies.
 | ||||||
|  | 	TrustingAllProxies bool | ||||||
|  | 	// KnownProxies represents addresses of trusted proxies.
 | ||||||
|  | 	TrustedProxies []net.IP | ||||||
|  | 	// TrustedNetworks represents addresses of trusted networks.
 | ||||||
|  | 	TrustedNetworks []*net.IPNet | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var defaultOptions = &ForwardedHeadersOptions{ | ||||||
|  | 	ForwardLimit: 1, | ||||||
|  | 	TrustedProxies: []net.IP{ | ||||||
|  | 		net.IPv4(127, 0, 0, 1), | ||||||
|  | 	}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewForwardedHeadersOptions creates new middleware options
 | ||||||
|  | func NewForwardedHeadersOptions() *ForwardedHeadersOptions { | ||||||
|  | 	return &ForwardedHeadersOptions{ | ||||||
|  | 		ForwardLimit:    defaultOptions.ForwardLimit, | ||||||
|  | 		TrustedProxies:  defaultOptions.TrustedProxies, | ||||||
|  | 		TrustedNetworks: defaultOptions.TrustedNetworks, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithForwardLimit sets number of entries to be processed
 | ||||||
|  | func (opts *ForwardedHeadersOptions) WithForwardLimit(limit int) *ForwardedHeadersOptions { | ||||||
|  | 	opts.ForwardLimit = limit | ||||||
|  | 	return opts | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TrustAllProxies sets to trust all proxies
 | ||||||
|  | func (opts *ForwardedHeadersOptions) TrustAllProxies() *ForwardedHeadersOptions { | ||||||
|  | 	opts.TrustingAllProxies = true | ||||||
|  | 	return opts | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearTrustedProxies clears trusted proxy list
 | ||||||
|  | func (opts *ForwardedHeadersOptions) ClearTrustedProxies() *ForwardedHeadersOptions { | ||||||
|  | 	opts.TrustingAllProxies = false | ||||||
|  | 	opts.TrustedProxies = make([]net.IP, 0) | ||||||
|  | 	return opts | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddTrustedProxy adds proxy IP to trusted proxy list
 | ||||||
|  | func (opts *ForwardedHeadersOptions) AddTrustedProxy(ip string) *ForwardedHeadersOptions { | ||||||
|  | 	// Special option to trust all proxies if IP address is set as wildcard
 | ||||||
|  | 	if ip == "*" { | ||||||
|  | 		opts.TrustingAllProxies = true | ||||||
|  | 		return opts | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ipaddr := net.ParseIP(ip) | ||||||
|  | 	if ipaddr == nil { | ||||||
|  | 		return opts | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	opts.TrustedProxies = append(opts.TrustedProxies, ipaddr) | ||||||
|  | 	return opts | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearTrustedNetworks clears trusted network list
 | ||||||
|  | func (opts *ForwardedHeadersOptions) ClearTrustedNetworks() *ForwardedHeadersOptions { | ||||||
|  | 	opts.TrustedNetworks = make([]*net.IPNet, 0) | ||||||
|  | 	return opts | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddTrustedNetwork adds network to trusted network list
 | ||||||
|  | func (opts *ForwardedHeadersOptions) AddTrustedNetwork(cidr string) *ForwardedHeadersOptions { | ||||||
|  | 	_, netmask, err := net.ParseCIDR(cidr) | ||||||
|  | 	if err != nil || netmask == nil { | ||||||
|  | 		return opts | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	opts.TrustedNetworks = append(opts.TrustedNetworks, netmask) | ||||||
|  | 	return opts | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (opts *ForwardedHeadersOptions) isTrustedProxy(ip net.IP) bool { | ||||||
|  | 	if opts.TrustingAllProxies { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if ip == nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tip := range opts.TrustedProxies { | ||||||
|  | 		if tip.Equal(ip) { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tnet := range opts.TrustedNetworks { | ||||||
|  | 		if tnet.Contains(ip) { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							|  | @ -175,6 +175,9 @@ github.com/bradfitz/gomemcache/memcache | ||||||
| github.com/caddyserver/certmagic | github.com/caddyserver/certmagic | ||||||
| # github.com/cespare/xxhash/v2 v2.1.1 | # github.com/cespare/xxhash/v2 v2.1.1 | ||||||
| github.com/cespare/xxhash/v2 | github.com/cespare/xxhash/v2 | ||||||
|  | # github.com/chi-middleware/proxy v1.1.1 | ||||||
|  | ## explicit | ||||||
|  | github.com/chi-middleware/proxy | ||||||
| # github.com/chris-ramon/douceur v0.2.0 | # github.com/chris-ramon/douceur v0.2.0 | ||||||
| github.com/chris-ramon/douceur/parser | github.com/chris-ramon/douceur/parser | ||||||
| # github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 | # github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue