router: misc changes
This commit is contained in:
parent
d7a732d78a
commit
03332873d2
|
@ -197,9 +197,11 @@
|
||||||
hardware = inputs.nixos-hardware.nixosModules;
|
hardware = inputs.nixos-hardware.nixosModules;
|
||||||
} // args.specialArgs or { };
|
} // args.specialArgs or { };
|
||||||
modules = [
|
modules = [
|
||||||
{ _module.args = {
|
({ config, ... }: {
|
||||||
|
_module.args = {
|
||||||
pkgs-kernel = import inputs.nixpkgs-kernel { inherit (args) system; overlays = all-overlays ++ config.nixpkgs.overlays; };
|
pkgs-kernel = import inputs.nixpkgs-kernel { inherit (args) system; overlays = all-overlays ++ config.nixpkgs.overlays; };
|
||||||
}; }
|
};
|
||||||
|
})
|
||||||
(getPrivSys hostname)
|
(getPrivSys hostname)
|
||||||
{ networking.hostName = lib.mkDefault hostname;
|
{ networking.hostName = lib.mkDefault hostname;
|
||||||
nixpkgs.overlays = all-overlays; }
|
nixpkgs.overlays = all-overlays; }
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
lalrpop
|
lalrpop
|
||||||
tio
|
tio
|
||||||
tdesktop
|
tdesktop
|
||||||
|
osu-wine
|
||||||
];
|
];
|
||||||
xdg.configFile."looking-glass/client.ini".text = ''
|
xdg.configFile."looking-glass/client.ini".text = ''
|
||||||
[app]
|
[app]
|
||||||
|
|
20
system/hosts/router/a.py
Normal file
20
system/hosts/router/a.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import pytricia # type: ignore
|
||||||
|
|
||||||
|
def build_ipset(ips: list[str]) -> pytricia.PyTricia:
|
||||||
|
pyt = pytricia.PyTricia()
|
||||||
|
for ip in ips:
|
||||||
|
try:
|
||||||
|
pyt.insert(ip, None)
|
||||||
|
except:
|
||||||
|
with open("/var/lib/unbound/error.log", "at") as f:
|
||||||
|
f.write(f"Warning: couldn't insert ip {ip}:\n")
|
||||||
|
traceback.print_exc(file=f)
|
||||||
|
return pyt
|
||||||
|
|
||||||
|
s = build_ipset(["10.0.0.0/24"])
|
|
@ -230,6 +230,8 @@ MDNS_REJECT_TYPES: list[RdataType]
|
||||||
MDNS_ACCEPT_TYPES: list[RdataType]
|
MDNS_ACCEPT_TYPES: list[RdataType]
|
||||||
MDNS_REJECT_NAMES: Optional[re.Pattern]
|
MDNS_REJECT_NAMES: Optional[re.Pattern]
|
||||||
MDNS_ACCEPT_NAMES: Optional[re.Pattern]
|
MDNS_ACCEPT_NAMES: Optional[re.Pattern]
|
||||||
|
REJECT_A: Optional[re.Pattern] = None
|
||||||
|
REJECT_AAAA: Optional[re.Pattern] = None
|
||||||
|
|
||||||
sysbus: pydbus.bus.Bus
|
sysbus: pydbus.bus.Bus
|
||||||
avahi: Any # pydbus.proxy.ProxyObject
|
avahi: Any # pydbus.proxy.ProxyObject
|
||||||
|
@ -512,10 +514,26 @@ def build_ipset(ips: list[str]) -> pytricia.PyTricia:
|
||||||
return pyt
|
return pyt
|
||||||
|
|
||||||
|
|
||||||
|
IP_Q = pytricia.PyTricia()
|
||||||
|
IP_Q_LEN = 0
|
||||||
|
|
||||||
|
|
||||||
def add_ips(set: str, ipv6: bool, ips: list[str], flush: bool = False):
|
def add_ips(set: str, ipv6: bool, ips: list[str], flush: bool = False):
|
||||||
|
global IP_Q, IP_Q_LEN
|
||||||
|
for ip in ips:
|
||||||
|
try:
|
||||||
|
IP_Q.insert(ip, None)
|
||||||
|
except:
|
||||||
|
with open("/var/lib/unbound/error.log", "at") as f:
|
||||||
|
f.write(f"Warning 2: couldn't insert ip {ip}:\n")
|
||||||
|
traceback.print_exc(file=f)
|
||||||
|
IP_Q_LEN += len(ips)
|
||||||
|
if IP_Q_LEN < 16:
|
||||||
|
return
|
||||||
# with open('/var/lib/unbound/info.log', 'at') as f:
|
# with open('/var/lib/unbound/info.log', 'at') as f:
|
||||||
# print('set', set, 'ipv6', ipv6, 'ips', ips, file=f)
|
# print('set', set, 'ipv6', ipv6, 'ips', ips, file=f)
|
||||||
pyt = build_ipset(ips)
|
pyt = IP_Q
|
||||||
|
IP_Q = pytricia.PyTricia()
|
||||||
ruleset: list[dict] = []
|
ruleset: list[dict] = []
|
||||||
if flush:
|
if flush:
|
||||||
ruleset.append(
|
ruleset.append(
|
||||||
|
@ -568,23 +586,33 @@ def add_ips(set: str, ipv6: bool, ips: list[str], flush: bool = False):
|
||||||
# with open('/var/lib/unbound/info.log', 'at') as f:
|
# with open('/var/lib/unbound/info.log', 'at') as f:
|
||||||
# print('data', data, file=f)
|
# print('data', data, file=f)
|
||||||
try:
|
try:
|
||||||
out = subprocess.run(
|
if flush:
|
||||||
["/run/current-system/sw/bin/nft", "-j", "-f", "/dev/stdin"],
|
out = subprocess.run(
|
||||||
capture_output=True,
|
["/run/current-system/sw/bin/nft", "-j", "-f", "/dev/stdin"],
|
||||||
input=data,
|
capture_output=True,
|
||||||
)
|
input=data,
|
||||||
# with open('/var/lib/unbound/info.log', 'at') as f:
|
)
|
||||||
# print('out', out, file=f)
|
# with open('/var/lib/unbound/info.log', 'at') as f:
|
||||||
if out.returncode != 0:
|
# print('out', out, file=f)
|
||||||
with open("/var/lib/unbound/nftables.log", "wb") as f:
|
if out.returncode != 0:
|
||||||
f.write(b"Error running nftables ruleset. Ruleset:\n")
|
with open("/var/lib/unbound/nftables.log", "wb") as f:
|
||||||
f.write(data)
|
f.write(b"Error running nftables ruleset. Ruleset:\n")
|
||||||
f.write(b"\n")
|
f.write(data)
|
||||||
f.write(b"stdout:\n")
|
f.write(b"\n")
|
||||||
f.write(out.stdout)
|
f.write(b"stdout:\n")
|
||||||
f.write(b"\nstderr:\n")
|
f.write(out.stdout)
|
||||||
f.write(out.stderr)
|
f.write(b"\nstderr:\n")
|
||||||
f.write(b"\n")
|
f.write(out.stderr)
|
||||||
|
f.write(b"\n")
|
||||||
|
else:
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
["/run/current-system/sw/bin/nft", "-j", "-f", "/dev/stdin"],
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
assert proc.stdin is not None
|
||||||
|
proc.stdin.write(data)
|
||||||
|
proc.stdin.write(b"\n")
|
||||||
|
proc.stdin.close()
|
||||||
except:
|
except:
|
||||||
with open("/var/lib/unbound/error.log", "at") as f:
|
with open("/var/lib/unbound/error.log", "at") as f:
|
||||||
f.write(f"While adding ips for set {set}:\n")
|
f.write(f"While adding ips for set {set}:\n")
|
||||||
|
@ -595,7 +623,7 @@ def add_split_domain(domains: Domains, split_domain: list[str]):
|
||||||
if not split_domain:
|
if not split_domain:
|
||||||
return
|
return
|
||||||
split_domain = split_domain[:]
|
split_domain = split_domain[:]
|
||||||
if split_domain and split_domain[-1] == '*':
|
if split_domain and split_domain[-1] == "*":
|
||||||
split_domain.pop()
|
split_domain.pop()
|
||||||
if not split_domain:
|
if not split_domain:
|
||||||
return
|
return
|
||||||
|
@ -644,6 +672,15 @@ def init(*args: Any, **kwargs: Any):
|
||||||
global MDNS_REJECT_TYPES, MDNS_ACCEPT_TYPES
|
global MDNS_REJECT_TYPES, MDNS_ACCEPT_TYPES
|
||||||
global MDNS_REJECT_NAMES, MDNS_ACCEPT_NAMES
|
global MDNS_REJECT_NAMES, MDNS_ACCEPT_NAMES
|
||||||
global NFT_QUERIES, NFT_TOKEN, DOMAIN_NAME_OVERRIDES
|
global NFT_QUERIES, NFT_TOKEN, DOMAIN_NAME_OVERRIDES
|
||||||
|
global REJECT_A, REJECT_AAAA
|
||||||
|
|
||||||
|
w = os.environ.get("REJECT_A", None)
|
||||||
|
if w is not None:
|
||||||
|
REJECT_A = re.compile(w)
|
||||||
|
|
||||||
|
w = os.environ.get("REJECT_AAAA", None)
|
||||||
|
if w is not None:
|
||||||
|
REJECT_AAAA = re.compile(w)
|
||||||
|
|
||||||
domain_name_overrides: str = os.environ.get("DOMAIN_NAME_OVERRIDES", "")
|
domain_name_overrides: str = os.environ.get("DOMAIN_NAME_OVERRIDES", "")
|
||||||
if domain_name_overrides:
|
if domain_name_overrides:
|
||||||
|
@ -867,11 +904,11 @@ def operate(id, event, qstate, qdata) -> bool:
|
||||||
for i in range(rep.rrset_count):
|
for i in range(rep.rrset_count):
|
||||||
d = rep.rrsets[i].entry.data
|
d = rep.rrsets[i].entry.data
|
||||||
rk = rep.rrsets[i].rk
|
rk = rep.rrsets[i].rk
|
||||||
|
# IN
|
||||||
|
if rk.rrset_class != 256:
|
||||||
|
continue
|
||||||
for j in range(0, d.count + d.rrsig_count):
|
for j in range(0, d.count + d.rrsig_count):
|
||||||
wire = array.array("B", d.rr_data[j]).tobytes()
|
wire = array.array("B", d.rr_data[j]).tobytes()
|
||||||
# IN
|
|
||||||
if rk.rrset_class != 256:
|
|
||||||
continue
|
|
||||||
# A, AAAA
|
# A, AAAA
|
||||||
if (
|
if (
|
||||||
rk.type == 256
|
rk.type == 256
|
||||||
|
@ -968,6 +1005,57 @@ def operate(id, event, qstate, qdata) -> bool:
|
||||||
|
|
||||||
qstate.ext_state[id] = MODULE_FINISHED
|
qstate.ext_state[id] = MODULE_FINISHED
|
||||||
|
|
||||||
|
rej_a = REJECT_A and REJECT_A.match(n2)
|
||||||
|
rej_aaaa = REJECT_AAAA and REJECT_AAAA.match(n2)
|
||||||
|
if rej_a or rej_aaaa:
|
||||||
|
if qstate.return_msg and qstate.return_msg.rep:
|
||||||
|
rep = qstate.return_msg.rep
|
||||||
|
have_other = False
|
||||||
|
changed = False
|
||||||
|
msg = DNSMessage(
|
||||||
|
qstate.qinfo.qname_str,
|
||||||
|
qstate.qinfo.qtype,
|
||||||
|
qstate.qinfo.qclass,
|
||||||
|
qstate.query_flags,
|
||||||
|
)
|
||||||
|
for i in range(rep.rrset_count):
|
||||||
|
d = rep.rrsets[i].entry.data
|
||||||
|
rk = rep.rrsets[i].rk
|
||||||
|
if rk.rrset_class == 256 and (
|
||||||
|
rej_a and rk.type == 256 or rej_aaaa and rk.type == 7168
|
||||||
|
):
|
||||||
|
changed = True
|
||||||
|
continue
|
||||||
|
if rk.rrset_class == 256 and (
|
||||||
|
rej_aaaa
|
||||||
|
and not rej_a
|
||||||
|
and rk.type == 256
|
||||||
|
or rej_a
|
||||||
|
and not rej_aaaa
|
||||||
|
and rk.type == 7168
|
||||||
|
):
|
||||||
|
have_other = True
|
||||||
|
# IN
|
||||||
|
for j in range(0, d.count):
|
||||||
|
if rk.type == 256 and rej_a:
|
||||||
|
continue
|
||||||
|
elif rk.type == 7168 and rej_aaaa:
|
||||||
|
continue
|
||||||
|
msg.answer.append(
|
||||||
|
rr2text(
|
||||||
|
(rk.dname_str, rk.rrset_class, rk.type, d.rr_data[j]), d.ttl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if changed and not have_other:
|
||||||
|
# reject
|
||||||
|
qstate.ext_state[id] = MODULE_ERROR
|
||||||
|
return True
|
||||||
|
elif changed:
|
||||||
|
# replace
|
||||||
|
if not msg.set_return_msg(qstate):
|
||||||
|
qstate.ext_state[id] = MODULE_ERROR
|
||||||
|
return True
|
||||||
|
|
||||||
# Only resolve via Avahi if we got NXDOMAIN from the upstream DNS
|
# Only resolve via Avahi if we got NXDOMAIN from the upstream DNS
|
||||||
# server, or if we could not reach the upstream DNS server. If we
|
# server, or if we could not reach the upstream DNS server. If we
|
||||||
# got some records for the name from the upstream DNS server
|
# got some records for the name from the upstream DNS server
|
||||||
|
|
|
@ -473,8 +473,8 @@ in {
|
||||||
gateways = [ netAddresses.lan6 ];
|
gateways = [ netAddresses.lan6 ];
|
||||||
radvdSettings.AdvAutonomous = true;
|
radvdSettings.AdvAutonomous = true;
|
||||||
coreradSettings.autonomous = true;
|
coreradSettings.autonomous = true;
|
||||||
# don't allocate addresses for most devices
|
# # don't allocate addresses for most devices
|
||||||
keaSettings.pools = [ ];
|
# keaSettings.pools = [ ];
|
||||||
# just assign the reservations
|
# just assign the reservations
|
||||||
keaSettings.reservations = map (res:
|
keaSettings.reservations = map (res:
|
||||||
(if res.duid != null then { duid = res.duid; } else { hw-address = res.macAddress; }) // {
|
(if res.duid != null then { duid = res.duid; } else { hw-address = res.macAddress; }) // {
|
||||||
|
@ -597,20 +597,21 @@ in {
|
||||||
[(is.eq ip.saddr "@block4") (log "block4/s ") drop]
|
[(is.eq ip.saddr "@block4") (log "block4/s ") drop]
|
||||||
[(is.eq ip6.saddr "@block6") (log "block6/s ") drop]
|
[(is.eq ip6.saddr "@block6") (log "block6/s ") drop]
|
||||||
# default to no vpn...
|
# default to no vpn...
|
||||||
[(mangle meta.mark wan_table)]
|
# [(mangle meta.mark wan_table)]
|
||||||
# # default to vpn...
|
# default to vpn...
|
||||||
# [(mangle meta.mark vpn_table)]
|
[(mangle meta.mark vpn_table)]
|
||||||
|
[(is.eq meta.mark 0)]
|
||||||
|
# ...but unvpn traffic to/from force_unvpn4/force_unvpn6
|
||||||
|
[(is.eq ip.daddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
||||||
|
[(is.eq ip6.daddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
||||||
|
[(is.eq ip.saddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
||||||
|
[(is.eq ip6.saddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
||||||
# ...force vpn to/from force_vpn4/force_vpn6
|
# ...force vpn to/from force_vpn4/force_vpn6
|
||||||
# (disable this if it breaks some sites)
|
# (disable this if it breaks some sites)
|
||||||
[(is.eq ip.daddr "@force_vpn4") (mangle meta.mark vpn_table)]
|
[(is.eq ip.daddr "@force_vpn4") (mangle meta.mark vpn_table)]
|
||||||
[(is.eq ip6.daddr "@force_vpn6") (mangle meta.mark vpn_table)]
|
[(is.eq ip6.daddr "@force_vpn6") (mangle meta.mark vpn_table)]
|
||||||
[(is.eq ip.saddr "@force_vpn4") (mangle meta.mark vpn_table)]
|
[(is.eq ip.saddr "@force_vpn4") (mangle meta.mark vpn_table)]
|
||||||
[(is.eq ip6.saddr "@force_vpn6") (mangle meta.mark vpn_table)]
|
[(is.eq ip6.saddr "@force_vpn6") (mangle meta.mark vpn_table)]
|
||||||
# ...but unvpn traffic to/from force_unvpn4/force_unvpn6
|
|
||||||
[(is.eq ip.daddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
|
||||||
[(is.eq ip6.daddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
|
||||||
[(is.eq ip.saddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
|
||||||
[(is.eq ip6.saddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
|
||||||
# block requests to port 25 from hosts other than the server so they can't send mail pretending to originate from my domain
|
# block requests to port 25 from hosts other than the server so they can't send mail pretending to originate from my domain
|
||||||
# only do this for lans since traffic from other interfaces isn't forwarded to wan
|
# only do this for lans since traffic from other interfaces isn't forwarded to wan
|
||||||
[(is.eq meta.iifname lanSet) (is.ne ether.saddr cfg.serverMac) (is.eq meta.l4proto (f: f.tcp)) (is.eq tcp.dport 25) (log "smtp ") drop]
|
[(is.eq meta.iifname lanSet) (is.ne ether.saddr cfg.serverMac) (is.eq meta.l4proto (f: f.tcp)) (is.eq tcp.dport 25) (log "smtp ") drop]
|
||||||
|
|
Loading…
Reference in a new issue