Fix Tunnel: ID-Sync Backend<->Agent, bidirektionaler Proxy, API-Key via Query-Param

- Backend gibt tunnel_id vor, Agent uebernimmt sie
- Proxy-Verbindung bidirektional: Daten vom Agent zurueck an TCP-Client
- Middleware akzeptiert api_key als Query-Parameter (fuer WebSocket)
- Getestet: OPNsense WebUI erreichbar ueber Tunnel
This commit is contained in:
cynfo3000
2026-02-28 07:52:38 +01:00
parent f47154787d
commit fa68e191f9
4 changed files with 53 additions and 20 deletions
+33 -12
View File
@@ -21,6 +21,9 @@ type BackendTunnel struct {
Listener net.Listener
Active bool
CreatedAt time.Time
// Aktive Proxy-Verbindungen (fuer Rueckkanal)
proxyConn net.Conn
proxyMutex sync.Mutex
}
type TunnelManager struct {
@@ -86,12 +89,13 @@ func (tm *TunnelManager) OpenTunnel(agentID, targetHost string, targetPort int)
// Proxy-Server starten
go tm.runTunnelProxy(tunnel)
// Command an Agent senden
// Command an Agent senden — tunnel_id vorgeben damit Backend und Agent dieselbe ID nutzen
cmd := map[string]interface{}{
"type": "command",
"id": tm.generateTunnelID(),
"command": "tunnel_open",
"params": map[string]interface{}{
"tunnel_id": tunnelID,
"target_host": targetHost,
"target_port": targetPort,
},
@@ -220,28 +224,38 @@ func (tm *TunnelManager) handleProxyConnection(tunnel *BackendTunnel, conn net.C
log.Printf("Tunnel %s: Proxy-Verbindung von %s", tunnel.ID, conn.RemoteAddr())
// Buffer für TCP-Data
// Aktive Proxy-Verbindung registrieren (fuer Rueckkanal vom Agent)
tunnel.proxyMutex.Lock()
tunnel.proxyConn = conn
tunnel.proxyMutex.Unlock()
defer func() {
tunnel.proxyMutex.Lock()
tunnel.proxyConn = nil
tunnel.proxyMutex.Unlock()
log.Printf("Tunnel %s: Proxy-Verbindung beendet", tunnel.ID)
}()
// Buffer fuer TCP-Data
buffer := make([]byte, 32768)
for {
for tunnel.Active {
n, err := conn.Read(buffer)
if err != nil {
if err.Error() != "EOF" {
if err.Error() != "EOF" && tunnel.Active {
log.Printf("Tunnel %s: Proxy-Read-Fehler: %v", tunnel.ID, err)
}
break
}
if n > 0 {
// Daten über WebSocket an Agent weiterleiten
// Daten ueber WebSocket an Agent weiterleiten
if err := tm.sendTunnelData(tunnel.ID, buffer[:n]); err != nil {
log.Printf("Tunnel %s: Weiterleitung fehlgeschlagen: %v", tunnel.ID, err)
break
}
}
}
log.Printf("Tunnel %s: Proxy-Verbindung beendet", tunnel.ID)
}
func (tm *TunnelManager) sendTunnelData(tunnelID string, data []byte) error {
@@ -284,12 +298,19 @@ func (tm *TunnelManager) ProcessBinaryMessage(agentID string, data []byte) error
return fmt.Errorf("Tunnel %s nicht gefunden oder inaktiv", tunnelID)
}
// Hier würden wir die Daten an aktive Proxy-Verbindungen weiterleiten
// Da das komplexer ist, implementieren wir erstmal nur das Logging
log.Printf("Tunnel %s: %d Bytes von Agent erhalten", tunnelID, len(payload))
// Daten an aktive Proxy-Verbindung weiterleiten
tunnel.proxyMutex.Lock()
conn := tunnel.proxyConn
tunnel.proxyMutex.Unlock()
// TODO: Implement actual forwarding to active proxy connections
// Das würde einen Connection-Pool pro Tunnel erfordern
if conn == nil {
return fmt.Errorf("Tunnel %s: keine aktive Proxy-Verbindung", tunnelID)
}
_, writeErr := conn.Write(payload)
if writeErr != nil {
return fmt.Errorf("Tunnel %s: Proxy-Write fehlgeschlagen: %w", tunnelID, writeErr)
}
return nil
}