diff --git a/packages/ytl-linux-digabi2-examnet/lib/internet-forwarding.just b/packages/ytl-linux-digabi2-examnet/lib/internet-forwarding.just index 5a4ea81..759af74 100644 --- a/packages/ytl-linux-digabi2-examnet/lib/internet-forwarding.just +++ b/packages/ytl-linux-digabi2-examnet/lib/internet-forwarding.just @@ -30,6 +30,8 @@ enable net-device-wan net-device-lan error-code: \ just internet-forwarding enable-kernel-ip-forwarding {{error-code}} + just internet-forwarding assert-chain-exists filter DOCKER-USER {{error-code}} + # Remove possible existing iptables rules and recreate allowlist filter chain to ensure idempotency just internet-forwarding remove-iptables-rules-by-comment "$INTERNET_ALLOWLIST_IPSET_NAME" {{error-code}} just iptables recreate-chain filter $INTERNET_ALLOWLIST_FILTER_CHAIN {{error-code}} @@ -61,14 +63,14 @@ enable net-device-wan net-device-lan error-code: \ --jump DROP # Allow return traffic - just iptables add-rule filter FORWARD {{error-code}} \ + just iptables add-rule filter DOCKER-USER {{error-code}} \ --in-interface "{{net-device-wan}}" --out-interface "{{net-device-lan}}" \ --match comment --comment "$INTERNET_ALLOWLIST_IPSET_NAME" \ --match conntrack --ctstate RELATED,ESTABLISHED \ --jump ACCEPT # Enforce allowlist for LAN->WAN traffic - just iptables add-rule filter FORWARD {{error-code}} \ + just iptables add-rule filter DOCKER-USER {{error-code}} \ --in-interface "{{net-device-lan}}" --out-interface "{{net-device-wan}}" \ --match comment --comment "$INTERNET_ALLOWLIST_IPSET_NAME" \ --jump "$INTERNET_ALLOWLIST_FILTER_CHAIN" @@ -103,6 +105,19 @@ disable error-code: \ just log info "Done disabling internet forwarding" +assert-chain-exists table chain error-code: + #!/usr/bin/env bash + set -euo pipefail + + just log debug "Checking that iptables chain {{chain}} exists in table {{table}}" + + if ! iptables --wait --table {{table}} --list {{chain}} --line-numbers --numeric > /dev/null 2>&1; then + just log error "Required iptables chain {{chain}} does not exist in table {{table}}" + exit {{error-code}} + fi + + just log debug "Iptables chain {{chain}} exists in table {{table}}" + configure-logging error-code: #!/usr/bin/env bash set -euo pipefail @@ -153,6 +168,7 @@ remove-iptables-rules-by-comment comment error-code: set -euo pipefail just iptables remove-rules-by-comment nat POSTROUTING {{comment}} {{error-code}} + just iptables remove-rules-by-comment filter DOCKER-USER {{comment}} {{error-code}} just iptables remove-rules-by-comment filter FORWARD {{comment}} {{error-code}} flush-and-destroy-ipset ipset-name error-code: diff --git a/packages/ytl-linux-digabi2-examnet/templates/dnsmasq.conf.template b/packages/ytl-linux-digabi2-examnet/templates/dnsmasq.conf.template index 44648de..738a325 100644 --- a/packages/ytl-linux-digabi2-examnet/templates/dnsmasq.conf.template +++ b/packages/ytl-linux-digabi2-examnet/templates/dnsmasq.conf.template @@ -47,3 +47,7 @@ ${ALLOWLISTED_IPSET_CONFIGURATION} # request stalls (since this is not a router) for however long the client timeout is set to; possibly Infinity address=/#/0.0.0.0 address=/#/:: + +# Reduce DNS cache TTLs as Microsoft has very short TTL for the A records of the allowlisted servers +max-cache-ttl=5 +max-ttl=5 diff --git a/packages/ytl-linux-digabi2-examnet/templates/rsyslog-internet-forwarding.conf.template b/packages/ytl-linux-digabi2-examnet/templates/rsyslog-internet-forwarding.conf.template index 1f10ee8..7139f98 100644 --- a/packages/ytl-linux-digabi2-examnet/templates/rsyslog-internet-forwarding.conf.template +++ b/packages/ytl-linux-digabi2-examnet/templates/rsyslog-internet-forwarding.conf.template @@ -5,5 +5,17 @@ if ($msg contains "YTL_ALLOW_NEW-") then { createDirs="off" fileCreateMode="0644" ) - stop +} + +if ($programname == "dnsmasq" and ( + $msg contains " forwarded " or + $msg contains " reply " or + $msg contains " ipset add " +)) then { + action( + type="omfile" + file="$PATH_INTERNET_FORWARDING_LOGS" + createDirs="off" + fileCreateMode="0644" + ) } diff --git a/packages/ytl-linux-digabi2-examnet/test/examnet-legacy.test.ts b/packages/ytl-linux-digabi2-examnet/test/examnet-legacy.test.ts index 90d7968..454427b 100644 --- a/packages/ytl-linux-digabi2-examnet/test/examnet-legacy.test.ts +++ b/packages/ytl-linux-digabi2-examnet/test/examnet-legacy.test.ts @@ -6,7 +6,7 @@ import { mkdtemp, writeFile, chmod, readFile, mkdir, unlink, truncate, access } import { tmpdir } from 'node:os' const ENV_TEST_MODE = { TEST_MODE: 'test' } -describe('examnet', async () => { +describe('examnet (legacy)', async () => { let callsLog let mockBinDir let mockEtcDir diff --git a/packages/ytl-linux-digabi2-examnet/test/examnet.test.ts b/packages/ytl-linux-digabi2-examnet/test/examnet.test.ts index 0c5436a..b6c0daa 100644 --- a/packages/ytl-linux-digabi2-examnet/test/examnet.test.ts +++ b/packages/ytl-linux-digabi2-examnet/test/examnet.test.ts @@ -237,6 +237,8 @@ describe('examnet (just port)', () => { callRm(`${mockEtcDir}/hosts.tmp`), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -271,6 +273,8 @@ describe('examnet (just port)', () => { callRm(`${mockEtcDir}/hosts.tmp`), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -303,6 +307,8 @@ describe('examnet (just port)', () => { callRm(`${mockEtcDir}/hosts.tmp`), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -476,8 +482,11 @@ describe('examnet (just port)', () => { callIpLinkShow('eth1'), callSysctl('1'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -510,12 +519,12 @@ describe('examnet (just port)', () => { callIptablesCheckChain('filter', 'YTL_LAN_WAN_IPSET', '--jump DROP'), callIptablesCheckChain( 'filter', - 'FORWARD', + 'DOCKER-USER', '--in-interface eth0 --out-interface eth1 --match comment --comment ytl_internet_allowlist --match conntrack --ctstate RELATED,ESTABLISHED --jump ACCEPT' ), callIptablesCheckChain( 'filter', - 'FORWARD', + 'DOCKER-USER', '--in-interface eth1 --out-interface eth0 --match comment --comment ytl_internet_allowlist --jump YTL_LAN_WAN_IPSET' ), callIptablesCheckChain( @@ -555,8 +564,11 @@ describe('examnet (just port)', () => { callIpLinkShow('eth1'), callSysctl('1'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -618,8 +630,11 @@ describe('examnet (just port)', () => { callIpLinkShow('eth1'), callSysctl('1'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -651,12 +666,12 @@ describe('examnet (just port)', () => { callIptablesCheckChain('filter', 'YTL_LAN_WAN_IPSET', '--jump DROP'), callIptablesCheckChain( 'filter', - 'FORWARD', + 'DOCKER-USER', '--in-interface eth0 --out-interface eth1 --match comment --comment ytl_internet_allowlist --match conntrack --ctstate RELATED,ESTABLISHED --jump ACCEPT' ), callIptablesCheckChain( 'filter', - 'FORWARD', + 'DOCKER-USER', '--in-interface eth1 --out-interface eth0 --match comment --comment ytl_internet_allowlist --jump YTL_LAN_WAN_IPSET' ), callIptablesCheckChain( @@ -813,8 +828,11 @@ describe('examnet (just port)', () => { callIpLinkShow('eth1'), callSysctl('1'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('nat', 'POSTROUTING'), callIptablesList('nat', 'POSTROUTING'), + callIptablesList('filter', 'DOCKER-USER'), + callIptablesList('filter', 'DOCKER-USER'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'FORWARD'), callIptablesList('filter', 'YTL_LAN_WAN_IPSET'), @@ -846,12 +864,12 @@ describe('examnet (just port)', () => { callIptablesCheckChain('filter', 'YTL_LAN_WAN_IPSET', '--jump DROP'), callIptablesCheckChain( 'filter', - 'FORWARD', + 'DOCKER-USER', '--in-interface eth0 --out-interface eth1 --match comment --comment ytl_internet_allowlist --match conntrack --ctstate RELATED,ESTABLISHED --jump ACCEPT' ), callIptablesCheckChain( 'filter', - 'FORWARD', + 'DOCKER-USER', '--in-interface eth1 --out-interface eth0 --match comment --comment ytl_internet_allowlist --jump YTL_LAN_WAN_IPSET' ), callIptablesCheckChain(