Created
February 11, 2020 06:40
-
-
Save fakuivan/b0a46dd8e176cde599515930dd610974 to your computer and use it in GitHub Desktop.
jq based bash script used to configure zerotier's rule engine via the controller API
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
#!/usr/bin/env bash | |
run_on_ztncui () { | |
(source ~/containers/ztncui.sh && ztncui-compose exec -T ztncui bash -c "$1"); return $? | |
} | |
NETWORKS="$(run_on_ztncui 'curl -s -X GET --header "X-ZT1-Auth: $ZT_TOKEN" "$ZT_ADDR"/controller/network')" | |
for rules_file in ./rules/*.ztrules; do | |
nwid="$(python3 -c "import pathlib, sys; print(pathlib.Path(sys.argv[1]).stem)" "$rules_file")" && | |
# Check if network id matches any network on the controller | |
{ [[ "$(echo "$NETWORKS" | jq --arg nwid "$nwid" 'any(. == $nwid)')" == "true" ]] || continue; } && | |
config="$(run_on_ztncui 'curl -s -X GET --header "X-ZT1-Auth: $ZT_TOKEN" "$ZT_ADDR"/controller/network/'"$(printf %q "$nwid")")" && | |
#npm install -g zerotier-rule-compiler | |
rules_compiled="$(node /usr/local/lib/node_modules/zerotier-rule-compiler/cli.js "$rules_file")" && | |
config_merged="$(jq -s '.[1] * .[0].config' <(echo "$rules_compiled") <(echo "$config"))" && | |
echo Writing final config | |
final_config="$(echo "$config_merged" | run_on_ztncui 'curl -s -X POST --header "X-ZT1-Auth: $ZT_TOKEN" -d @- "$ZT_ADDR"/controller/network/'"$(printf %q "$nwid")")" && | |
# jd could be used instead | |
diff -u <(echo "$config" | jq .) <(echo "$final_config" | jq .) --color && | |
rules_file="./rules/$nwid.caps.json" | |
if [[ -r "$rules_file" ]]; then | |
members="$(run_on_ztncui 'curl -s -X GET --header "X-ZT1-Auth: $ZT_TOKEN" "$ZT_ADDR"/controller/network/'"$(printf %q "$nwid")"'/member')" | |
caps="$(jq -s '.[0] as $members | | |
.[1].capabilitiesByName as $caps | | |
.[2] | | |
with_entries(select(.key | in($members))) | | |
with_entries(.value |= map(select(. | in($caps)) | $caps[.]))' \ | |
<(echo "$members") <(echo "$rules_compiled") "$rules_file")" | |
i=0; while [[ "$i" < "$(echo "$caps" | jq 'keys | length')" ]]; do | |
member="$(echo "$caps" | jq -r --arg iter "$i" 'keys | .[$iter | tonumber]')" | |
member_config="$(run_on_ztncui 'curl -s -X GET --header "X-ZT1-Auth: $ZT_TOKEN" "$ZT_ADDR"/controller/network/'"$(printf %q "$nwid")"'/member/'"$(printf %q "$member")")" | |
member_caps="$(echo "$caps" | jq --arg member "$member" '.[$member]')" | |
member_config_merged="$(jq -s --arg member "$member" '.[0] * {"capabilities": .[1][$member]}' <(echo "$member_config") <(echo "$caps"))" | |
member_final_config="$(echo "$member_config_merged" | | |
run_on_ztncui 'curl -s -X POST --header "X-ZT1-Auth: $ZT_TOKEN" -d @- "$ZT_ADDR"/controller/network/'"$(printf %q "$nwid")"'/member/'"$(printf %q "$member")")" | |
diff -u <(echo "$member_config" | jq .) <(echo "$member_final_config" | jq .) --color | |
i=$(("$i" + 1)) | |
done | |
fi | |
done |
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
{ | |
"feeeededdd": ["ipv6_router", "oofer"], | |
"deadbeefed": ["ipv6_router"] | |
} |
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
# | |
# This is a default rule set that allows IPv4 and IPv6 traffic but otherwise | |
# behaves like a standard Ethernet switch. | |
# | |
# Please keep in mind that ZeroTier versions prior to 1.2.0 do NOT support advanced | |
# network rules. | |
# | |
# Since both senders and receivers enforce rules, you will get the following | |
# behavior in a network with both old and new versions: | |
# | |
# (old: 1.1.14 and older, new: 1.2.0 and newer) | |
# | |
# old <--> old: No rules are honored. | |
# old <--> new: Rules work but are only enforced by new side. Tags will NOT work, and | |
# capabilities will only work if assigned to the new side. | |
# new <--> new: Full rules engine support including tags and capabilities. | |
# | |
# We recommend upgrading all your devices to 1.2.0 as soon as convenient. Version | |
# 1.2.0 also includes a significantly improved software update mechanism that is | |
# turned on by default on Mac and Windows. (Linux and mobile are typically kept up | |
# to date using package/app management.) | |
# | |
# Allow ipv6 routers to make use of 6PLANE addressing | |
cap ipv6_router | |
id 100 | |
accept | |
not chr ipauth | |
and not chr inbound | |
and ethertype ipv6 | |
; | |
; | |
cap oofer | |
id 300 | |
accept; | |
; | |
# | |
# Allow only IPv4, IPv4 ARP, and IPv6 Ethernet frames. | |
# | |
drop | |
not ethertype ipv4 | |
and not ethertype arp | |
and not ethertype ipv6 | |
; | |
# | |
# Uncomment to drop non-ZeroTier issued and managed IP addresses. | |
# | |
# This prevents IP spoofing but also blocks manual IP management at the OS level and | |
# bridging unless special rules to exempt certain hosts or traffic are added before | |
# this rule. | |
# | |
#drop | |
break | |
not chr ipauth | |
; | |
# Accept anything else. This is required since default is 'drop'. | |
accept; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment