Harden resolver and expand traffic runtime controls

This commit is contained in:
beckline
2026-02-24 00:17:46 +03:00
parent 89eaaf3f23
commit 50518a641d
18 changed files with 2048 additions and 181 deletions

View File

@@ -7,6 +7,7 @@ import (
"net/http"
"os"
"path/filepath"
"sort"
"strings"
)
@@ -42,9 +43,24 @@ func handleDomainsTable(w http.ResponseWriter, r *http.Request) {
return
}
stdout, _, _, err := runCommand("ipset", "list", "agvpn4")
lines := []string{}
if err == nil {
for _, setName := range []string{"agvpn4", "agvpn_dyn4"} {
stdout, _, code, _ := runCommand("nft", "list", "set", "inet", "agvpn", setName)
if code == 0 {
for _, l := range strings.Split(stdout, "\n") {
l = strings.TrimRight(l, "\r")
if l != "" {
lines = append(lines, l)
}
}
continue
}
// Backward-compatible fallback for legacy hosts that still have ipset.
stdout, _, code, _ = runCommand("ipset", "list", setName)
if code != 0 {
continue
}
for _, l := range strings.Split(stdout, "\n") {
l = strings.TrimRight(l, "\r")
if l != "" {
@@ -59,7 +75,7 @@ func handleDomainsTable(w http.ResponseWriter, r *http.Request) {
// domains file
// ---------------------------------------------------------------------
// GET /api/v1/domains/file?name=bases|meta|subs|static|smartdns|last-ips-map|last-ips-map-direct|last-ips-map-wildcard
// GET /api/v1/domains/file?name=bases|meta|subs|static|smartdns|last-ips-map|last-ips-map-direct|last-ips-map-wildcard|wildcard-observed-hosts
// POST /api/v1/domains/file { "name": "...", "content": "..." }
func handleDomainsFile(w http.ResponseWriter, r *http.Request) {
switch r.Method {
@@ -73,6 +89,13 @@ func handleDomainsFile(w http.ResponseWriter, r *http.Request) {
})
return
}
if name == "wildcard-observed-hosts" {
writeJSON(w, http.StatusOK, map[string]string{
"content": readWildcardObservedHostsContent(),
"source": "derived",
})
return
}
path, ok := domainFiles[name]
if !ok {
http.Error(w, "unknown file name", http.StatusBadRequest)
@@ -126,7 +149,7 @@ func handleDomainsFile(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
return
}
if body.Name == "last-ips-map-direct" || body.Name == "last-ips-map-wildcard" {
if body.Name == "last-ips-map-direct" || body.Name == "last-ips-map-wildcard" || body.Name == "wildcard-observed-hosts" {
http.Error(w, "read-only file name", http.StatusBadRequest)
return
}
@@ -146,6 +169,39 @@ func handleDomainsFile(w http.ResponseWriter, r *http.Request) {
}
}
func readWildcardObservedHostsContent() string {
data, err := os.ReadFile(lastIPsMapDyn)
if err != nil {
return ""
}
seen := make(map[string]struct{})
out := make([]string, 0, 256)
for _, ln := range strings.Split(string(data), "\n") {
ln = strings.TrimSpace(ln)
if ln == "" || strings.HasPrefix(ln, "#") {
continue
}
fields := strings.Fields(ln)
if len(fields) < 2 {
continue
}
host := strings.TrimSpace(fields[1])
if host == "" || strings.HasPrefix(host, "[") {
continue
}
if _, ok := seen[host]; ok {
continue
}
seen[host] = struct{}{}
out = append(out, host)
}
sort.Strings(out)
if len(out) == 0 {
return ""
}
return strings.Join(out, "\n") + "\n"
}
// ---------------------------------------------------------------------
// smartdns wildcards
// ---------------------------------------------------------------------