feat: installer fetched from the direct address sets it as the agent's own with the main one as fallback (and downloads from it); agents fall back to whichever address is not theirs; (direct) beside the connection status
This commit is contained in:
1 parent
021da93229
commit
79828e3f8a
11 files changed
+72
-25
No files matched your search
@@ -11,6 +11,7 @@ import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/x-grk/longpolling-remote-access/internal/proto"
|
||||
@@ -227,6 +228,7 @@ func (s *Server) handleAgentEdit(w http.ResponseWriter, r *http.Request) {
|
||||
"UserErr": r.URL.Query().Get("uerr"),
|
||||
"Transport": firstNonEmpty(a.Transport, proto.TransportAuto),
|
||||
"OnWS": s.wsAgents.On(a.ID),
|
||||
"ViaDirect": viaDirectOf(&s.viaDirectA, a.ID),
|
||||
"Online": s.online(a),
|
||||
}
|
||||
// The user list lives on the machine, so it is only known while it is online.
|
||||
@@ -437,7 +439,7 @@ func (s *Server) handleSettings(w http.ResponseWriter, r *http.Request) {
|
||||
"Host": host,
|
||||
"Direct": direct,
|
||||
"DirectShort": fmt.Sprintf("wget -qO- %s/i/%s | sudo sh", direct, code),
|
||||
"DirectCurl": fmt.Sprintf("curl -fsSL %s/install.sh | sudo HOST=%s FALLBACK_HOST=%s ENROLL_SECRET=%s sh", direct, host, direct, secret),
|
||||
"DirectCurl": fmt.Sprintf("curl -fsSL %s/install.sh | sudo HOST=%s FALLBACK_HOST=%s ENROLL_SECRET=%s sh", direct, direct, host, secret),
|
||||
"Secret": secret,
|
||||
"CodeLen": s.db.InstallCodeLen(),
|
||||
"Admins": admins,
|
||||
@@ -664,7 +666,7 @@ func (s *Server) handleUfwRevoke(w http.ResponseWriter, r *http.Request) {
|
||||
// handleInstallScript serves the generic installer; the secret is NOT baked in,
|
||||
// so it must be supplied via env or the interactive prompt.
|
||||
func (s *Server) handleInstallScript(w http.ResponseWriter, r *http.Request) {
|
||||
s.renderInstall(w, "")
|
||||
s.renderInstall(w, r, "")
|
||||
}
|
||||
|
||||
// handleShortInstall serves the installer behind the short /i/<code> link with
|
||||
@@ -686,16 +688,35 @@ func (s *Server) handleShortInstall(w http.ResponseWriter, r *http.Request) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
s.renderInstall(w, s.db.EnrollSecret())
|
||||
s.renderInstall(w, r, s.db.EnrollSecret())
|
||||
}
|
||||
|
||||
// renderInstall writes install.sh with the current host and an optional secret.
|
||||
func (s *Server) renderInstall(w http.ResponseWriter, secret string) {
|
||||
// viaDirect reports whether the request came to the direct address.
|
||||
func (s *Server) viaDirect(r *http.Request) bool {
|
||||
d := directHost(s.db.DirectAddress())
|
||||
if d == "" {
|
||||
return false
|
||||
}
|
||||
host := r.Host
|
||||
if h, _, err := net.SplitHostPort(host); err == nil {
|
||||
host = h
|
||||
}
|
||||
return strings.EqualFold(host, d)
|
||||
}
|
||||
|
||||
// renderInstall writes install.sh with the server's addresses and an
|
||||
// optional secret. Fetched from the direct address, it makes that the
|
||||
// agent's address and the main one its fallback; otherwise the other way.
|
||||
func (s *Server) renderInstall(w http.ResponseWriter, r *http.Request, secret string) {
|
||||
host, fallback := s.db.HostAddress(), s.db.DirectAddress()
|
||||
if s.viaDirect(r) {
|
||||
host, fallback = fallback, host
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/x-shellscript; charset=utf-8")
|
||||
if err := s.installTmpl.Execute(w, map[string]any{
|
||||
"Host": s.db.HostAddress(),
|
||||
"Direct": s.db.DirectAddress(),
|
||||
"Secret": secret,
|
||||
"Host": host,
|
||||
"Fallback": fallback,
|
||||
"Secret": secret,
|
||||
}); err != nil {
|
||||
log.Printf("install.sh render: %v", err)
|
||||
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||
@@ -707,3 +728,11 @@ func (s *Server) downloadHandler() http.Handler {
|
||||
// install one-liner works before the machine is enrolled.
|
||||
return http.FileServer(http.Dir(s.distDir))
|
||||
}
|
||||
|
||||
// viaDirectOf tells whether the agent last reached the server at the direct
|
||||
// address.
|
||||
func viaDirectOf(m *sync.Map, id string) bool {
|
||||
v, _ := m.Load(id)
|
||||
b, _ := v.(bool)
|
||||
return b
|
||||
}
|
||||
Reference in new issue
Block a user