0
0
Fork 0
mirror of https://github.com/go-gitea/gitea synced 2024-11-25 07:02:48 +01:00

refactor reverseproxy setting

This commit is contained in:
Lunny Xiao 2024-09-26 19:23:34 -07:00
parent 3f9e360142
commit f173431b8e
No known key found for this signature in database
GPG key ID: C3B7C91B632F738A
12 changed files with 104 additions and 50 deletions

View file

@ -0,0 +1,40 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package setting
var ReverseProxyAuth = struct {
Enabled bool
EnableReverseProxyAuthAPI bool
EnableReverseProxyAutoRegister bool
EnableReverseProxyEmail bool
EnableReverseProxyFullName bool
ReverseProxyAuthUser string
ReverseProxyAuthEmail string
ReverseProxyAuthFullName string
ReverseProxyLimit int
ReverseProxyTrustedProxies []string
}{}
func loadReverseProxyAuthFrom(rootCfg ConfigProvider) error {
serviceSec := rootCfg.Section("service")
ReverseProxyAuth.Enabled = serviceSec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
ReverseProxyAuth.EnableReverseProxyAuthAPI = serviceSec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION_API").MustBool()
ReverseProxyAuth.EnableReverseProxyAutoRegister = serviceSec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
ReverseProxyAuth.EnableReverseProxyEmail = serviceSec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
ReverseProxyAuth.EnableReverseProxyFullName = serviceSec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
securitySec := rootCfg.Section("security")
ReverseProxyAuth.ReverseProxyAuthUser = securitySec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
ReverseProxyAuth.ReverseProxyAuthEmail = securitySec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL")
ReverseProxyAuth.ReverseProxyAuthFullName = securitySec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME")
ReverseProxyAuth.ReverseProxyLimit = securitySec.Key("REVERSE_PROXY_LIMIT").MustInt(1)
ReverseProxyAuth.ReverseProxyTrustedProxies = securitySec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",")
if len(ReverseProxyAuth.ReverseProxyTrustedProxies) == 0 {
ReverseProxyAuth.ReverseProxyTrustedProxies = []string{"127.0.0.0/8", "::1/128"}
}
return nil
}

View file

@ -15,16 +15,12 @@ import (
var ( var (
// Security settings // Security settings
InstallLock bool InstallLock bool
SecretKey string SecretKey string
InternalToken string // internal access token InternalToken string // internal access token
LogInRememberDays int LogInRememberDays int
CookieRememberName string CookieRememberName string
ReverseProxyAuthUser string
ReverseProxyAuthEmail string
ReverseProxyAuthFullName string
ReverseProxyLimit int
ReverseProxyTrustedProxies []string
MinPasswordLength int MinPasswordLength int
ImportLocalPaths bool ImportLocalPaths bool
DisableGitHooks bool DisableGitHooks bool
@ -114,16 +110,6 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
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")
ReverseProxyAuthEmail = sec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL")
ReverseProxyAuthFullName = sec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME")
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(8) MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(8)
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)

View file

@ -45,11 +45,6 @@ var Service = struct {
RequireSignInView bool RequireSignInView bool
EnableNotifyMail bool EnableNotifyMail bool
EnableBasicAuth bool EnableBasicAuth bool
EnableReverseProxyAuth bool
EnableReverseProxyAuthAPI bool
EnableReverseProxyAutoRegister bool
EnableReverseProxyEmail bool
EnableReverseProxyFullName bool
EnableCaptcha bool EnableCaptcha bool
RequireCaptchaForLogin bool RequireCaptchaForLogin bool
RequireExternalRegistrationCaptcha bool RequireExternalRegistrationCaptcha bool
@ -157,11 +152,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true) Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true) Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
Service.EnableReverseProxyAuthAPI = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION_API").MustBool()
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
Service.EnableReverseProxyFullName = sec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false) Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false)
Service.RequireCaptchaForLogin = sec.Key("REQUIRE_CAPTCHA_FOR_LOGIN").MustBool(false) Service.RequireCaptchaForLogin = sec.Key("REQUIRE_CAPTCHA_FOR_LOGIN").MustBool(false)
Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha) Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha)

View file

@ -203,6 +203,7 @@ func LoadSettings() {
loadDBSetting(CfgProvider) loadDBSetting(CfgProvider)
loadServiceFrom(CfgProvider) loadServiceFrom(CfgProvider)
loadReverseProxyAuthFrom(CfgProvider)
loadOAuth2ClientFrom(CfgProvider) loadOAuth2ClientFrom(CfgProvider)
loadCacheFrom(CfgProvider) loadCacheFrom(CfgProvider)
loadSessionFrom(CfgProvider) loadSessionFrom(CfgProvider)
@ -223,6 +224,7 @@ func LoadSettings() {
func LoadSettingsForInstall() { func LoadSettingsForInstall() {
loadDBSetting(CfgProvider) loadDBSetting(CfgProvider)
loadServiceFrom(CfgProvider) loadServiceFrom(CfgProvider)
loadReverseProxyAuthFrom(CfgProvider)
loadMailerFrom(CfgProvider) loadMailerFrom(CfgProvider)
} }

View file

@ -3194,7 +3194,16 @@ config.repo_root_path = Repository Root Path
config.lfs_root_path = LFS Root Path config.lfs_root_path = LFS Root Path
config.log_file_root_path = Log Path config.log_file_root_path = Log Path
config.script_type = Script Type config.script_type = Script Type
config.reverse_auth_user = Reverse Authentication User config.reverse_proxy_auth_config = Reverse Proxy Authentication Configuration
config.reverse_proxy_auth_user = Authentication User
config.reverse_proxy_auth_email = Authentication Email
config.reverse_proxy_auth_fullname = Authentication Fullname
config.reverse_proxy_auth_limit = Authentication Limit
config.reverse_proxy_auth_trusted_proxies = Authentication Trusted Proxies
config.reverse_proxy_auth_enable_api = Enable Authentication API
config.reverse_proxy_auth_enable_autoregister = Enable Authentication Auto Register
config.reverse_proxy_auth_enable_email = Enable Authentication Email
config.reverse_proxy_auth_enable_fullname = Enable Authentication Fullname
config.ssh_config = SSH Configuration config.ssh_config = SSH Configuration
config.ssh_enabled = Enabled config.ssh_enabled = Enabled

View file

@ -75,7 +75,7 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
} }
func verifyAuth(r *web.Router, authMethods []auth.Method) { func verifyAuth(r *web.Router, authMethods []auth.Method) {
if setting.Service.EnableReverseProxyAuth { if setting.ReverseProxyAuth.Enabled {
authMethods = append(authMethods, &auth.ReverseProxy{}) authMethods = append(authMethods, &auth.ReverseProxy{})
} }
authGroup := auth.NewGroup(authMethods...) authGroup := auth.NewGroup(authMethods...)

View file

@ -331,7 +331,7 @@ func reqExploreSignIn() func(ctx *context.APIContext) {
func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) {
return func(ctx *context.APIContext) { return func(ctx *context.APIContext) {
if ctx.IsSigned && setting.Service.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName { if ctx.IsSigned && setting.ReverseProxyAuth.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName {
return return
} }
if !ctx.IsBasicAuth { if !ctx.IsBasicAuth {
@ -700,7 +700,7 @@ func buildAuthGroup() *auth.Group {
&auth.HTTPSign{}, &auth.HTTPSign{},
&auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API &auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API
) )
if setting.Service.EnableReverseProxyAuthAPI { if setting.ReverseProxyAuth.EnableReverseProxyAuthAPI {
group.Add(&auth.ReverseProxy{}) group.Add(&auth.ReverseProxy{})
} }

View file

@ -60,11 +60,11 @@ func ProtocolMiddlewares() (handlers []any) {
}) })
}) })
if setting.ReverseProxyLimit > 0 { if setting.ReverseProxyAuth.ReverseProxyLimit > 0 {
opt := proxy.NewForwardedHeadersOptions(). opt := proxy.NewForwardedHeadersOptions().
WithForwardLimit(setting.ReverseProxyLimit). WithForwardLimit(setting.ReverseProxyAuth.ReverseProxyLimit).
ClearTrustedProxies() ClearTrustedProxies()
for _, n := range setting.ReverseProxyTrustedProxies { for _, n := range setting.ReverseProxyAuth.ReverseProxyTrustedProxies {
if !strings.Contains(n, "/") { if !strings.Contains(n, "/") {
opt.AddTrustedProxy(n) opt.AddTrustedProxy(n)
} else { } else {

View file

@ -136,9 +136,8 @@ func Config(ctx *context.Context) {
ctx.Data["CustomRootPath"] = setting.CustomPath ctx.Data["CustomRootPath"] = setting.CustomPath
ctx.Data["LogRootPath"] = setting.Log.RootPath ctx.Data["LogRootPath"] = setting.Log.RootPath
ctx.Data["ScriptType"] = setting.ScriptType ctx.Data["ScriptType"] = setting.ScriptType
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
ctx.Data["ReverseProxyAuthEmail"] = setting.ReverseProxyAuthEmail
ctx.Data["ReverseProxyAuth"] = setting.ReverseProxyAuth
ctx.Data["SSH"] = setting.SSH ctx.Data["SSH"] = setting.SSH
ctx.Data["LFS"] = setting.LFS ctx.Data["LFS"] = setting.LFS

View file

@ -102,7 +102,7 @@ func buildAuthGroup() *auth_service.Group {
group.Add(&auth_service.OAuth2{}) // FIXME: this should be removed and only applied in download and oauth related routers group.Add(&auth_service.OAuth2{}) // FIXME: this should be removed and only applied in download and oauth related routers
group.Add(&auth_service.Basic{}) // FIXME: this should be removed and only applied in download and git/lfs routers group.Add(&auth_service.Basic{}) // FIXME: this should be removed and only applied in download and git/lfs routers
if setting.Service.EnableReverseProxyAuth { if setting.ReverseProxyAuth.Enabled {
group.Add(&auth_service.ReverseProxy{}) // reverseproxy should before Session, otherwise the header will be ignored if user has login group.Add(&auth_service.ReverseProxy{}) // reverseproxy should before Session, otherwise the header will be ignored if user has login
} }
group.Add(&auth_service.Session{}) group.Add(&auth_service.Session{})

View file

@ -34,7 +34,7 @@ type ReverseProxy struct{}
// getUserName extracts the username from the "setting.ReverseProxyAuthUser" header // getUserName extracts the username from the "setting.ReverseProxyAuthUser" header
func (r *ReverseProxy) getUserName(req *http.Request) string { func (r *ReverseProxy) getUserName(req *http.Request) string {
return strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuthUser)) return strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuth.ReverseProxyAuthUser))
} }
// Name represents the name of auth method // Name represents the name of auth method
@ -69,7 +69,7 @@ func (r *ReverseProxy) getUserFromAuthUser(req *http.Request) (*user_model.User,
// getEmail extracts the email from the "setting.ReverseProxyAuthEmail" header // getEmail extracts the email from the "setting.ReverseProxyAuthEmail" header
func (r *ReverseProxy) getEmail(req *http.Request) string { func (r *ReverseProxy) getEmail(req *http.Request) string {
return strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuthEmail)) return strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuth.ReverseProxyAuthEmail))
} }
// getUserFromAuthEmail extracts the username from the "setting.ReverseProxyAuthEmail" header // getUserFromAuthEmail extracts the username from the "setting.ReverseProxyAuthEmail" header
@ -80,7 +80,7 @@ func (r *ReverseProxy) getEmail(req *http.Request) string {
// user object is returned (populated with the email found in header). // user object is returned (populated with the email found in header).
// Returns nil if header is empty or if "setting.EnableReverseProxyEmail" is disabled. // Returns nil if header is empty or if "setting.EnableReverseProxyEmail" is disabled.
func (r *ReverseProxy) getUserFromAuthEmail(req *http.Request) *user_model.User { func (r *ReverseProxy) getUserFromAuthEmail(req *http.Request) *user_model.User {
if !setting.Service.EnableReverseProxyEmail { if !setting.ReverseProxyAuth.EnableReverseProxyEmail {
return nil return nil
} }
email := r.getEmail(req) email := r.getEmail(req)
@ -130,7 +130,7 @@ func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store Da
// isAutoRegisterAllowed checks if EnableReverseProxyAutoRegister setting is true // isAutoRegisterAllowed checks if EnableReverseProxyAutoRegister setting is true
func (r *ReverseProxy) isAutoRegisterAllowed() bool { func (r *ReverseProxy) isAutoRegisterAllowed() bool {
return setting.Service.EnableReverseProxyAutoRegister return setting.ReverseProxyAuth.EnableReverseProxyAutoRegister
} }
// newUser creates a new user object for the purpose of automatic registration // newUser creates a new user object for the purpose of automatic registration
@ -142,16 +142,16 @@ func (r *ReverseProxy) newUser(req *http.Request) *user_model.User {
} }
email := gouuid.New().String() + "@localhost" email := gouuid.New().String() + "@localhost"
if setting.Service.EnableReverseProxyEmail { if setting.ReverseProxyAuth.EnableReverseProxyEmail {
webAuthEmail := req.Header.Get(setting.ReverseProxyAuthEmail) webAuthEmail := req.Header.Get(setting.ReverseProxyAuth.ReverseProxyAuthEmail)
if len(webAuthEmail) > 0 { if len(webAuthEmail) > 0 {
email = webAuthEmail email = webAuthEmail
} }
} }
var fullname string var fullname string
if setting.Service.EnableReverseProxyFullName { if setting.ReverseProxyAuth.EnableReverseProxyFullName {
fullname = req.Header.Get(setting.ReverseProxyAuthFullName) fullname = req.Header.Get(setting.ReverseProxyAuth.ReverseProxyAuthFullName)
} }
user := &user_model.User{ user := &user_model.User{

View file

@ -44,8 +44,6 @@
<dd>{{.LogRootPath}}</dd> <dd>{{.LogRootPath}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.script_type"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.script_type"}}</dt>
<dd>{{.ScriptType}}</dd> <dd>{{.ScriptType}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_auth_user"}}</dt>
<dd>{{.ReverseProxyAuthUser}}</dd>
</dl> </dl>
</div> </div>
@ -180,6 +178,35 @@
</dl> </dl>
</div> </div>
{{if .ReverseProxyAuth.Enabled}}
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_config"}}
</h4>
<div class="ui attached table segment">
<dl class="admin-dl-horizontal">
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_enable_autoregister"}}</dt>
<dd>{{.ReverseProxyAuth.EnableReverseProxyAutoRegister}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_auth_user"}}</dt>
<dd>{{.ReverseProxyAuth.ReverseProxyAuthUser}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_enable_email"}}</dt>
<dd>{{.ReverseProxyAuth.EnableReverseProxyEmail}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_email"}}</dt>
<dd>{{.ReverseProxyAuth.ReverseProxyAuthEmail}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_enable_fullname"}}</dt>
<dd>{{.ReverseProxyAuth.EnableReverseProxyFullName}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_fullname"}}</dt>
<dd>{{.ReverseProxyAuth.ReverseProxyAuthFullName}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_enable_api"}}</dt>
<dd>{{.ReverseProxyAuth.EnableReverseProxyAuthAPI}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_limit"}}</dt>
<dd>{{.ReverseProxyAuth.ReverseProxyLimit}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_proxy_auth_trusted_proxies"}}</dt>
<dd>{{.ReverseProxyAuth.ReverseProxyTrustedProxies}}</dd>
</dl>
</div>
{{end}}
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.config.webhook_config"}} {{ctx.Locale.Tr "admin.config.webhook_config"}}
</h4> </h4>