diff --git a/cmd/converge/pagehandler.go b/cmd/converge/pagehandler.go index bdc256e..bcc46d7 100644 --- a/cmd/converge/pagehandler.go +++ b/cmd/converge/pagehandler.go @@ -3,11 +3,10 @@ package main import ( templates2 "converge/pkg/server/templates" "net/http" - "os" ) func pageHandler(w http.ResponseWriter, r *http.Request) { - username, _ := os.LookupEnv("CONVERGE_USERNAME") + username := getAgentSshUser() access := getConvergeAccess(r, username) switch r.URL.Path { diff --git a/cmd/converge/usage.go b/cmd/converge/usage.go index 63304ff..dc53a2a 100644 --- a/cmd/converge/usage.go +++ b/cmd/converge/usage.go @@ -1,9 +1,12 @@ package main import ( + "converge/pkg/server/templates" "log" + "math/rand" "net/http" - "time" + "os" + "strconv" ) func generateCLIExammple(w http.ResponseWriter, r *http.Request) { @@ -14,11 +17,31 @@ func generateCLIExammple(w http.ResponseWriter, r *http.Request) { http.Error(w, "Error parsing form", http.StatusBadRequest) return } - remote_shells := r.Form["remote-shell"] - local_shells := r.Form["local-shhell"] + ids := r.Form["rendez-vous-id"] + id := "" + if len(ids) > 0 { + id = ids[0] + } + if id == "" { + id = strconv.Itoa(rand.Int() % 1000000) + } + remoteShells := r.Form["remote-shell"] + localShells := r.Form["local-shell"] keys := r.FormValue("ssh-keys") - log.Printf("remote_shells %v", remote_shells) - log.Printf("local_shells %v", local_shells) + log.Printf("remote_shells %v", remoteShells) + log.Printf("local_shells %v", localShells) log.Printf("ssh-keys %v", keys) - w.Write([]byte(time.Now().Format(time.DateTime))) + + access := getConvergeAccess(r, getAgentSshUser()) + + usageInputs := templates.NewUsageInputs(id, remoteShells, localShells) + err = templates.ShellUsage(access, usageInputs).Render(r.Context(), w) + if err != nil { + http.Error(w, err.Error(), 500) + } +} + +func getAgentSshUser() string { + username, _ := os.LookupEnv("CONVERGE_USERNAME") + return username } diff --git a/pkg/server/templates/about.templ b/pkg/server/templates/about.templ index dddd15b..90ee0bf 100644 --- a/pkg/server/templates/about.templ +++ b/pkg/server/templates/about.templ @@ -39,6 +39,49 @@ templ About() { When the timeout of a session is near the user is informed about this with messages in the shell.
+ +end-to-end encryoption
+ssh keys
+agent options
+client access
+ +
+ wsproxy
is a command that can be used as a proxy command for SSH which performs the connection to the
+ remote server. This command needs to be downloaded only once (see downloads). It does not depend on
+ the converge implementation but only on the websocket standards. Other tools that
+ provide a mapping of stdio to a websocket can also be used instead of wsproxy.
+
+ This option is less convenient than the proxy command because it requires two separate + commands to execute. +
+ ++ Local clients can connect using regular ssh and sftp commands through a tunnel that + translates a local TCP port to a websocket connection in converge. See + the downloads section. + This runs a local client that allows SSH to port 10000 and connects to converge using + a websocket connection. +
+ +
+ The agent supports a --shells command-line option by which a comma-separated
+ list of shells can be prepended to the default search path for shells, e.g.
+ --shells zsh,csh,sh
(linux) or cmd,powershell
for
+ windows.
+
+ The agent sets a
+ This is what you run on a remote server, typically in your continuous integration job. +
+ + if shells[BASH] { +{` + `}curl http{access.Secure}://{access.HostPort}/static/agent > agent{` + chmod 755 agent + `}./agent --id {usageInputs.Id} ws{access.Secure}://{access.HostPort}{` + rm -f agent + `}+ } + if shells[CMD] || shells[POWERSHELL] { +
{` + `}curl http{access.Secure}://{access.HostPort}/static/agent.exe > agent.exe{` + `}agent --id {usageInputs.Id} ws{access.Secure}://{access.HostPort}{` + del agent.exe + `}+ } + +
+ The agent has more command-line options than shown here. + Download the agent and run it without arguments to + see all options. +
++ Tip: Run the above command locally in a similar shell (for instance in a + docker container) then try to connect to the shell using the commands below. If that + works, then you are all set. +
+ + +{` + `}ssh -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.HostPort}/client/{usageInputs.Id}" { access.Username }{"@localhost"} {` + `}sftp -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.HostPort}/client/{usageInputs.Id}" { access.Username }{"@localhost"} {` + `}+ +
{` + # cd back to the agent directory + cd $agentdir + + # prevent logout when last user exits + touch $agentdir/.hold + `}+ + } + if shells[CMD] { +
{` + # cd back to the agent directory + cd %agentdir% + + # prevent logout when last user exits + echo > %agentdir%\.hold + `}+ } + if shells[POWERSHELL] { +
{` + # cd back to the agent directory + cd $env:agentdir + + # prevent logout when last user exits + $null > $env:agentdir\.hold + `}+ } + if shells[CMD] || shells[POWERSHELL] { +
windows
++ NOTE: When running the agent on windows, an exit of the remote session using + exit in powershell or command prompt does not terminate the shell completely. + To terminate the client ssh session must be killed by closing the terminal. + Cleanup of remote processes on the agent appears to work properly despite this + problem. It is just that exit of the windows shell (powershell or command prompt) + is not detected properly. +
+ } +bash
+ } + if shells[CMD] { +cmd
+ } + if shells[POWERSHELL] { +powershell
+ } +