feat: route every console session through the agent relay
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -33,6 +34,15 @@ func consoleConnect(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if srv.Status != "active" {
|
||||
c.JSON(http.StatusConflict, gin.H{
|
||||
"error": "agent_offline",
|
||||
"message": "The agent on this server is not connected. " +
|
||||
"Console sessions are relayed by the agent, so it must be online.",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
sess, err := services.CreateConsoleSession(auth.InstanceID(c), body.ServerID, body.Protocol, body.KeyID, actorFromCtx(c), c.ClientIP())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
@@ -59,7 +69,7 @@ func consoleConnect(c *gin.Context) {
|
||||
}
|
||||
|
||||
services.LogEvent(auth.InstanceID(c), "console.opened", actorFromCtx(c), srv.ServerID, "",
|
||||
"console session opened ("+body.Protocol+")")
|
||||
"console session opened ("+body.Protocol+", agent-relayed)")
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"session_id": sess.SessionID,
|
||||
@@ -124,7 +134,25 @@ func consoleTunnel(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
gp, err := services.BuildGuacParams(srv, sess.Protocol, sess.SSHUsername, privKey, passphrase, rdpUser, rdpPass)
|
||||
targetPort, err := services.TargetPort(srv, sess.Protocol)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
relay, err := services.OpenConsoleProxy(instanceID, srv.ServerID, targetPort)
|
||||
if err != nil {
|
||||
if errors.Is(err, services.ErrAgentOffline) {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "agent_offline"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "could not open relay"})
|
||||
return
|
||||
}
|
||||
defer relay.Close()
|
||||
|
||||
gp, err := services.BuildGuacParams(sess.Protocol, sess.SSHUsername, privKey, passphrase,
|
||||
rdpUser, rdpPass, relay.Host, relay.Port)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -162,6 +190,11 @@ func consoleTunnel(c *gin.Context) {
|
||||
|
||||
wsServer := guac.NewWebsocketServer(connect)
|
||||
wsServer.OnDisconnect = func(id string, r *http.Request, t guac.Tunnel) {
|
||||
if reason := relay.Reason(); reason != "" {
|
||||
services.LogEvent(instanceID, "console.proxy_failed", actorFromCtx(c), srv.ServerID, "",
|
||||
"console relay failed: "+reason)
|
||||
}
|
||||
relay.Close()
|
||||
_ = services.EndConsoleSession(instanceID, sessionID)
|
||||
}
|
||||
wsServer.ServeHTTP(c.Writer, c.Request)
|
||||
|
||||
Reference in New Issue
Block a user