fix: remove an agent's forward rules with the agent (0.0.4)
Deleting a machine left its forward rules behind: the host ports stayed bound and "busy" with no page to remove them from. The rules, their listeners and ufw rules now go with the agent, and rules orphaned by older versions are dropped on start. A host port equal to the direct tunnel port gets its own message.
This commit is contained in:
1 parent
328ade651c
commit
f3cb7701f2
4 files changed
+29
-7
No files matched your search
+1
-1
@@ -1 +1 @@
|
|||||||
0.0.3
|
0.0.4
|
||||||
@@ -146,6 +146,12 @@ func (s *Server) handleAgentDelete(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := r.PathValue("id")
|
id := r.PathValue("id")
|
||||||
|
// Its forward rules go with it: left behind they would keep their host
|
||||||
|
// ports bound and busy with no page to remove them from.
|
||||||
|
rules, _ := s.db.ListForwardRulesByAgent(id)
|
||||||
|
for _, rule := range rules {
|
||||||
|
s.removeForward(rule.ID)
|
||||||
|
}
|
||||||
_ = s.db.DeleteAgent(id)
|
_ = s.db.DeleteAgent(id)
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ func (s *Server) handleForwardsPage(w http.ResponseWriter, r *http.Request) {
|
|||||||
rules, _ := s.db.ListForwardRulesByAgent(id)
|
rules, _ := s.db.ListForwardRulesByAgent(id)
|
||||||
errMsg := map[string]string{
|
errMsg := map[string]string{
|
||||||
"busy": "Этот порт хоста уже занят другим правилом.",
|
"busy": "Этот порт хоста уже занят другим правилом.",
|
||||||
|
"tunnel": "Этот порт занят прямым туннелем панели (см. Настройки).",
|
||||||
"port": "Некорректный номер порта.",
|
"port": "Некорректный номер порта.",
|
||||||
"listen": "Не удалось занять порт на хосте (возможно, уже используется).",
|
"listen": "Не удалось занять порт на хосте (возможно, уже используется).",
|
||||||
"db": "Ошибка базы данных.",
|
"db": "Ошибка базы данных.",
|
||||||
@@ -76,7 +77,11 @@ func (s *Server) handleForwardAdd(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Reject a host port already bound by another forward rule or the tunnel.
|
// Reject a host port already bound by another forward rule or the tunnel.
|
||||||
if s.db.HostPortUsed(hostPort) || hostPort == s.TunnelPort() {
|
if hostPort == s.TunnelPort() {
|
||||||
|
http.Redirect(w, r, "/agents/"+id+"/forwards?err=tunnel", http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.db.HostPortUsed(hostPort) {
|
||||||
http.Redirect(w, r, "/agents/"+id+"/forwards?err=busy", http.StatusSeeOther)
|
http.Redirect(w, r, "/agents/"+id+"/forwards?err=busy", http.StatusSeeOther)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -107,14 +112,19 @@ func (s *Server) handleForwardDelete(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
rid, _ := strconv.ParseInt(r.PathValue("rid"), 10, 64)
|
rid, _ := strconv.ParseInt(r.PathValue("rid"), 10, 64)
|
||||||
rule, _ := s.db.GetForwardRule(rid)
|
rule, _ := s.db.GetForwardRule(rid)
|
||||||
s.fwd.close(rid)
|
s.removeForward(rid)
|
||||||
_ = s.db.DeleteForwardRule(rid)
|
|
||||||
// Remove the ufw rule bound to this forward rule (the shared tunnel port
|
|
||||||
// stays while another direct forward needs it).
|
|
||||||
s.ufw.revokeForRule(rid)
|
|
||||||
dest := "/"
|
dest := "/"
|
||||||
if rule != nil {
|
if rule != nil {
|
||||||
dest = "/agents/" + rule.AgentID + "/forwards"
|
dest = "/agents/" + rule.AgentID + "/forwards"
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, dest, http.StatusSeeOther)
|
http.Redirect(w, r, dest, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removeForward closes a forward rule's listener and deletes the rule, along
|
||||||
|
// with the ufw rule bound to it (the shared tunnel port stays while another
|
||||||
|
// direct forward needs it).
|
||||||
|
func (s *Server) removeForward(rid int64) {
|
||||||
|
s.fwd.close(rid)
|
||||||
|
_ = s.db.DeleteForwardRule(rid)
|
||||||
|
s.ufw.revokeForRule(rid)
|
||||||
|
}
|
||||||
@@ -161,6 +161,12 @@ func (s *Server) restoreForwards() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, r := range rules {
|
for _, r := range rules {
|
||||||
|
// Rules of an agent deleted by an older version: drop them.
|
||||||
|
if a, err := s.db.GetAgent(r.AgentID); err == nil && a == nil {
|
||||||
|
log.Printf("forward rule %d: agent %s is gone, removing", r.ID, r.AgentID)
|
||||||
|
s.removeForward(r.ID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if err := s.fwd.open(r); err != nil {
|
if err := s.fwd.open(r); err != nil {
|
||||||
log.Printf("restore forward rule %d (%s:%d): %v", r.ID, r.ListenAddr, r.HostPort, err)
|
log.Printf("restore forward rule %d (%s:%d): %v", r.ID, r.ListenAddr, r.HostPort, err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user