mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-26 23:29:57 +00:00
AUTH-2369: RDP Bastion prototype
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflared/h2mux"
|
||||
"github.com/cloudflare/cloudflared/sshserver"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -118,13 +119,13 @@ func Stream(conn, backendConn io.ReadWriter) {
|
||||
|
||||
// DefaultStreamHandler is provided to the the standard websocket to origin stream
|
||||
// This exist to allow SOCKS to deframe data before it gets to the origin
|
||||
func DefaultStreamHandler(wsConn *Conn, remoteConn net.Conn) {
|
||||
func DefaultStreamHandler(wsConn *Conn, remoteConn net.Conn, _ http.Header) {
|
||||
Stream(wsConn, remoteConn)
|
||||
}
|
||||
|
||||
// StartProxyServer will start a websocket server that will decode
|
||||
// the websocket data and write the resulting data to the provided
|
||||
func StartProxyServer(logger *logrus.Logger, listener net.Listener, remote string, shutdownC <-chan struct{}, streamHandler func(wsConn *Conn, remoteConn net.Conn)) error {
|
||||
func StartProxyServer(logger *logrus.Logger, listener net.Listener, staticHost string, shutdownC <-chan struct{}, streamHandler func(wsConn *Conn, remoteConn net.Conn, requestHeaders http.Header)) error {
|
||||
upgrader := websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
@@ -137,7 +138,18 @@ func StartProxyServer(logger *logrus.Logger, listener net.Listener, remote strin
|
||||
}()
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
stream, err := net.Dial("tcp", remote)
|
||||
// If remote is an empty string, get the destination from the client.
|
||||
finalDestination := staticHost
|
||||
if finalDestination == "" {
|
||||
if jumpDestination := r.Header.Get(h2mux.CFJumpDestinationHeader); jumpDestination == "" {
|
||||
logger.Error("Did not receive final destination from client. The --destination flag is likely not set")
|
||||
return
|
||||
} else {
|
||||
finalDestination = jumpDestination
|
||||
}
|
||||
}
|
||||
|
||||
stream, err := net.Dial("tcp", finalDestination)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Cannot connect to remote.")
|
||||
return
|
||||
@@ -162,24 +174,17 @@ func StartProxyServer(logger *logrus.Logger, listener net.Listener, remote strin
|
||||
conn.Close()
|
||||
}()
|
||||
|
||||
token := r.Header.Get("cf-access-token")
|
||||
if destination := r.Header.Get("CF-Access-SSH-Destination"); destination != "" {
|
||||
if err := sendSSHPreamble(stream, destination, token); err != nil {
|
||||
logger.WithError(err).Error("Failed to send SSH preamble")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
streamHandler(&Conn{conn}, stream)
|
||||
streamHandler(&Conn{conn}, stream, r.Header)
|
||||
})
|
||||
|
||||
return httpServer.Serve(listener)
|
||||
}
|
||||
|
||||
// sendSSHPreamble sends the final SSH destination address to the cloudflared SSH proxy
|
||||
// SendSSHPreamble sends the final SSH destination address to the cloudflared SSH proxy
|
||||
// The destination is preceded by its length
|
||||
func sendSSHPreamble(stream net.Conn, destination, token string) error {
|
||||
preamble := &sshserver.SSHPreamble{Destination: destination, JWT: token}
|
||||
// Not part of sshserver module to fix compilation for incompatible operating systems
|
||||
func SendSSHPreamble(stream net.Conn, destination, token string) error {
|
||||
preamble := sshserver.SSHPreamble{Destination: destination, JWT: token}
|
||||
payload, err := json.Marshal(preamble)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Reference in New Issue
Block a user