0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-12-10 00:18:33 +01:00

Merge dbae827e3520a2ec86a952b56b079504b087a5d1 into 98ef79d73a6a546241dd02959ae17f136369b604

This commit is contained in:
Lunny Xiao 2025-12-07 23:24:07 +01:00 committed by GitHub
commit 6020d4d379
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 97 additions and 44 deletions

View File

@ -0,0 +1,37 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package setting
var ReverseProxy = struct {
EnableAuth bool
EnableAuthAPI bool
EnableAutoRegister bool
EnableEmail bool
EnableFullName bool
AuthUser string
AuthEmail string
AuthFullName string
Limit int
TrustedProxies []string
}{}
func loadReverseProxyFrom(rootCfg ConfigProvider) {
serviceSec := rootCfg.Section("service")
ReverseProxy.EnableAuth = serviceSec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
ReverseProxy.EnableAuthAPI = serviceSec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION_API").MustBool()
ReverseProxy.EnableAutoRegister = serviceSec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
ReverseProxy.EnableEmail = serviceSec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
ReverseProxy.EnableFullName = serviceSec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
securitySec := rootCfg.Section("security")
ReverseProxy.AuthUser = securitySec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
ReverseProxy.AuthEmail = securitySec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL")
ReverseProxy.AuthFullName = securitySec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME")
ReverseProxy.Limit = securitySec.Key("REVERSE_PROXY_LIMIT").MustInt(1)
ReverseProxy.TrustedProxies = securitySec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",")
if len(ReverseProxy.TrustedProxies) == 0 {
ReverseProxy.TrustedProxies = []string{"127.0.0.0/8", "::1/128"}
}
}

View File

@ -21,11 +21,6 @@ var (
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 = true DisableGitHooks = true
@ -116,16 +111,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

@ -48,11 +48,6 @@ var Service = struct {
EnableNotifyMail bool EnableNotifyMail bool
EnableBasicAuth bool EnableBasicAuth bool
EnablePasskeyAuth bool EnablePasskeyAuth bool
EnableReverseProxyAuth bool
EnableReverseProxyAuthAPI bool
EnableReverseProxyAutoRegister bool
EnableReverseProxyEmail bool
EnableReverseProxyFullName bool
EnableCaptcha bool EnableCaptcha bool
RequireCaptchaForLogin bool RequireCaptchaForLogin bool
RequireExternalRegistrationCaptcha bool RequireExternalRegistrationCaptcha bool
@ -182,11 +177,6 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true) Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
Service.EnablePasswordSignInForm = sec.Key("ENABLE_PASSWORD_SIGNIN_FORM").MustBool(true) Service.EnablePasswordSignInForm = sec.Key("ENABLE_PASSWORD_SIGNIN_FORM").MustBool(true)
Service.EnablePasskeyAuth = sec.Key("ENABLE_PASSKEY_AUTHENTICATION").MustBool(true) Service.EnablePasskeyAuth = sec.Key("ENABLE_PASSKEY_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

@ -118,6 +118,7 @@ func loadCommonSettingsFrom(cfg ConfigProvider) error {
loadOAuth2From(cfg) loadOAuth2From(cfg)
loadSecurityFrom(cfg) loadSecurityFrom(cfg)
loadReverseProxyFrom(cfg)
if err := loadAttachmentFrom(cfg); err != nil { if err := loadAttachmentFrom(cfg); err != nil {
return err return err
} }

View File

@ -3345,7 +3345,18 @@ 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.reverseproxy_config = Reverse Proxy Configuration
config.reverseproxy_enable_auth = Enable Reverse Proxy Authentication
config.reverseproxy_enable_auth_api = Enable Reverse Proxy Authentication for API
config.reverseproxy_enable_auto_register = Enable Reverse Proxy Auto Registration
config.reverseproxy_enable_email = Enable Reverse Proxy Email
config.reverseproxy_enable_full_name = Enable Reverse Proxy Full Name
config.reverseproxy_auth_user = Reverse Authentication User
config.reverseproxy_auth_email = Reverse Authentication Email
config.reverseproxy_auth_full_name = Reverse Authentication Full Name
config.reverseproxy_limit = Reverse Proxy Limit
config.reverseproxy_trusted_proxies = Reverse Proxy Trusted Proxies
config.ssh_config = SSH Configuration config.ssh_config = SSH Configuration
config.ssh_enabled = Enabled config.ssh_enabled = Enabled

View File

@ -89,7 +89,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.ReverseProxy.EnableAuth {
authMethods = append(authMethods, &auth.ReverseProxy{}) authMethods = append(authMethods, &auth.ReverseProxy{})
} }
authGroup := auth.NewGroup(authMethods...) authGroup := auth.NewGroup(authMethods...)

View File

@ -379,7 +379,7 @@ func reqUsersExploreEnabled() 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.ReverseProxy.EnableAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName {
return return
} }
if !ctx.IsBasicAuth { if !ctx.IsBasicAuth {
@ -760,7 +760,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.ReverseProxy.EnableAuthAPI {
group.Add(&auth.ReverseProxy{}) group.Add(&auth.ReverseProxy{})
} }

View File

@ -28,8 +28,8 @@ func ProtocolMiddlewares() (handlers []any) {
handlers = append(handlers, ChiRoutePathHandler()) // make sure chi has correct paths handlers = append(handlers, ChiRoutePathHandler()) // make sure chi has correct paths
handlers = append(handlers, RequestContextHandler()) // prepare the context and panic recovery handlers = append(handlers, RequestContextHandler()) // prepare the context and panic recovery
if setting.ReverseProxyLimit > 0 && len(setting.ReverseProxyTrustedProxies) > 0 { if setting.ReverseProxy.Limit > 0 && len(setting.ReverseProxy.TrustedProxies) > 0 {
handlers = append(handlers, ForwardedHeadersHandler(setting.ReverseProxyLimit, setting.ReverseProxyTrustedProxies)) handlers = append(handlers, ForwardedHeadersHandler(setting.ReverseProxy.Limit, setting.ReverseProxy.TrustedProxies))
} }
if setting.IsRouteLogEnabled() { if setting.IsRouteLogEnabled() {

View File

@ -136,8 +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["ReverseProxy"] = setting.ReverseProxy
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.ReverseProxy.EnableAuth {
group.Add(&auth_service.ReverseProxy{}) // reverse-proxy should before Session, otherwise the header will be ignored if user has login group.Add(&auth_service.ReverseProxy{}) // reverse-proxy 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

@ -33,7 +33,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.ReverseProxy.AuthUser))
} }
// Name represents the name of auth method // Name represents the name of auth method
@ -68,7 +68,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.ReverseProxy.AuthEmail))
} }
// getUserFromAuthEmail extracts the username from the "setting.ReverseProxyAuthEmail" header // getUserFromAuthEmail extracts the username from the "setting.ReverseProxyAuthEmail" header
@ -79,7 +79,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.ReverseProxy.EnableEmail {
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.ReverseProxy.EnableAutoRegister
} }
// 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.ReverseProxy.EnableEmail {
webAuthEmail := req.Header.Get(setting.ReverseProxyAuthEmail) webAuthEmail := req.Header.Get(setting.ReverseProxy.AuthEmail)
if len(webAuthEmail) > 0 { if len(webAuthEmail) > 0 {
email = webAuthEmail email = webAuthEmail
} }
} }
var fullname string var fullname string
if setting.Service.EnableReverseProxyFullName { if setting.ReverseProxy.EnableFullName {
fullname = req.Header.Get(setting.ReverseProxyAuthFullName) fullname = req.Header.Get(setting.ReverseProxy.AuthFullName)
} }
user := &user_model.User{ user := &user_model.User{

View File

@ -44,11 +44,40 @@
<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>
{{if or .ReverseProxy.EnableAuth .ReverseProxy.EnableAuthAPI}}
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.config.reverseproxy_config"}}
</h4>
<div class="ui attached table segment">
<dl class="admin-dl-horizontal">
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_enable_auth"}}</dt>
<dd>{{.ReverseProxy.EnableAuth}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_enable_auth_api"}}</dt>
<dd>{{.ReverseProxy.EnableAuthAPI}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_enable_auto_register"}}</dt>
<dd>{{.ReverseProxy.EnableAutoRegister}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_enable_email"}}</dt>
<dd>{{.ReverseProxy.EnableEmail}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_enable_full_name"}}</dt>
<dd>{{.ReverseProxy.EnableFullName}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_auth_user"}}</dt>
<dd>{{.ReverseProxy.AuthUser}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_auth_email"}}</dt>
<dd>{{.ReverseProxy.AuthEmail}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_auth_full_name"}}</dt>
<dd>{{.ReverseProxy.AuthFullName}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_limit"}}</dt>
<dd>{{.ReverseProxy.Limit}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverseproxy_trusted_proxies"}}</dt>
<dd>{{.ReverseProxy.TrustedProxies}}</dd>
</dl>
</div>
{{end}}
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.config.ssh_config"}} {{ctx.Locale.Tr "admin.config.ssh_config"}}
</h4> </h4>