Skip to content

Commit

Permalink
sevices/friendbot: Allow friendbot to include cloudflare derived IP a…
Browse files Browse the repository at this point in the history
…ddress in request logs (#5359)
  • Loading branch information
tamirms authored Jun 28, 2024
1 parent 27a3c2a commit 01dc176
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
17 changes: 14 additions & 3 deletions services/friendbot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/go-chi/chi"
"github.com/spf13/cobra"

"github.com/stellar/go/services/friendbot/internal"
"github.com/stellar/go/support/app"
"github.com/stellar/go/support/config"
Expand All @@ -29,6 +30,7 @@ type Config struct {
BaseFee int64 `toml:"base_fee" valid:"optional"`
MinionBatchSize int `toml:"minion_batch_size" valid:"optional"`
SubmitTxRetriesAllowed int `toml:"submit_tx_retries_allowed" valid:"optional"`
UseCloudflareIP bool `toml:"use_cloudflare_ip" valid:"optional"`
}

func main() {
Expand Down Expand Up @@ -68,7 +70,7 @@ func run(cmd *cobra.Command, args []string) {
log.Error(err)
os.Exit(1)
}
router := initRouter(fb)
router := initRouter(cfg, fb)
registerProblems()

addr := fmt.Sprintf("0.0.0.0:%d", cfg.Port)
Expand All @@ -84,8 +86,8 @@ func run(cmd *cobra.Command, args []string) {
})
}

func initRouter(fb *internal.Bot) *chi.Mux {
mux := http.NewAPIMux(log.DefaultLogger)
func initRouter(cfg Config, fb *internal.Bot) *chi.Mux {
mux := newMux(cfg)

handler := &internal.FriendbotHandler{Friendbot: fb}
mux.Get("/", handler.Handle)
Expand All @@ -97,6 +99,15 @@ func initRouter(fb *internal.Bot) *chi.Mux {
return mux
}

func newMux(cfg Config) *chi.Mux {
mux := chi.NewRouter()
// first apply XFFMiddleware so we can have the real ip in the subsequent
// middlewares
mux.Use(http.XFFMiddleware(http.XFFMiddlewareConfig{BehindCloudflare: cfg.UseCloudflareIP}))
mux.Use(http.NewAPIMux(log.DefaultLogger).Middlewares()...)
return mux
}

func registerProblems() {
problem.RegisterError(sql.ErrNoRows, problem.NotFound)

Expand Down
33 changes: 33 additions & 0 deletions services/friendbot/router_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/require"

"github.com/stellar/go/support/log"
)

func TestIPLogging(t *testing.T) {
done := log.DefaultLogger.StartTest(log.InfoLevel)

mux := newMux(Config{UseCloudflareIP: true})
mux.Get("/", func(w http.ResponseWriter, request *http.Request) {
w.WriteHeader(http.StatusOK)
})
recorder := httptest.NewRecorder()
request := httptest.NewRequest("GET", "/", nil)
ipAddress := "255.128.255.128"
request.Header.Set("CF-Connecting-IP", ipAddress)
mux.ServeHTTP(recorder, request)
require.Equal(t, http.StatusOK, recorder.Code)

logged := done()
require.Len(t, logged, 2)
require.Equal(t, "starting request", logged[0].Message)
require.Equal(t, ipAddress, logged[0].Data["ip"])
require.Equal(t, "finished request", logged[1].Message)
require.Equal(t, ipAddress, logged[1].Data["ip"])
}
2 changes: 2 additions & 0 deletions support/http/logging_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"

"github.com/stellar/go/support/http/mutil"
"github.com/stellar/go/support/log"
)
Expand Down Expand Up @@ -136,6 +137,7 @@ func logEndOfRequest(
"subsys": "http",
"path": r.URL.String(),
"method": r.Method,
"ip": r.RemoteAddr,
"status": mw.Status(),
"bytes": mw.BytesWritten(),
"duration": duration,
Expand Down
9 changes: 5 additions & 4 deletions support/http/logging_middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (

"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/stretchr/testify/assert"

"github.com/stellar/go/support/http/httptest"
"github.com/stellar/go/support/log"
"github.com/stretchr/testify/assert"
)

// setXFFMiddleware sets "X-Forwarded-For" header to test LoggingMiddlewareWithOptions.
Expand Down Expand Up @@ -143,7 +144,7 @@ func TestHTTPMiddlewareWithOptions(t *testing.T) {
assert.Equal(t, req1, logged[2].Data["req"])
assert.Equal(t, "/path/1234", logged[2].Data["path"])
assert.Equal(t, "/path/{value}", logged[2].Data["route"])
assert.Equal(t, 9, len(logged[2].Data))
assert.Equal(t, 10, len(logged[2].Data))

assert.Equal(t, "starting request", logged[3].Message)
assert.Equal(t, "http", logged[3].Data["subsys"])
Expand All @@ -162,7 +163,7 @@ func TestHTTPMiddlewareWithOptions(t *testing.T) {
assert.Equal(t, req2, logged[4].Data["req"])
assert.Equal(t, "/not_found", logged[4].Data["path"])
assert.Equal(t, "/not_found", logged[4].Data["route"])
assert.Equal(t, 9, len(logged[4].Data))
assert.Equal(t, 10, len(logged[4].Data))

assert.Equal(t, "starting request", logged[5].Message)
assert.Equal(t, "http", logged[5].Data["subsys"])
Expand All @@ -181,7 +182,7 @@ func TestHTTPMiddlewareWithOptions(t *testing.T) {
assert.Equal(t, req3, logged[6].Data["req"])
assert.Equal(t, "/really_not_found", logged[6].Data["path"])
assert.Equal(t, "", logged[6].Data["route"])
assert.Equal(t, 9, len(logged[6].Data))
assert.Equal(t, 10, len(logged[6].Data))
}
}

Expand Down
1 change: 1 addition & 0 deletions support/http/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/rs/cors"

"github.com/stellar/go/support/log"
)

Expand Down

0 comments on commit 01dc176

Please sign in to comment.