Skip to content

Commit dedc833

Browse files
authored
DVO-1024: log "id" claim from CL authorization token (#19)
Engine API auth includes optional "id" claim which CL might set to its, well, id. To improve troubleshooting, log not only remote IP of the CL node, but also its "id", if set.
1 parent 5c0ab8f commit dedc833

File tree

4 files changed

+49
-16
lines changed

4 files changed

+49
-16
lines changed

cmd/jwt-tokens-service/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import (
88
"log"
99
"net/http"
1010
"os"
11+
"time"
1112

12-
"github.com/golang-jwt/jwt"
13+
"github.com/golang-jwt/jwt/v5"
1314
)
1415

1516
var (
@@ -64,7 +65,7 @@ func generateJWT(secretHex string) (string, error) {
6465
token := jwt.New(jwt.SigningMethodHS256)
6566
claims := token.Claims.(jwt.MapClaims)
6667

67-
claims["iat"] = jwt.TimeFunc().Unix()
68+
claims["iat"] = time.Now().Unix()
6869
if *clientID != "" {
6970
claims["id"] = *clientID
7071
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ require (
4141

4242
require (
4343
github.com/ethereum/go-ethereum v1.15.2
44-
github.com/golang-jwt/jwt v3.2.2+incompatible
44+
github.com/golang-jwt/jwt/v5 v5.2.2
4545
github.com/gorilla/mux v1.8.0
4646
github.com/sirupsen/logrus v1.9.3
4747
github.com/stretchr/testify v1.9.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
3434
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
3535
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
3636
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
37-
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
38-
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
37+
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
38+
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
3939
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
4040
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
4141
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=

proxy.go

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"sync"
1717
"time"
1818

19+
"github.com/golang-jwt/jwt/v5"
1920
"github.com/sirupsen/logrus"
2021
)
2122

@@ -114,6 +115,38 @@ func (p *ProxyService) StartHTTPServer() error {
114115
return err
115116
}
116117

118+
func getLogFieldsFromRequest(req *http.Request) logrus.Fields {
119+
logFields := logrus.Fields{"remoteHost": getRemoteHost(req)}
120+
121+
token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
122+
jwtID := getIDClaim(token)
123+
if jwtID != "" {
124+
logFields["clID"] = jwtID
125+
}
126+
127+
return logFields
128+
}
129+
130+
// getIDClaim extracts the "id" claim from JWT token
131+
// Ignores signatures and does not validate the token.
132+
// Returns empty string if no token, invalid token, or no "id" claim
133+
func getIDClaim(tokenStr string) string {
134+
token, _, err := jwt.NewParser().ParseUnverified(tokenStr, jwt.MapClaims{})
135+
if err != nil {
136+
return ""
137+
}
138+
139+
if claims, ok := token.Claims.(jwt.MapClaims); ok {
140+
if id, exists := claims["id"]; exists {
141+
if idStr, ok := id.(string); ok {
142+
return idStr
143+
}
144+
}
145+
}
146+
147+
return ""
148+
}
149+
117150
func (p *ProxyService) ServeHTTP(w http.ResponseWriter, req *http.Request) {
118151
// return OK for all GET requests, used for debug
119152
if req.Method == http.MethodGet {
@@ -129,15 +162,16 @@ func (p *ProxyService) ServeHTTP(w http.ResponseWriter, req *http.Request) {
129162
return
130163
}
131164

165+
log := p.log.WithFields(getLogFieldsFromRequest(req))
132166
remoteHost := getRemoteHost(req)
133-
requestJSON, err := p.checkBeaconRequest(bodyBytes, remoteHost)
167+
requestJSON, err := p.checkBeaconRequest(log, bodyBytes, remoteHost)
134168
if err != nil {
135169
w.WriteHeader(http.StatusInternalServerError)
136170
return
137171
}
138172

139173
if p.shouldFilterRequest(remoteHost, requestJSON.Method) {
140-
p.log.WithField("remoteHost", remoteHost).Debug("request filtered from beacon node proxy is not synced to")
174+
log.Debug("request filtered from beacon node proxy is not synced to")
141175
w.WriteHeader(http.StatusOK)
142176
return
143177
}
@@ -257,28 +291,28 @@ func (p *ProxyService) callProxies(req *http.Request, bodyBytes []byte) {
257291
}
258292
}
259293

260-
func (p *ProxyService) checkBeaconRequest(bodyBytes []byte, remoteHost string) (JSONRPCRequest, error) {
294+
func (p *ProxyService) checkBeaconRequest(log *logrus.Entry, bodyBytes []byte, remoteHost string) (JSONRPCRequest, error) {
261295
var requestJSON JSONRPCRequest
262296
var batchRequestJSON []JSONRPCRequest
263297
err := json.Unmarshal(bodyBytes, &requestJSON)
264298

265299
if err != nil {
266-
p.log.WithError(err).Warn("failed to decode request body json, trying to decode as batch request")
300+
log.WithError(err).Warn("failed to decode request body json, trying to decode as batch request")
267301
// may be batch request
268302
if err := json.Unmarshal(bodyBytes, &batchRequestJSON); err != nil {
269-
p.log.WithError(err).Error("failed to decode request body json as batch request")
303+
log.WithError(err).Error("failed to decode request body json as batch request")
270304
return requestJSON, err
271305
}
272306
// not interested in batch requests
273307
return requestJSON, nil
274308
}
275309

276-
p.log.WithFields(logrus.Fields{
310+
log.WithFields(logrus.Fields{
277311
"method": requestJSON.Method,
278312
"id": requestJSON.ID,
279313
}).Debug("request received from beacon node")
280314

281-
p.updateBestBeaconEntry(requestJSON, remoteHost)
315+
p.updateBestBeaconEntry(log, requestJSON, remoteHost)
282316

283317
return requestJSON, nil
284318
}
@@ -302,14 +336,12 @@ func (p *ProxyService) isFromBestBeaconEntry(remoteHost string) bool {
302336
}
303337

304338
// updates for which the proxy / beacon should sync to
305-
func (p *ProxyService) updateBestBeaconEntry(request JSONRPCRequest, requestAddr string) {
339+
func (p *ProxyService) updateBestBeaconEntry(log *logrus.Entry, request JSONRPCRequest, requestAddr string) {
306340
p.mu.Lock()
307341
defer p.mu.Unlock()
308342

309343
if p.bestBeaconEntry == nil {
310-
log.WithFields(logrus.Fields{
311-
"newAddr": requestAddr,
312-
}).Info("request received from beacon node")
344+
log.Info("request received from beacon node")
313345
p.bestBeaconEntry = &BeaconEntry{Addr: requestAddr, Timestamp: 0}
314346
}
315347

0 commit comments

Comments
 (0)