Created
August 29, 2023 13:52
-
-
Save eableson/685f54949e224b43cfca8596189811fc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/user set admin password="<complicated password>" | |
:global localSubnet "10.248.1.0/24" | |
:global localIP "10.248.1.254" | |
:global localDhcpPool "10.248.1.1-10.248.1.99" | |
:global internalDNS "192.168.10.199,192.168.2.240" | |
:global zerotierSubnet "10.249.0.0/16" | |
:global zerotierNetworkID "<zerotier network id>" | |
# Array of remote subnets to be routed through the zerotier connection | |
:global routedSubnets { \ | |
{ "192.168.10.0/24"; "office"}; \ | |
{ "192.168.2.0/24"; "house"} \ | |
} | |
:global wan1Gateway1 "208.67.220.220"; # OpenDNS | |
:global wan1Gateway2 "1.0.0.1"; # Cloudflare secondary | |
:global wan1GwRecursive1 "208.67.222.222"; # OpenDNS | |
:global wan1GwRecursive2 "9.9.9.9"; # Quad 9 | |
:global wan2GwRecursive1 "94.140.14.14"; # AdGuard | |
:global wan2GwRecursive2 "149.112.112.112"; # Quad 9 Secondary | |
### Basic bridging setup ### | |
# Local bridge for internal LAN ports | |
/interface bridge add name=local | |
/interface bridge port add interface=ether3 bridge=local | |
/interface bridge port add interface=ether4 bridge=local | |
/interface bridge port add interface=ether5 bridge=local | |
/interface bridge port add interface=ether6 bridge=local | |
/interface bridge port add interface=ether7 bridge=local | |
/interface bridge port add interface=ether8 bridge=local | |
### Interface lists ### | |
# Setup interface list for both WAN ports to use for firewall rules | |
/interface list add name=WAN | |
/interface list member add list=WAN interface=ether1 | |
/interface list member add list=WAN interface=ether2 | |
# Setup interface list for LAN ports to use for firewall rules | |
/interface list add name=LAN | |
/interface list member add list=LAN interface=local | |
# Setup DNS services, required for Zerotier to resolve servers | |
/ip dns set servers=1.1.1.1,8.8.8.8 | |
# Configure internal LAN network subnet and DHCP | |
/ip address add address="$localIP/24" interface=local | |
/ip pool add name=lan_pool ranges=$localDhcpPool | |
/ip dhcp-server add address-pool=lan_pool disabled=no interface=local lease-time=1h name=dhcp_lan | |
/ip dhcp-server network add address=$localSubnet dns-server=$internalDNS gateway=$localIP | |
# Lock down access to the Winbox MAC access | |
tool mac-server set allowed-interface-list=LAN | |
tool mac-server mac-winbox set allowed-interface-list=LAN | |
/ip neighbor discovery-settings set discover-interface-list=LAN | |
# Basic firewall rules to lock down access from the WAN ports, but allow ping | |
/ip firewall filter add chain=input connection-state=established,related action=accept comment="accept established,related"; | |
/ip firewall filter add chain=input connection-state=invalid action=drop; | |
/ip firewall filter add chain=input in-interface-list=WAN protocol=icmp action=accept comment="allow ICMP"; | |
/ip firewall filter add chain=input in-interface-list=WAN action=drop comment="block everything else"; | |
# NAT configuration and security | |
/ip firewall nat add chain=srcnat out-interface-list=WAN action=masquerade | |
/ip firewall filter add chain=forward action=fasttrack-connection connection-state=established,related comment="fast-track for established,related"; | |
/ip firewall filter add chain=forward action=accept connection-state=established,related comment="accept established,related"; | |
/ip firewall filter add chain=forward action=drop connection-state=invalid | |
/ip firewall filter add chain=forward action=drop connection-state=new connection-nat-state=!dstnat in-interface-list=WAN comment="drop access to clients behind NAT from WAN" | |
# Configure DHCP on WAN interfaces with script to auto-update the router as required on renewals | |
/ip dhcp-client add interface=ether1 add-default-route=no script=":if (\$bound=1) do={\r\ | |
\n /ip/route/set [find where comment=\"ISP1\"] gateway=\$\"gateway-address\"\r\ | |
\n}\r\ | |
\n\r\ | |
\n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\ | |
\n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]\r\ | |
\n" use-peer-dns=no use-peer-ntp=no | |
/ip dhcp-client add interface=ether2 add-default-route=no script=":if (\$bound=1) do={\r\ | |
\n /ip/route/set [find where comment=\"ISP2\"] gateway=\$\"gateway-address\"\r\ | |
\n}\r\ | |
\n\r\ | |
\n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\ | |
\n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]" use-peer-dns=no use-peer-ntp=no | |
# Create routing tables for each WAN interface | |
/routing table add fib name=to_ISP1 | |
/routing table add fib name=to_ISP2 | |
/ip route | |
# recursive routes for ECMP default gateways, dst-address are public DNS servers | |
add distance=1 dst-address="$wan1Gateway1/32" gateway=ether1 scope=10 target-scope=10 comment=ISP1 | |
add distance=1 dst-address="$wan1Gateway2/32" gateway=ether2 scope=10 target-scope=10 comment=ISP2 | |
# ECMP default gateways | |
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=$wan1Gateway1 scope=10 target-scope=11 | |
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=$wan1Gateway2 scope=10 target-scope=11 | |
# recursive routes for default gateways, dst-address are public DNS servers | |
add dst-address="$wan1GwRecursive1/32" gateway=ether1 scope=10 comment="ISP1" | |
add dst-address="$wan1GwRecursive2/32" gateway=ether1 scope=10 comment="ISP1" | |
add dst-address="$wan2GwRecursive1/32" gateway=ether2 scope=10 comment="ISP2" | |
add dst-address="$wan2GwRecursive2/32" gateway=ether2 scope=10 comment="ISP2" | |
# load-balanced w/ auto failover default gateways | |
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=$wan1GwRecursive1 routing-table=to_ISP1 scope=10 target-scope=11 | |
add check-gateway=ping distance=2 dst-address=0.0.0.0/0 gateway=$wan1GwRecursive2 routing-table=to_ISP1 scope=10 target-scope=11 | |
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=$wan2GwRecursive1 routing-table=to_ISP2 scope=10 target-scope=11 | |
add check-gateway=ping distance=2 dst-address=0.0.0.0/0 gateway=$wan2GwRecursive2 routing-table=to_ISP2 scope=10 target-scope=11 | |
/ip firewall address-list add address=$localSubnet list=local | |
/ip firewall address-list add address=$zerotierSubnet list=zerotier | |
:foreach net in=$routedSubnets do={ | |
/ip firewall address-list add address=($net->0) list=($net->1); | |
} | |
### Firewall Mangle Rules ### | |
/ip firewall mangle | |
add action=accept chain=prerouting comment="bridge access" dst-address-list=local in-interface-list=LAN | |
# WAN to LAN | |
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=established,related in-interface=ether1 new-connection-mark=ISP1_conn passthrough=yes | |
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=established,related in-interface=ether2 new-connection-mark=ISP2_conn passthrough=yes | |
### PCC mangles ### | |
# allow direct routes for internal routes | |
add action=accept chain=prerouting dst-address-list=zerotier | |
add action=accept chain=prerouting dst-address-list=ztrouted | |
:foreach net in=$routedSubnets do={ | |
add action=accept chain=prerouting dst-address-list=($net->1); | |
} | |
# NAT marks for traffic destined for internet | |
add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-list=!local dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes per-connection-classifier=both-addresses-and-ports:2/0 | |
add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-list=!local dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes per-connection-classifier=both-addresses-and-ports:2/1 | |
add action=mark-routing chain=prerouting connection-mark=ISP1_conn in-interface-list=LAN new-routing-mark=to_ISP1 passthrough=yes | |
add action=mark-routing chain=prerouting connection-mark=ISP2_conn in-interface-list=LAN new-routing-mark=to_ISP2 passthrough=yes | |
add action=mark-routing chain=output connection-mark=ISP1_conn dst-address-list=!local new-routing-mark=to_ISP1 passthrough=yes | |
add action=mark-routing chain=output connection-mark=ISP2_conn dst-address-list=!local new-routing-mark=to_ISP2 passthrough=yes | |
/zerotier/enable zt1 | |
/zerotier/interface/add network=$zerotierNetworkID instance=zt1 | |
:delay 4000ms; | |
/ip firewall filter add action=accept chain=forward in-interface=zerotier1 place-before=0 | |
/ip firewall filter add action=accept chain=input in-interface=zerotier1 place-before=0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment