feat: 连接列表显示客户端真实 IP,支持反代和 CDN 场景
新增可配置的 real_ip_headers(默认 CF-Connecting-IP > X-Real-IP > X-Forwarded-For 降级取值),trusted_proxies 用于 gin 代理信任链。 WebSocket 连接建立时捕获真实 IP 并在 /profile 和 /admin 连接列表展示, 登录会话 IP 同步改用真实 IP。
This commit is contained in:
@@ -31,6 +31,7 @@ var upgrader = websocket.Upgrader{
|
||||
|
||||
func HandleWS(c *gin.Context) {
|
||||
tokenStr := c.Query("token")
|
||||
realIP := middleware.GetRealIP(c)
|
||||
|
||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
@@ -51,11 +52,11 @@ func HandleWS(c *gin.Context) {
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
runTunnel(conn, &u)
|
||||
runTunnel(conn, &u, realIP)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := authenticate(conn, db.DB, c.ClientIP())
|
||||
user, err := authenticate(conn, db.DB, realIP)
|
||||
if err != nil {
|
||||
log.Printf("认证读取失败: %v", err)
|
||||
conn.Close()
|
||||
@@ -65,5 +66,5 @@ func HandleWS(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
runTunnel(conn, user)
|
||||
runTunnel(conn, user, realIP)
|
||||
}
|
||||
|
||||
@@ -435,6 +435,7 @@ type ClientInfo struct {
|
||||
Username string `json:"username"`
|
||||
IP string `json:"ip"`
|
||||
IP6 string `json:"ip6,omitempty"`
|
||||
RealIP string `json:"real_ip"`
|
||||
ConnectedAt string `json:"connected_at"`
|
||||
RxBytes int64 `json:"rx_bytes"`
|
||||
TxBytes int64 `json:"tx_bytes"`
|
||||
|
||||
@@ -35,6 +35,7 @@ type tunnelConn struct {
|
||||
svc *VpnService
|
||||
assignedIP net.IP
|
||||
assignedIP6 net.IP
|
||||
realIP string
|
||||
connectedAt time.Time
|
||||
writeMu sync.Mutex
|
||||
ready atomic.Bool
|
||||
@@ -91,6 +92,7 @@ func (c *tunnelConn) info() ClientInfo {
|
||||
UserID: c.user.ID,
|
||||
Username: c.user.Username,
|
||||
IP: c.assignedIP.String(),
|
||||
RealIP: c.realIP,
|
||||
ConnectedAt: c.connectedAt.Format("2006-01-02 15:04:05"),
|
||||
RxBytes: c.rxBytes.Load(),
|
||||
TxBytes: c.txBytes.Load(),
|
||||
@@ -101,7 +103,7 @@ func (c *tunnelConn) info() ClientInfo {
|
||||
return ci
|
||||
}
|
||||
|
||||
func runTunnel(conn *websocket.Conn, user *model.User) {
|
||||
func runTunnel(conn *websocket.Conn, user *model.User, realIP string) {
|
||||
defer conn.Close()
|
||||
|
||||
if VPN == nil || !VPN.Running() {
|
||||
@@ -143,6 +145,7 @@ func runTunnel(conn *websocket.Conn, user *model.User) {
|
||||
svc: VPN,
|
||||
assignedIP: ip4,
|
||||
assignedIP6: ip6,
|
||||
realIP: realIP,
|
||||
connectedAt: time.Now(),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user