Skip to content

Commit e3e3599

Browse files
vadmesteAnis Eleuch
andauthored
ws: Calculate the client IP from the WS request headers as well (#3403)
Currently, the websocket code adds an IP to X-Forwarded-For where the IP is calculated from the TCP connection established to Console, however the established TCP connection can be coming from the load balancer as well, hence the necesssity to evaluate the client IP based on X-Forwarded-For or X-Real-IP headers Look for client IPs in the websocket request connection. Co-authored-by: Anis Eleuch <anis@min.io>
1 parent aa74e31 commit e3e3599

File tree

1 file changed

+20
-24
lines changed

1 file changed

+20
-24
lines changed

api/ws_handle.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,19 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
177177
return
178178
}
179179

180+
clientIP := getSourceIPFromHeaders(req)
181+
if clientIP == "" {
182+
if ip, _, err := net.SplitHostPort(conn.RemoteAddr().String()); err == nil {
183+
clientIP = ip
184+
} else {
185+
// In case there's an error, return an empty string
186+
LogError("Invalid ws.RemoteAddr() = %v\n", err)
187+
}
188+
}
189+
180190
switch {
181191
case strings.HasPrefix(wsPath, `/trace`):
182-
wsAdminClient, err := newWebSocketAdminClient(conn, session)
192+
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
183193
if err != nil {
184194
ErrorWithContext(ctx, err)
185195
closeWsConn(conn)
@@ -216,7 +226,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
216226
go wsAdminClient.trace(ctx, traceRequestItem)
217227
case strings.HasPrefix(wsPath, `/console`):
218228

219-
wsAdminClient, err := newWebSocketAdminClient(conn, session)
229+
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
220230
if err != nil {
221231
ErrorWithContext(ctx, err)
222232
closeWsConn(conn)
@@ -237,7 +247,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
237247
closeWsConn(conn)
238248
return
239249
}
240-
wsAdminClient, err := newWebSocketAdminClient(conn, session)
250+
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
241251
if err != nil {
242252
ErrorWithContext(ctx, err)
243253
closeWsConn(conn)
@@ -251,7 +261,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
251261
closeWsConn(conn)
252262
return
253263
}
254-
wsS3Client, err := newWebSocketS3Client(conn, session, wOptions.BucketName, "")
264+
wsS3Client, err := newWebSocketS3Client(conn, session, wOptions.BucketName, "", clientIP)
255265
if err != nil {
256266
ErrorWithContext(ctx, err)
257267
closeWsConn(conn)
@@ -265,7 +275,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
265275
closeWsConn(conn)
266276
return
267277
}
268-
wsAdminClient, err := newWebSocketAdminClient(conn, session)
278+
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
269279
if err != nil {
270280
ErrorWithContext(ctx, err)
271281
closeWsConn(conn)
@@ -279,7 +289,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
279289
closeWsConn(conn)
280290
return
281291
}
282-
wsAdminClient, err := newWebSocketAdminClient(conn, session)
292+
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
283293
if err != nil {
284294
ErrorWithContext(ctx, err)
285295
closeWsConn(conn)
@@ -288,7 +298,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
288298
go wsAdminClient.profile(ctx, pOptions)
289299

290300
case strings.HasPrefix(wsPath, `/objectManager`):
291-
wsMinioClient, err := newWebSocketMinioClient(conn, session)
301+
wsMinioClient, err := newWebSocketMinioClient(conn, session, clientIP)
292302
if err != nil {
293303
ErrorWithContext(ctx, err)
294304
closeWsConn(conn)
@@ -303,12 +313,11 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
303313
}
304314

305315
// newWebSocketAdminClient returns a wsAdminClient authenticated as an admin user
306-
func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal) (*wsAdminClient, error) {
316+
func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal, clientIP string) (*wsAdminClient, error) {
307317
// create a websocket connection interface implementation
308318
// defining the connection to be used
309319
wsConnection := wsConn{conn: conn}
310320

311-
clientIP := wsConnection.remoteAddress()
312321
// Only start Websocket Interaction after user has been
313322
// authenticated with MinIO
314323
mAdmin, err := newAdminFromClaims(autClaims, clientIP)
@@ -326,15 +335,9 @@ func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal)
326335
}
327336

328337
// newWebSocketS3Client returns a wsAdminClient authenticated as Console admin
329-
func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucketName, prefix string) (*wsS3Client, error) {
338+
func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucketName, prefix, clientIP string) (*wsS3Client, error) {
330339
// Only start Websocket Interaction after user has been
331340
// authenticated with MinIO
332-
clientIP, _, err := net.SplitHostPort(conn.RemoteAddr().String())
333-
if err != nil {
334-
// In case there's an error, return an empty string
335-
log.Printf("Invalid ws.clientIP = %s\n", err)
336-
}
337-
338341
s3Client, err := newS3BucketClient(claims, bucketName, prefix, clientIP)
339342
if err != nil {
340343
LogError("error creating S3Client:", err)
@@ -351,14 +354,7 @@ func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucket
351354
return wsS3Client, nil
352355
}
353356

354-
func newWebSocketMinioClient(conn *websocket.Conn, claims *models.Principal) (*wsMinioClient, error) {
355-
// Only start Websocket Interaction after user has been
356-
// authenticated with MinIO
357-
clientIP, _, err := net.SplitHostPort(conn.RemoteAddr().String())
358-
if err != nil {
359-
// In case there's an error, return an empty string
360-
log.Printf("Invalid ws.clientIP = %s\n", err)
361-
}
357+
func newWebSocketMinioClient(conn *websocket.Conn, claims *models.Principal, clientIP string) (*wsMinioClient, error) {
362358
mClient, err := newMinioClient(claims, clientIP)
363359
if err != nil {
364360
LogError("error creating MinioClient:", err)

0 commit comments

Comments
 (0)