Delete a forwarded opening the way ufw accepts it, and read a fresh machine's resolver as not in use — both measured on a lab machine (hq ADR 0100)

This commit is contained in:
2026-09-22 17:37:01 +02:00
parent 5e3dd3f59c
commit 3e0e6e6b7e
9 changed files with 699 additions and 17 deletions
+9 -11
View File
@@ -10,13 +10,11 @@ import (
"github.com/novox/mesh-host/internal/store"
)
// quietUDP are processes whose UDP sockets every fresh machine has — name resolution, address
// configuration, time — and which serve nobody. ss names a process by its first fifteen characters,
// so both spellings are here.
//
// **Still to be measured** (novox/hq ADR 0100): this list is what a fresh machine is expected to
// hold, and it must be checked against a freshly installed lab machine before it is trusted.
var quietUDP = map[string]bool{
// quiet are the processes every fresh machine runs that serve nobody: name resolution (whose
// link-local resolver listens on TCP as well as UDP, on every address), address configuration and
// time. ss names a process by its first fifteen characters, so both spellings are here. Measured
// on a freshly installed lab machine (testdata/fresh-machine-listeners.txt): these and nothing else.
var quiet = map[string]bool{
"systemd-resolved": true, "systemd-resolve": true,
"systemd-networkd": true, "systemd-network": true,
"systemd-timesyncd": true, "systemd-timesyn": true,
@@ -24,8 +22,8 @@ var quietUDP = map[string]bool{
}
// InUse says what makes this machine a machine in use (novox/hq ADR 0100): every running container
// no host made, and every socket listening on an address other than loopback that is not ssh's — a
// UDP one only when it is held by something other than what every fresh machine runs. ours names
// no host made, and every socket listening on an address other than loopback that is neither ssh's
// nor held by what every fresh machine runs. ours names
// what the mesh itself runs, which a re-run of genesis finds and does not count.
func InUse(ctx context.Context, run Runner, ours func(name string) bool) ([]string, []reachable.Reach, error) {
var containers []string
@@ -61,9 +59,9 @@ func counts(r reachable.Reach) bool {
}
switch r.Protocol {
case "tcp":
return r.By != "sshd" && !(r.By == "" && r.Port == 22)
return r.By != "sshd" && !(r.By == "" && r.Port == 22) && !quiet[r.By]
case "udp":
return !quietUDP[r.By]
return !quiet[r.By]
}
return false
}
+25 -2
View File
@@ -2,6 +2,7 @@ package bootstrap
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
@@ -13,8 +14,8 @@ import (
// and listener it counted.
// Lines as `ss -Hltunp` prints them. The ssh, samba, loopback and proxy lines are captured from a
// real machine; the resolver, DHCP and time lines are written in the same shape for the processes a
// fresh machine runs, and still need measuring against one.
// real machine; the resolver, DHCP and time lines are written in the same shape. What a fresh machine
// actually runs is measured in testdata/fresh-machine-listeners.txt.
const inUseSockets = `tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1188536,fd=6))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1188536,fd=7))
tcp LISTEN 0 32 127.0.0.1:53 0.0.0.0:* users:(("dnsmasq",pid=1189392,fd=7))
@@ -97,3 +98,25 @@ func TestARerunOfGenesisIsNotAMachineInUse(t *testing.T) {
t.Errorf("what an earlier genesis raised was counted as a machine in use: %v", err)
}
}
func TestAFreshlyInstalledMachineAsMeasuredIsNotInUse(t *testing.T) {
// Captured with `ss -Hltunp` on a freshly installed lab machine: its resolver listens on TCP on
// every address, which the record's words alone would count.
raw, err := os.ReadFile("testdata/fresh-machine-listeners.txt")
if err != nil {
t.Fatal(err)
}
run := func(ctx context.Context, name string, args ...string) (string, error) {
if name == "ss" {
return string(raw), nil
}
return "", nil
}
containers, listeners, err := InUse(context.Background(), run, func(string) bool { return false })
if err != nil {
t.Fatal(err)
}
if len(containers) != 0 || len(listeners) != 0 {
t.Errorf("a fresh machine read as in use: containers %v, listeners %v", containers, listeners)
}
}
+12
View File
@@ -0,0 +1,12 @@
udp UNCONN 0 0 0.0.0.0:5353 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=17))
udp UNCONN 0 0 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=13))
udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=24))
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=22))
udp UNCONN 0 0 [::]:5353 [::]:* users:(("systemd-resolve",pid=262,fd=18))
udp UNCONN 0 0 [::]:5355 [::]:* users:(("systemd-resolve",pid=262,fd=15))
udp UNCONN 0 0 [fe80::1266:6aff:fe24:628d]%enp5s0:546 [::]:* users:(("systemd-network",pid=272,fd=36))
tcp LISTEN 0 4096 127.0.0.1:39473 0.0.0.0:* users:(("containerd",pid=394,fd=14))
tcp LISTEN 0 4096 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=14))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=23))
tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=25))
tcp LISTEN 0 4096 [::]:5355 [::]:* users:(("systemd-resolve",pid=262,fd=16))
+13 -2
View File
@@ -38,6 +38,17 @@ const (
Unsupported Kind = "unsupported"
)
// deletion is the arguments that delete a rule as `ufw show added` printed it. A route rule is
// deleted with `route delete …`: ufw refuses `delete route …` as invalid syntax. And ufw answers
// success when asked to delete a rule it does not hold, so every deletion is read back.
func deletion(rule string) []string {
w := words(rule)
if len(w) > 0 && w[0] == "route" {
return append([]string{"route", "delete"}, w[1:]...)
}
return append([]string{"delete"}, w...)
}
// MeshInterface is the private network's interface, the way an opening from the mesh is known.
// It must be the controller's overlay interface name.
const MeshInterface = "mesh0"
@@ -335,7 +346,7 @@ func Converge(ctx context.Context, run Runner, o *declaration.Opening) (string,
return "unchanged", nil
}
for _, rule := range stale {
if _, err := run(ctx, "ufw", append([]string{"delete"}, words(rule)...)...); err != nil {
if _, err := run(ctx, "ufw", deletion(rule)...); err != nil {
return "", fmt.Errorf("deleting the mesh's stale ufw rule %q: %w", rule, err)
}
}
@@ -381,7 +392,7 @@ func Remove(ctx context.Context, run Runner, id string) (int, error) {
if !markedFor(comment(rule), id) {
continue
}
if _, err := run(ctx, "ufw", append([]string{"delete"}, words(rule)...)...); err != nil {
if _, err := run(ctx, "ufw", deletion(rule)...); err != nil {
return removed, fmt.Errorf("deleting the mesh's ufw rule %q: %w", rule, err)
}
removed++
+93 -2
View File
@@ -180,9 +180,17 @@ func (f *fakeUFW) run(_ context.Context, name string, args ...string) (string, e
case args[0] == "disable":
f.active = false
return "Firewall stopped and disabled on system startup\n", nil
case args[0] == "delete":
case args[0] == "delete" && len(args) > 1 && args[1] == "route":
// As the real ufw answers it (captured in testdata/ufw-delete.txt): a route rule is
// deleted with `route delete`, never `delete route`.
return "", errors.New("ERROR: Invalid syntax")
case args[0] == "delete", args[0] == "route" && len(args) > 1 && args[1] == "delete":
rest := args[1:]
if args[0] == "route" {
rest = append([]string{"route"}, args[2:]...)
}
for i, r := range f.rules {
if strings.Join(words(r), "\x00") == strings.Join(args[1:], "\x00") {
if strings.Join(words(r), "\x00") == strings.Join(rest, "\x00") {
f.rules = append(f.rules[:i], f.rules[i+1:]...)
return "Rule deleted\n", nil
}
@@ -333,3 +341,86 @@ func TestDetectingTheFoundFirewall(t *testing.T) {
}
}
}
// The fixtures below were captured from a real ufw 0.36.2 on a lab machine, not written by hand:
// ufw prints a rule back in its own shorter form, so the mark in the comment is the only thing the
// host relies on.
func TestTheMarksAreReadFromWhatUfwReallyPrints(t *testing.T) {
raw, err := os.ReadFile("testdata/ufw-show-added.txt")
if err != nil {
t.Fatal(err)
}
run := func(ctx context.Context, name string, args ...string) (string, error) { return string(raw), nil }
rules, err := added(context.Background(), run)
if err != nil {
t.Fatal(err)
}
if len(rules) != 7 {
t.Fatalf("read %d rules, want 7: %q", len(rules), rules)
}
marked := 0
for _, r := range rules {
if strings.HasPrefix(comment(r), "mesh-host ") {
marked++
}
}
if marked != 5 {
t.Errorf("read %d marked rules, want 5", marked)
}
if !markedFor(comment(rules[5]), "adoption.opening-tcp-8443-forwarded") {
t.Errorf("the forwarded rule from the mesh lost its mark: %q", rules[5])
}
}
func TestEveryRealRuleIsDeletedInTheFormUfwAccepts(t *testing.T) {
raw, err := os.ReadFile("testdata/ufw-show-added.txt")
if err != nil {
t.Fatal(err)
}
run := func(ctx context.Context, name string, args ...string) (string, error) { return string(raw), nil }
rules, _ := added(context.Background(), run)
// Each of these was run on the lab machine and answered "Rule deleted" (testdata/ufw-delete.txt).
want := map[string]string{
"allow 5671/tcp comment 'mesh-host adoption.opening-tcp-5671-incoming 1a2b3c4d'": "delete allow 5671/tcp comment|mesh-host adoption.opening-tcp-5671-incoming 1a2b3c4d",
"allow in on mesh0 to any port 5432 proto tcp comment 'mesh-host adoption.opening-tcp-5432-incoming deadbeef'": "delete allow in on mesh0 to any port 5432 proto tcp comment|mesh-host adoption.opening-tcp-5432-incoming deadbeef",
"route allow 80/tcp comment 'mesh-host adoption.opening-tcp-8081-forwarded 0badf00d'": "route delete allow 80/tcp comment|mesh-host adoption.opening-tcp-8081-forwarded 0badf00d",
"route allow in on mesh0 to any port 443 proto tcp comment 'mesh-host adoption.opening-tcp-8443-forwarded cafe0001'": "route delete allow in on mesh0 to any port 443 proto tcp comment|mesh-host adoption.opening-tcp-8443-forwarded cafe0001",
}
seen := 0
for _, r := range rules {
w, ok := want[r]
if !ok {
continue
}
seen++
d := deletion(r)
got := strings.Join(d[:len(d)-1], " ") + "|" + d[len(d)-1]
if got != w {
t.Errorf("deleting %q\n got %s\n want %s", r, got, w)
}
}
if seen != len(want) {
t.Errorf("matched %d of %d captured rules", seen, len(want))
}
}
func TestARealUfwRulesetIsUfw(t *testing.T) {
raw, err := os.ReadFile("testdata/ufw-active.nft")
if err != nil {
t.Fatal(err)
}
status, err := os.ReadFile("testdata/ufw-status-active.txt")
if err != nil {
t.Fatal(err)
}
if !statusActive(string(status)) {
t.Fatal("the captured status does not read as active")
}
if refusing := Refusing(string(raw), true); len(refusing) > 0 {
t.Errorf("a machine with ufw active and nothing else read as refusing in %v", refusing)
}
if refusing := Refusing(string(raw), false); len(refusing) == 0 {
t.Error("ufw's drop chains, with ufw not known to be active, read as refusing nothing")
}
}
+478
View File
@@ -0,0 +1,478 @@
table ip nat {
chain DOCKER {
}
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
xt match "addrtype" counter packets 2 bytes 1160 jump DOCKER
}
chain OUTPUT {
type nat hook output priority dstnat; policy accept;
ip daddr != 127.0.0.0/8 xt match "addrtype" counter packets 0 bytes 0 jump DOCKER
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 172.17.0.0/16 oifname != "docker0" counter packets 0 bytes 0 xt target "MASQUERADE"
}
}
table ip filter {
chain DOCKER {
iifname != "docker0" oifname "docker0" counter packets 0 bytes 0 drop
}
chain DOCKER-FORWARD {
counter packets 0 bytes 0 jump DOCKER-CT
counter packets 0 bytes 0 jump DOCKER-INTERNAL
counter packets 0 bytes 0 jump DOCKER-BRIDGE
iifname "docker0" counter packets 0 bytes 0 accept
}
chain DOCKER-BRIDGE {
oifname "docker0" counter packets 0 bytes 0 jump DOCKER
}
chain DOCKER-CT {
oifname "docker0" xt match "conntrack" counter packets 0 bytes 0 accept
}
chain DOCKER-INTERNAL {
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
counter packets 0 bytes 0 jump DOCKER-USER
counter packets 0 bytes 0 jump DOCKER-FORWARD
counter packets 0 bytes 0 jump ufw-before-logging-forward
counter packets 0 bytes 0 jump ufw-before-forward
counter packets 0 bytes 0 jump ufw-after-forward
counter packets 0 bytes 0 jump ufw-after-logging-forward
counter packets 0 bytes 0 jump ufw-reject-forward
counter packets 0 bytes 0 jump ufw-track-forward
}
chain DOCKER-USER {
}
chain ufw-before-logging-input {
}
chain ufw-before-logging-output {
}
chain ufw-before-logging-forward {
}
chain ufw-before-input {
iifname "lo" counter packets 0 bytes 0 accept
xt match "conntrack" counter packets 0 bytes 0 accept
xt match "conntrack" counter packets 0 bytes 0 jump ufw-logging-deny
xt match "conntrack" counter packets 0 bytes 0 drop
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
udp sport 67 udp dport 68 counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw-not-local
ip daddr 224.0.0.251 udp dport 5353 counter packets 0 bytes 0 accept
ip daddr 239.255.255.250 udp dport 1900 counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw-user-input
}
chain ufw-before-output {
oifname "lo" counter packets 0 bytes 0 accept
xt match "conntrack" counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw-user-output
}
chain ufw-before-forward {
xt match "conntrack" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
ip protocol icmp xt match "icmp" counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw-user-forward
}
chain ufw-after-input {
udp dport 137 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
udp dport 138 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
tcp dport 139 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
tcp dport 445 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
udp dport 67 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
udp dport 68 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
xt match "addrtype" counter packets 0 bytes 0 jump ufw-skip-to-policy-input
}
chain ufw-after-output {
}
chain ufw-after-forward {
}
chain ufw-after-logging-input {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw-after-logging-output {
}
chain ufw-after-logging-forward {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw-reject-input {
}
chain ufw-reject-output {
}
chain ufw-reject-forward {
}
chain ufw-track-input {
}
chain ufw-track-output {
ip protocol tcp xt match "conntrack" counter packets 0 bytes 0 accept
ip protocol udp xt match "conntrack" counter packets 0 bytes 0 accept
}
chain ufw-track-forward {
}
chain INPUT {
type filter hook input priority filter; policy drop;
counter packets 1 bytes 76 jump ufw-before-logging-input
counter packets 1 bytes 76 jump ufw-before-input
counter packets 0 bytes 0 jump ufw-after-input
counter packets 0 bytes 0 jump ufw-after-logging-input
counter packets 0 bytes 0 jump ufw-reject-input
counter packets 0 bytes 0 jump ufw-track-input
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
counter packets 1 bytes 76 jump ufw-before-logging-output
counter packets 1 bytes 76 jump ufw-before-output
counter packets 1 bytes 76 jump ufw-after-output
counter packets 1 bytes 76 jump ufw-after-logging-output
counter packets 1 bytes 76 jump ufw-reject-output
counter packets 1 bytes 76 jump ufw-track-output
}
chain ufw-logging-deny {
xt match "conntrack" limit rate 3/minute burst 10 packets counter packets 0 bytes 0 return
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw-logging-allow {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw-skip-to-policy-input {
counter packets 0 bytes 0 drop
}
chain ufw-skip-to-policy-output {
counter packets 0 bytes 0 accept
}
chain ufw-skip-to-policy-forward {
counter packets 0 bytes 0 drop
}
chain ufw-not-local {
xt match "addrtype" counter packets 0 bytes 0 return
xt match "addrtype" counter packets 0 bytes 0 return
xt match "addrtype" counter packets 0 bytes 0 return
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 jump ufw-logging-deny
counter packets 0 bytes 0 drop
}
chain ufw-user-input {
tcp dport 22 counter packets 0 bytes 0 accept
tcp dport 8080 counter packets 0 bytes 0 accept
udp dport 51820 counter packets 0 bytes 0 accept
}
chain ufw-user-output {
}
chain ufw-user-forward {
tcp dport 80 counter packets 0 bytes 0 accept
iifname "mesh0" tcp dport 443 counter packets 0 bytes 0 accept
}
chain ufw-user-logging-input {
}
chain ufw-user-logging-output {
}
chain ufw-user-logging-forward {
}
chain ufw-user-limit {
limit rate 3/minute burst 5 packets counter packets 0 bytes 0 xt target "LOG"
counter packets 0 bytes 0 xt target "REJECT"
}
chain ufw-user-limit-accept {
counter packets 0 bytes 0 accept
}
}
table ip6 nat {
chain DOCKER {
}
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
xt match "addrtype" counter packets 0 bytes 0 jump DOCKER
}
chain OUTPUT {
type nat hook output priority dstnat; policy accept;
ip6 daddr != ::1 xt match "addrtype" counter packets 0 bytes 0 jump DOCKER
}
}
table ip6 filter {
chain DOCKER {
}
chain DOCKER-FORWARD {
counter packets 0 bytes 0 jump DOCKER-CT
counter packets 0 bytes 0 jump DOCKER-INTERNAL
counter packets 0 bytes 0 jump DOCKER-BRIDGE
}
chain DOCKER-BRIDGE {
}
chain DOCKER-CT {
}
chain DOCKER-INTERNAL {
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
counter packets 0 bytes 0 jump DOCKER-USER
counter packets 0 bytes 0 jump DOCKER-FORWARD
counter packets 0 bytes 0 jump ufw6-before-logging-forward
counter packets 0 bytes 0 jump ufw6-before-forward
counter packets 0 bytes 0 jump ufw6-after-forward
counter packets 0 bytes 0 jump ufw6-after-logging-forward
counter packets 0 bytes 0 jump ufw6-reject-forward
counter packets 0 bytes 0 jump ufw6-track-forward
}
chain DOCKER-USER {
}
chain ufw6-before-logging-input {
}
chain ufw6-before-logging-output {
}
chain ufw6-before-logging-forward {
}
chain ufw6-before-input {
iifname "lo" counter packets 0 bytes 0 accept
xt match "rt" counter packets 0 bytes 0 drop
xt match "conntrack" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
xt match "conntrack" counter packets 0 bytes 0 jump ufw6-logging-deny
xt match "conntrack" counter packets 0 bytes 0 drop
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 ip6 daddr fe80::/10 udp sport 547 udp dport 546 counter packets 0 bytes 0 accept
ip6 daddr ff02::fb udp dport 5353 counter packets 0 bytes 0 accept
ip6 daddr ff02::f udp dport 1900 counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw6-user-input
}
chain ufw6-before-output {
oifname "lo" counter packets 0 bytes 0 accept
xt match "rt" counter packets 0 bytes 0 drop
xt match "conntrack" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
ip6 saddr fe80::/10 meta l4proto ipv6-icmp xt match "icmp6" xt match "hl" counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw6-user-output
}
chain ufw6-before-forward {
xt match "rt" counter packets 0 bytes 0 drop
xt match "conntrack" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw6-user-forward
}
chain ufw6-after-input {
udp dport 137 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
udp dport 138 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
tcp dport 139 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
tcp dport 445 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
udp dport 546 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
udp dport 547 counter packets 0 bytes 0 jump ufw6-skip-to-policy-input
}
chain ufw6-after-output {
}
chain ufw6-after-forward {
}
chain ufw6-after-logging-input {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw6-after-logging-output {
}
chain ufw6-after-logging-forward {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw6-reject-input {
}
chain ufw6-reject-output {
}
chain ufw6-reject-forward {
}
chain ufw6-track-input {
}
chain ufw6-track-output {
meta l4proto tcp xt match "conntrack" counter packets 0 bytes 0 accept
meta l4proto udp xt match "conntrack" counter packets 0 bytes 0 accept
}
chain ufw6-track-forward {
}
chain INPUT {
type filter hook input priority filter; policy drop;
counter packets 1 bytes 128 jump ufw6-before-logging-input
counter packets 1 bytes 128 jump ufw6-before-input
counter packets 0 bytes 0 jump ufw6-after-input
counter packets 0 bytes 0 jump ufw6-after-logging-input
counter packets 0 bytes 0 jump ufw6-reject-input
counter packets 0 bytes 0 jump ufw6-track-input
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
counter packets 4 bytes 304 jump ufw6-before-logging-output
counter packets 4 bytes 304 jump ufw6-before-output
counter packets 0 bytes 0 jump ufw6-after-output
counter packets 0 bytes 0 jump ufw6-after-logging-output
counter packets 0 bytes 0 jump ufw6-reject-output
counter packets 0 bytes 0 jump ufw6-track-output
}
chain ufw6-logging-deny {
xt match "conntrack" limit rate 3/minute burst 10 packets counter packets 0 bytes 0 return
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw6-logging-allow {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 xt target "LOG"
}
chain ufw6-skip-to-policy-input {
counter packets 0 bytes 0 drop
}
chain ufw6-skip-to-policy-output {
counter packets 0 bytes 0 accept
}
chain ufw6-skip-to-policy-forward {
counter packets 0 bytes 0 drop
}
chain ufw6-user-input {
tcp dport 22 counter packets 0 bytes 0 accept
tcp dport 8080 counter packets 0 bytes 0 accept
udp dport 51820 counter packets 0 bytes 0 accept
}
chain ufw6-user-output {
}
chain ufw6-user-forward {
tcp dport 80 counter packets 0 bytes 0 accept
iifname "mesh0" tcp dport 443 counter packets 0 bytes 0 accept
}
chain ufw6-user-logging-input {
}
chain ufw6-user-logging-output {
}
chain ufw6-user-logging-forward {
}
chain ufw6-user-limit {
limit rate 3/minute burst 5 packets counter packets 0 bytes 0 xt target "LOG"
counter packets 0 bytes 0 xt target "REJECT"
}
chain ufw6-user-limit-accept {
counter packets 0 bytes 0 accept
}
}
+40
View File
@@ -0,0 +1,40 @@
Rule deleted
Rule deleted (v6)
rc=0
Rule deleted
Rule deleted (v6)
rc=0
ERROR: Invalid syntax
rc=1
===ADDED2
Added user rules (see 'ufw status' for running firewall):
ufw allow 22/tcp
ufw allow 8080/tcp
ufw route allow 80/tcp comment 'mesh-host adoption.opening-tcp-8081-forwarded 0badf00d'
ufw route allow in on mesh0 to any port 443 proto tcp comment 'mesh-host adoption.opening-tcp-8443-forwarded cafe0001'
ufw allow 51820/udp comment 'mesh-host adoption.opening-udp-51820-incoming 11112222'
Firewall reloaded
reload rc=0
===AFTERRELOAD
3
Firewall stopped and disabled on system startup
===DISABLED
Status: inactive
/etc/ufw/user.rules
3
Firewall is active and enabled on system startup
Status: active
Rule deleted
Rule deleted (v6)
rc=0
Rule deleted
Rule deleted (v6)
rc=0
Could not delete non-existent rule
Could not delete non-existent rule (v6)
wrongcomment rc=0
Added user rules (see 'ufw status' for running firewall):
ufw allow 22/tcp
ufw allow 8080/tcp
ufw allow 51820/udp comment 'mesh-host adoption.opening-udp-51820-incoming 11112222'
Status: active
+8
View File
@@ -0,0 +1,8 @@
Added user rules (see 'ufw status' for running firewall):
ufw allow 22/tcp
ufw allow 8080/tcp
ufw allow 5671/tcp comment 'mesh-host adoption.opening-tcp-5671-incoming 1a2b3c4d'
ufw allow in on mesh0 to any port 5432 proto tcp comment 'mesh-host adoption.opening-tcp-5432-incoming deadbeef'
ufw route allow 80/tcp comment 'mesh-host adoption.opening-tcp-8081-forwarded 0badf00d'
ufw route allow in on mesh0 to any port 443 proto tcp comment 'mesh-host adoption.opening-tcp-8443-forwarded cafe0001'
ufw allow 51820/udp comment 'mesh-host adoption.opening-udp-51820-incoming 11112222'
+21
View File
@@ -0,0 +1,21 @@
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
8080/tcp ALLOW Anywhere
5671/tcp ALLOW Anywhere # mesh-host adoption.opening-tcp-5671-incoming 1a2b3c4d
5432/tcp on mesh0 ALLOW Anywhere # mesh-host adoption.opening-tcp-5432-incoming deadbeef
51820/udp ALLOW Anywhere # mesh-host adoption.opening-udp-51820-incoming 11112222
22/tcp (v6) ALLOW Anywhere (v6)
8080/tcp (v6) ALLOW Anywhere (v6)
5671/tcp (v6) ALLOW Anywhere (v6) # mesh-host adoption.opening-tcp-5671-incoming 1a2b3c4d
5432/tcp (v6) on mesh0 ALLOW Anywhere (v6) # mesh-host adoption.opening-tcp-5432-incoming deadbeef
51820/udp (v6) ALLOW Anywhere (v6) # mesh-host adoption.opening-udp-51820-incoming 11112222
80/tcp ALLOW FWD Anywhere # mesh-host adoption.opening-tcp-8081-forwarded 0badf00d
443/tcp ALLOW FWD Anywhere on mesh0 # mesh-host adoption.opening-tcp-8443-forwarded cafe0001
80/tcp (v6) ALLOW FWD Anywhere (v6) # mesh-host adoption.opening-tcp-8081-forwarded 0badf00d
443/tcp (v6) ALLOW FWD Anywhere (v6) on mesh0 # mesh-host adoption.opening-tcp-8443-forwarded cafe0001
===STATUSV