From befb2ffada75e6b63414c53b95956543a8b0a877 Mon Sep 17 00:00:00 2001 From: Lunny Xiao <xiaolunwen@gmail.com> Date: Tue, 20 Sep 2022 09:02:00 +0800 Subject: [PATCH 1/4] log real ip of requests from ssh --- modules/private/internal.go | 15 +++++++++++++-- routers/init.go | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/private/internal.go b/modules/private/internal.go index 2ea516ba80e19..21e5c9a27999b 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -10,6 +10,8 @@ import ( "fmt" "net" "net/http" + "os" + "strings" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/json" @@ -18,13 +20,14 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func newRequest(ctx context.Context, url, method string) *httplib.Request { +func newRequest(ctx context.Context, url, method, sourceIP string) *httplib.Request { if setting.InternalToken == "" { log.Fatal(`The INTERNAL_TOKEN setting is missing from the configuration file: %q. Ensure you are running in the correct environment or set the correct configuration file with -c.`, setting.CustomConf) } return httplib.NewRequest(url, method). SetContext(ctx). + Header("X-Real-IP", sourceIP). Header("Authorization", fmt.Sprintf("Bearer %s", setting.InternalToken)) } @@ -42,8 +45,16 @@ func decodeJSONError(resp *http.Response) *Response { return &res } +func getClientIP() string { + sshConnEnv := strings.TrimSpace(os.Getenv("SSH_CONNECTION")) + if len(sshConnEnv) == 0 { + return "127.0.0.1" + } + return strings.Fields(sshConnEnv)[0] +} + func newInternalRequest(ctx context.Context, url, method string) *httplib.Request { - req := newRequest(ctx, url, method).SetTLSClientConfig(&tls.Config{ + req := newRequest(ctx, url, method, getClientIP()).SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true, ServerName: setting.Domain, }) diff --git a/routers/init.go b/routers/init.go index 85a38899e34f0..aac350aaedf70 100644 --- a/routers/init.go +++ b/routers/init.go @@ -48,6 +48,8 @@ import ( "code.gitea.io/gitea/services/repository/archiver" "code.gitea.io/gitea/services/task" "code.gitea.io/gitea/services/webhook" + + chi_middleware "github.com/go-chi/chi/v5/middleware" ) func mustInit(fn func() error) { @@ -167,6 +169,7 @@ func GlobalInitInstalled(ctx context.Context) { func NormalRoutes(ctx context.Context) *web.Route { ctx, _ = templates.HTMLRenderer(ctx) r := web.NewRoute() + r.Use(chi_middleware.RealIP) for _, middle := range common.Middlewares() { r.Use(middle) } From 06bac0dfd7a9e5c4d67d9107aae516dd801d584e Mon Sep 17 00:00:00 2001 From: Lunny Xiao <xiaolunwen@gmail.com> Date: Tue, 20 Sep 2022 10:44:58 +0800 Subject: [PATCH 2/4] Only internal API accept realIP because the ip get from ssh server side --- routers/init.go | 3 --- routers/private/internal.go | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/routers/init.go b/routers/init.go index aac350aaedf70..85a38899e34f0 100644 --- a/routers/init.go +++ b/routers/init.go @@ -48,8 +48,6 @@ import ( "code.gitea.io/gitea/services/repository/archiver" "code.gitea.io/gitea/services/task" "code.gitea.io/gitea/services/webhook" - - chi_middleware "github.com/go-chi/chi/v5/middleware" ) func mustInit(fn func() error) { @@ -169,7 +167,6 @@ func GlobalInitInstalled(ctx context.Context) { func NormalRoutes(ctx context.Context) *web.Route { ctx, _ = templates.HTMLRenderer(ctx) r := web.NewRoute() - r.Use(chi_middleware.RealIP) for _, middle := range common.Middlewares() { r.Use(middle) } diff --git a/routers/private/internal.go b/routers/private/internal.go index 061c7f3c822af..1075fe24cdf34 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/web" "gitea.com/go-chi/binding" + chi_middleware "github.com/go-chi/chi/v5/middleware" ) // CheckInternalToken check internal token is set @@ -50,6 +51,7 @@ func bind(obj interface{}) http.HandlerFunc { // These APIs will be invoked by internal commands for example `gitea serv` and etc. func Routes() *web.Route { r := web.NewRoute() + r.Use(chi_middleware.RealIP) r.Use(context.PrivateContexter()) r.Use(CheckInternalToken) From fd9f2b0de2dbfbeb37632d95bdaa567020d011f9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao <xiaolunwen@gmail.com> Date: Tue, 20 Sep 2022 10:56:29 +0800 Subject: [PATCH 3/4] Add comment --- routers/private/internal.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routers/private/internal.go b/routers/private/internal.go index 1075fe24cdf34..c82ae1ec0f0ca 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -51,9 +51,11 @@ func bind(obj interface{}) http.HandlerFunc { // These APIs will be invoked by internal commands for example `gitea serv` and etc. func Routes() *web.Route { r := web.NewRoute() - r.Use(chi_middleware.RealIP) r.Use(context.PrivateContexter()) r.Use(CheckInternalToken) + // Log the real ip address of the request from SSH is really helpful for diagnosing sometimes. + // Since internal API will be sent only from Gitea sub commands and it's under controll, we can trust the headers. + r.Use(chi_middleware.RealIP) r.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent) r.Post("/ssh/{id}/update/{repoid}", UpdatePublicKeyInRepo) From af36fe96948fdf83f1ac7ff74de549c5bf4cb04c Mon Sep 17 00:00:00 2001 From: wxiaoguang <wxiaoguang@gmail.com> Date: Tue, 20 Sep 2022 11:03:11 +0800 Subject: [PATCH 4/4] fix spelling error --- routers/private/internal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/private/internal.go b/routers/private/internal.go index c82ae1ec0f0ca..e23cce3ef6052 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -54,7 +54,7 @@ func Routes() *web.Route { r.Use(context.PrivateContexter()) r.Use(CheckInternalToken) // Log the real ip address of the request from SSH is really helpful for diagnosing sometimes. - // Since internal API will be sent only from Gitea sub commands and it's under controll, we can trust the headers. + // Since internal API will be sent only from Gitea sub commands and it's under control (checked by InternalToken), we can trust the headers. r.Use(chi_middleware.RealIP) r.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent)