Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions modules/setting/reverseproxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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) {
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"}
}
}
26 changes: 6 additions & 20 deletions modules/setting/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,12 @@ import (

var (
// Security settings
InstallLock bool
SecretKey string
InternalToken string // internal access token
LogInRememberDays int
CookieRememberName string
ReverseProxyAuthUser string
ReverseProxyAuthEmail string
ReverseProxyAuthFullName string
ReverseProxyLimit int
ReverseProxyTrustedProxies []string
InstallLock bool
SecretKey string
InternalToken string // internal access token
LogInRememberDays int
CookieRememberName string

MinPasswordLength int
ImportLocalPaths bool
DisableGitHooks bool
Expand Down Expand Up @@ -114,16 +110,6 @@ func loadSecurityFrom(rootCfg ConfigProvider) {

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)
ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false)
DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(true)
Expand Down
11 changes: 1 addition & 10 deletions modules/setting/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ var Service = struct {
RequireSignInView bool
EnableNotifyMail bool
EnableBasicAuth bool
EnableReverseProxyAuth bool
EnableReverseProxyAuthAPI bool
EnableReverseProxyAutoRegister bool
EnableReverseProxyEmail bool
EnableReverseProxyFullName bool
EnableCaptcha bool
RequireCaptchaForLogin bool
RequireExternalRegistrationCaptcha bool
Expand Down Expand Up @@ -157,11 +152,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
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.RequireCaptchaForLogin = sec.Key("REQUIRE_CAPTCHA_FOR_LOGIN").MustBool(false)
Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha)
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ func LoadSettings() {

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

Expand Down
11 changes: 10 additions & 1 deletion options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3194,7 +3194,16 @@ config.repo_root_path = Repository Root Path
config.lfs_root_path = LFS Root Path
config.log_file_root_path = Log Path
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_enabled = Enabled
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
}

func verifyAuth(r *web.Router, authMethods []auth.Method) {
if setting.Service.EnableReverseProxyAuth {
if setting.ReverseProxyAuth.Enabled {
authMethods = append(authMethods, &auth.ReverseProxy{})
}
authGroup := auth.NewGroup(authMethods...)
Expand Down
4 changes: 2 additions & 2 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ func reqExploreSignIn() func(ctx *context.APIContext) {

func reqBasicOrRevProxyAuth() 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
}
if !ctx.IsBasicAuth {
Expand Down Expand Up @@ -700,7 +700,7 @@ func buildAuthGroup() *auth.Group {
&auth.HTTPSign{},
&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{})
}

Expand Down
6 changes: 3 additions & 3 deletions routers/common/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ func ProtocolMiddlewares() (handlers []any) {
})
})

if setting.ReverseProxyLimit > 0 {
if setting.ReverseProxyAuth.ReverseProxyLimit > 0 {
opt := proxy.NewForwardedHeadersOptions().
WithForwardLimit(setting.ReverseProxyLimit).
WithForwardLimit(setting.ReverseProxyAuth.ReverseProxyLimit).
ClearTrustedProxies()
for _, n := range setting.ReverseProxyTrustedProxies {
for _, n := range setting.ReverseProxyAuth.ReverseProxyTrustedProxies {
if !strings.Contains(n, "/") {
opt.AddTrustedProxy(n)
} else {
Expand Down
3 changes: 1 addition & 2 deletions routers/web/admin/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,8 @@ func Config(ctx *context.Context) {
ctx.Data["CustomRootPath"] = setting.CustomPath
ctx.Data["LogRootPath"] = setting.Log.RootPath
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["LFS"] = setting.LFS

Expand Down
2 changes: 1 addition & 1 deletion routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.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.Session{})
Expand Down
16 changes: 8 additions & 8 deletions services/auth/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type ReverseProxy struct{}

// getUserName extracts the username from the "setting.ReverseProxyAuthUser" header
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
Expand Down Expand Up @@ -69,7 +69,7 @@ func (r *ReverseProxy) getUserFromAuthUser(req *http.Request) (*user_model.User,

// getEmail extracts the email from the "setting.ReverseProxyAuthEmail" header
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
Expand All @@ -80,7 +80,7 @@ func (r *ReverseProxy) getEmail(req *http.Request) string {
// user object is returned (populated with the email found in header).
// Returns nil if header is empty or if "setting.EnableReverseProxyEmail" is disabled.
func (r *ReverseProxy) getUserFromAuthEmail(req *http.Request) *user_model.User {
if !setting.Service.EnableReverseProxyEmail {
if !setting.ReverseProxyAuth.EnableReverseProxyEmail {
return nil
}
email := r.getEmail(req)
Expand Down Expand Up @@ -130,7 +130,7 @@ func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store Da

// isAutoRegisterAllowed checks if EnableReverseProxyAutoRegister setting is true
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
Expand All @@ -142,16 +142,16 @@ func (r *ReverseProxy) newUser(req *http.Request) *user_model.User {
}

email := gouuid.New().String() + "@localhost"
if setting.Service.EnableReverseProxyEmail {
webAuthEmail := req.Header.Get(setting.ReverseProxyAuthEmail)
if setting.ReverseProxyAuth.EnableReverseProxyEmail {
webAuthEmail := req.Header.Get(setting.ReverseProxyAuth.ReverseProxyAuthEmail)
if len(webAuthEmail) > 0 {
email = webAuthEmail
}
}

var fullname string
if setting.Service.EnableReverseProxyFullName {
fullname = req.Header.Get(setting.ReverseProxyAuthFullName)
if setting.ReverseProxyAuth.EnableReverseProxyFullName {
fullname = req.Header.Get(setting.ReverseProxyAuth.ReverseProxyAuthFullName)
}

user := &user_model.User{
Expand Down
31 changes: 29 additions & 2 deletions templates/admin/config.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@
<dd>{{.LogRootPath}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.script_type"}}</dt>
<dd>{{.ScriptType}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.reverse_auth_user"}}</dt>
<dd>{{.ReverseProxyAuthUser}}</dd>
</dl>
</div>

Expand Down Expand Up @@ -180,6 +178,35 @@
</dl>
</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">
{{ctx.Locale.Tr "admin.config.webhook_config"}}
</h4>
Expand Down
Loading