Skip to content

Commit

Permalink
Add VNC console proxy
Browse files Browse the repository at this point in the history
Running request-console with the `-l` flag spawns a proxy (by default
on localhost:5900) to connect to with a VNC client.
  • Loading branch information
minus7 committed Jul 8, 2020
1 parent e2bb367 commit 2a6a93b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
64 changes: 64 additions & 0 deletions cli/server_request_console.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package cli

import (
"fmt"
"io"
"net"

"github.com/spf13/cobra"
"golang.org/x/net/websocket"
)

func newServerRequestConsoleCommand(cli *CLI) *cobra.Command {
Expand All @@ -16,9 +19,55 @@ func newServerRequestConsoleCommand(cli *CLI) *cobra.Command {
PreRunE: cli.ensureToken,
RunE: cli.wrap(runServerRequestConsole),
}
cmd.Flags().BoolP("listen", "l", false, "Listen for a VNC client")
cmd.Flags().StringP("bind", "b", "localhost:5900", "Bind host/port for VNC port")
return cmd
}

func consoleProxy(bind, url string) error {
s, err := net.Listen("tcp", bind)
if err != nil {
return err
}
defer s.Close()

fmt.Printf("\nListening for VNC client on %v...\n", bind)

conn, err := s.Accept()
if err != nil {
return err
}
fmt.Printf("VNC Client connect, establishing WebSocket connection...\n")
defer conn.Close()

ws, err := websocket.Dial(url, "binary", "https://console.hetzner.cloud/")
if err != nil {
return err
}
ws.PayloadType = websocket.BinaryFrame
fmt.Printf("Connected!\n")
defer ws.Close()

in := make(chan error, 1)
go func() {
_, err := io.Copy(conn, ws)
in <- err
}()

out := make(chan error, 1)
go func() {
_, err := io.Copy(ws, conn)
out <- err
}()

select {
case err = <-in:
return err
case err = <-out:
return err
}
}

func runServerRequestConsole(cli *CLI, cmd *cobra.Command, args []string) error {
idOrName := args[0]
server, _, err := cli.Client().Server.Get(cli.Context, idOrName)
Expand All @@ -41,5 +90,20 @@ func runServerRequestConsole(cli *CLI, cmd *cobra.Command, args []string) error
fmt.Printf("Console for server %d:\n", server.ID)
fmt.Printf("WebSocket URL: %s\n", result.WSSURL)
fmt.Printf("VNC Password: %s\n", result.Password)

listen, err := cmd.Flags().GetBool("listen")
if err != nil {
return err
}

if listen {
bind, err := cmd.Flags().GetString("bind")
if err != nil {
return err
}

return consoleProxy(bind, result.WSSURL)
}

return nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/spf13/cobra v0.0.7
github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
golang.org/x/net v0.0.0-20190522155817-f3200d17e092
)

go 1.14
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down

0 comments on commit 2a6a93b

Please sign in to comment.