Alternative contextpath is now supported.

This will simplify hosting in cases where you have no control over DNS but only over one domain.
This commit is contained in:
Erik Brakkee 2024-08-03 23:10:57 +02:00
parent b875540d6b
commit 1b76add15b
5 changed files with 45 additions and 24 deletions

View File

@ -27,9 +27,10 @@ func parsePublicId(path string) (publicId string, _ error) {
return matches[1], nil
}
func catchAllHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/docs", http.StatusFound)
return
func catchAllHandler(contextPath string) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, contextPath+"/docs", http.StatusFound)
}
}
func printHelp(msg string) {
@ -48,8 +49,13 @@ func printHelp(msg string) {
"an embedded SSH server to provide interactive access to the end-user. This works\n" +
"both on linux and on windows.\n" +
"\n" +
"-s <contentdir>: directory where static content of converge is placed\n" +
"-d <downloaddir>: directory where downloads of converge are placed\n"
"Options\n" +
"-s <contentdir>: directory where static content of converge is placed\n" +
"-d <downloaddir>: directory where downloads of converge are placed\n" +
"-c <contextpath>: by default all content is served at /. Use this option to specify\n" +
" a different context path. For instance to host converge at a base\n" +
" URL of https://example.com/converge, specify /converg (and without\n" +
" trailing slash. "
fmt.Fprintln(os.Stderr, helpText)
os.Exit(1)
}
@ -58,6 +64,7 @@ func main() {
downloaddir := "."
staticdir := "../static"
contextpath := ""
args := os.Args[1:]
for len(args) > 0 && strings.HasPrefix(args[0], "-") {
@ -74,6 +81,12 @@ func main() {
}
staticdir = args[1]
args = args[1:]
case "-c":
if len(args) <= 1 {
printHelp("The -c option expects an argument")
}
contextpath = args[1]
args = args[1:]
default:
printHelp("Unknown option " + args[0])
}
@ -162,7 +175,6 @@ func main() {
// TODO remove, simulate contextpath
contextpath := ""
http.HandleFunc(contextpath+"/agent/", registrationService.Handle)
http.HandleFunc(contextpath+"/client/", clientService.Handle)
http.HandleFunc(contextpath+"/ws/sessions", sessionService.Handle)
@ -176,11 +188,7 @@ func main() {
// TODO remove for testing contextpath
catchAllHandler2 := func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, contextpath+"/docs", http.StatusFound)
return
}
http.HandleFunc(contextpath+"/", catchAllHandler2)
http.HandleFunc(contextpath+"/", catchAllHandler(contextpath))
// create usage generator
http.HandleFunc(contextpath+"/usage", generateCLIExammple)

View File

@ -3,11 +3,23 @@ package main
import (
"converge/pkg/models"
"converge/pkg/server/converge"
"log"
"net/http"
"regexp"
"strings"
)
func getConvergeAccess(r *http.Request, sshRemoteUser string) models.ConvergeAccess {
pattern := regexp.MustCompile("^(.*)/usage$")
matches := pattern.FindStringSubmatch(r.URL.Path)
contextPath := ""
if len(matches) != 2 {
log.Printf("Cannot determine context path for %s, assumming it is empty", r.URL.Path)
} else {
contextPath = matches[1]
}
secure := ""
if r.TLS == nil {
secure = ""
@ -27,9 +39,10 @@ func getConvergeAccess(r *http.Request, sshRemoteUser string) models.ConvergeAcc
if err != nil {
panic(err)
}
baseUrl := strings.ReplaceAll(r.Host+contextPath, "//", "/")
return models.ConvergeAccess{
Secure: secure,
HostPort: r.Host,
BaseUrl: baseUrl,
Location: location,
Username: sshRemoteUser,
}

View File

@ -39,7 +39,7 @@ func main() {
access := models.ConvergeAccess{
Secure: "s",
HostPort: "example.com",
BaseUrl: "example.com",
Location: netherlands,
Username: "converge",
}

View File

@ -5,7 +5,7 @@ import "time"
type ConvergeAccess struct {
// 's" when secure, "" otherwise
Secure string
HostPort string
BaseUrl string
Location *time.Location
Username string
}

View File

@ -13,23 +13,23 @@ templ AgentUsage(access models.ConvergeAccess, usageInputs UsageInputs) {
if usageInputs.RemoteShells[BASH] {
<pre>{addSshKeys(BASH, usageInputs.SshKeys)}
curl --fail-with-body http{access.Secure}://{access.HostPort}/downloads/agent > agent{`
curl --fail-with-body http{access.Secure}://{access.BaseUrl}/downloads/agent > agent{`
chmod 755 agent
`}./agent --id {usageInputs.Id} ws{access.Secure}://{access.HostPort}{`
`}./agent --id {usageInputs.Id} ws{access.Secure}://{access.BaseUrl}{`
rm -f agent
`}</pre>
}
if usageInputs.RemoteShells[CMD] {
<pre>{addSshKeys(CMD, usageInputs.SshKeys)}
curl --fail-with-body http{access.Secure}://{access.HostPort}/downloads/agent.exe > agent.exe{`
`}agent --id {usageInputs.Id} ws{access.Secure}://{access.HostPort}{`
curl --fail-with-body http{access.Secure}://{access.BaseUrl}/downloads/agent.exe > agent.exe{`
`}agent --id {usageInputs.Id} ws{access.Secure}://{access.BaseUrl}{`
del agent.exe
`}</pre>
}
if usageInputs.RemoteShells[POWERSHELL] {
<pre>{addSshKeys(POWERSHELL, usageInputs.SshKeys)}
curl --fail-with-body http{access.Secure}://{access.HostPort}/downloads/agent.exe > agent.exe{`
`}agent --id {usageInputs.Id} ws{access.Secure}://{access.HostPort}{`
curl --fail-with-body http{access.Secure}://{access.BaseUrl}/downloads/agent.exe > agent.exe{`
`}agent --id {usageInputs.Id} ws{access.Secure}://{access.BaseUrl}{`
del agent.exe
`}</pre>
}
@ -55,8 +55,8 @@ templ AgentUsage(access models.ConvergeAccess, usageInputs UsageInputs) {
</p>
<pre>{`
`}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"} {`
`}ssh -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id}" { access.Username }{"@localhost"} {`
`}sftp -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id}" { access.Username }{"@localhost"} {`
`}</pre>
<p>This requires the <code>wsproxy</code> utility which is available in the
@ -79,8 +79,8 @@ templ AgentUsage(access models.ConvergeAccess, usageInputs UsageInputs) {
using:
</p>
<pre>{`
`}tcptows ws{access.Secure}://{access.HostPort}/client/{usageInputs.Id} {`
`}tcptows ws{access.Secure}://{access.HostPort}/client/{usageInputs.Id} {`
`}tcptows ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id} {`
`}tcptows ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id} {`
`}</pre>
<h2>Working with the agent</h2>