Skip to content

Commit 1428877

Browse files
lunnywxiaoguang6543zeripath
authored
log real ip of requests from ssh (#21216)
Partially fix #21213. This PR will get client IP address from SSH_CONNECTION env which should be the first field of that. And deliver it to the internal API so Gitea routers could record the real IP from SSH requests. Co-authored-by: wxiaoguang <[email protected]> Co-authored-by: 6543 <[email protected]> Co-authored-by: zeripath <[email protected]>
1 parent c540ee0 commit 1428877

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

modules/private/internal.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"fmt"
1111
"net"
1212
"net/http"
13+
"os"
14+
"strings"
1315

1416
"code.gitea.io/gitea/modules/httplib"
1517
"code.gitea.io/gitea/modules/json"
@@ -18,13 +20,14 @@ import (
1820
"code.gitea.io/gitea/modules/setting"
1921
)
2022

21-
func newRequest(ctx context.Context, url, method string) *httplib.Request {
23+
func newRequest(ctx context.Context, url, method, sourceIP string) *httplib.Request {
2224
if setting.InternalToken == "" {
2325
log.Fatal(`The INTERNAL_TOKEN setting is missing from the configuration file: %q.
2426
Ensure you are running in the correct environment or set the correct configuration file with -c.`, setting.CustomConf)
2527
}
2628
return httplib.NewRequest(url, method).
2729
SetContext(ctx).
30+
Header("X-Real-IP", sourceIP).
2831
Header("Authorization", fmt.Sprintf("Bearer %s", setting.InternalToken))
2932
}
3033

@@ -42,8 +45,16 @@ func decodeJSONError(resp *http.Response) *Response {
4245
return &res
4346
}
4447

48+
func getClientIP() string {
49+
sshConnEnv := strings.TrimSpace(os.Getenv("SSH_CONNECTION"))
50+
if len(sshConnEnv) == 0 {
51+
return "127.0.0.1"
52+
}
53+
return strings.Fields(sshConnEnv)[0]
54+
}
55+
4556
func newInternalRequest(ctx context.Context, url, method string) *httplib.Request {
46-
req := newRequest(ctx, url, method).SetTLSClientConfig(&tls.Config{
57+
req := newRequest(ctx, url, method, getClientIP()).SetTLSClientConfig(&tls.Config{
4758
InsecureSkipVerify: true,
4859
ServerName: setting.Domain,
4960
})

routers/private/internal.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"code.gitea.io/gitea/modules/web"
1818

1919
"gitea.com/go-chi/binding"
20+
chi_middleware "github.com/go-chi/chi/v5/middleware"
2021
)
2122

2223
// CheckInternalToken check internal token is set
@@ -57,6 +58,9 @@ func Routes() *web.Route {
5758
r := web.NewRoute()
5859
r.Use(context.PrivateContexter())
5960
r.Use(CheckInternalToken)
61+
// Log the real ip address of the request from SSH is really helpful for diagnosing sometimes.
62+
// Since internal API will be sent only from Gitea sub commands and it's under control (checked by InternalToken), we can trust the headers.
63+
r.Use(chi_middleware.RealIP)
6064

6165
r.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent)
6266
r.Post("/ssh/{id}/update/{repoid}", UpdatePublicKeyInRepo)

0 commit comments

Comments
 (0)