diff --git a/assemble-acl/README.md b/assemble-acl/README.md index e397228..92cc1f8 100644 --- a/assemble-acl/README.md +++ b/assemble-acl/README.md @@ -1,2 +1,6 @@ +*** Note *** +This is depreciated. You should probably be looking at this instead: +https://github.com/tailscale-dev/tailscale-acl-combiner + Example setup for splitting an ACL file up into sections, then reassembling it with a GitHub Action. Each .policy file is a segment of the ACL. The script checks trailing commas, then cats the files together before posting via the API. Optionally, you may use CODEOWNERS to require specific approvers for changes to that file. diff --git a/change-cgnat-routing/README.md b/change-cgnat-routing/README.md new file mode 100644 index 0000000..5eddd8a --- /dev/null +++ b/change-cgnat-routing/README.md @@ -0,0 +1,9 @@ +This script will read the `IPPool` section of your Tailscale policy file and re-set the local iptables/nftables rules to only drop traffic to those defined ranges instead of the entire 100.64.0.0/10 range. + +It will require an OAuth client with ACL:Read scope. + +To use: Define the tailnet, and the location of the OAuth client ID and Secret in the script + +**note** this assumes that *all* nodes in the tailnet are scoped to an IPPool. + +**note** this needs to be run right after `tailscale up` or after each reboot. Changes do not persist. diff --git a/change-cgnat-routing/set-ip-pools.sh b/change-cgnat-routing/set-ip-pools.sh new file mode 100644 index 0000000..10a0fc2 --- /dev/null +++ b/change-cgnat-routing/set-ip-pools.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +tailnet="tsjustworks.net" +CIDRs=() +pools=() +oauthId=$(cat ~/keys/$tailnet.policy.oauth.id) +oauthSecret=$(cat ~/keys/$tailnet.policy.oauth.secret) +apikey=$(curl -d "client_id=$oauthId" -d "client_secret=$oauthSecret" -sSL https://api.tailscale.com/api/v2/oauth/token |jq -r .access_token) + +#get defined pools +declare -a pools=$(curl -sSL https://api.tailscale.com/api/v2/tailnet/$tailnet/acl --header "Authorization: Bearer $apikey" |grep -i ippool) +IFS="," +for CIDR in ${pools}; do + CIDRs+=$(echo $CIDR |cut -d [ -f 2 |sed -e 's/\]//' -e 's/\"/\ /g' -e '/^\s*$/d') +done + +#remove default routing DROP +iptables -D ts-input ! -i tailscale0 -s 100.64.0.0/10 -j DROP + +#add in more specific DROP rules +IFS=" " +for CIDR in ${CIDRs}; do + iptables --insert ts-input 3 ! -i tailscale0 -s $CIDR -j DROP +done + +#show new state +iptables -L ts-input -v diff --git a/delete-old-nodes/README.md b/delete-old-nodes/README.md new file mode 100644 index 0000000..e5d692d --- /dev/null +++ b/delete-old-nodes/README.md @@ -0,0 +1,8 @@ +#Delete Old Nodes +This will clean out nodes which have not been seen longer than the value of `$oldenough` - I've set this to one month. + +I keep my api key in ~/keys/tailnetname.api.key - if you have them elsewhere, you should change the `$apikey` value. + +And set `$tailnet` to the domain of your tailnet. + +This will do a dry-run as is, and print the ID of the node it will delete. Uncomment the DELETE command to execute. diff --git a/delete-old-nodes/delete-old-nodes.sh b/delete-old-nodes/delete-old-nodes.sh new file mode 100644 index 0000000..56e31f5 --- /dev/null +++ b/delete-old-nodes/delete-old-nodes.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +tailnet="tailnetname.com" +apikey=$(<$HOME/keys/${tailnet}.api.key) +oldenough=$(date -I --date="1 month ago") + +curl -s "https://api.tailscale.com/api/v2/tailnet/$tailnet/devices" -u "$apikey:" |jq -r '.devices[] | "\(.lastSeen) \(.id)"' | + while read seen id; do + if [[ $seen < $oldenough ]] + then + echo $id " was last seen " $seen " getting rid of it" + ### Uncomment below line to execute script. Defaults to dry run. + #curl -s -X DELETE "https://api.tailscale.com/api/v2/device/$id" -u "$apikey:" + else + echo $id " was last seen " $seen " keeping it" + fi + done diff --git a/remove-nodes-by-name/README.md b/remove-nodes-by-name/README.md new file mode 100644 index 0000000..5124548 --- /dev/null +++ b/remove-nodes-by-name/README.md @@ -0,0 +1,8 @@ +#Delete Nodes By Name +This will delete any nodes on your tailnet that match a string in their device name. I've used it to clean up after several instances were created by a runaway script. + +I keep my api key in ~/keys/tailnetname.api.key - if you have them elsewhere, you should change the `$apikey` value. + +And set `$tailnet` to the domain of your tailnet. + +This will do a dry-run as is, and print the ID of the node it will delete. Uncomment the DELETE command to execute. diff --git a/remove-nodes-by-name/remove-nodes-by-name.sh b/remove-nodes-by-name/remove-nodes-by-name.sh new file mode 100755 index 0000000..968510d --- /dev/null +++ b/remove-nodes-by-name/remove-nodes-by-name.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +tailnet="tsjustworks.net" +apikey=$(<$HOME/keys/${tailnet}.api.key) +targetname="ephemeral-test-" + +curl -s "https://api.tailscale.com/api/v2/tailnet/$tailnet/devices" -u "$apikey:" |jq -r '.devices[] | "\(.id) \(.name)"' | + while read id name; do + if [[ $name = *"$targetname"* ]] + then + echo $name $id " includes " $name " in its name - getting rid of it" + #curl -s -X DELETE "https://api.tailscale.com/api/v2/device/$id" -u "$apikey:" + else + echo $name" does not have that string in its name, keeping it" + fi + done diff --git a/remove-suspsended-users/removeSuspendedUsers.sh b/remove-suspsended-users/removeSuspendedUsers.sh new file mode 100755 index 0000000..3fb866e --- /dev/null +++ b/remove-suspsended-users/removeSuspendedUsers.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +apikey=$(cat ~/keys/api.key) +tailnet="tsjustworks.net" +targetstatus="suspended" + +allusers=$(curl -s "https://api.tailscale.com/api/v2/tailnet/-/users" -u "$apikey:" || (echo "API call failed" >&2; exit 1)) + +victims=$(echo $allusers | jq -r '.users[] |select(.status == "'$targetstatus'")') +victimids=$(echo $allusers | jq -r '.users[] |select(.status == "'$targetstatus'") | .id') +v_array=($(echo "$victimids"|xargs)) +if [ ${#v_array[@]} == 0 ] +then + echo "No users found in state "$targetstatus", aborting" + exit 1 +fi + +echo "These users are scheduled for removal. Confirm before proceding" + +echo $victims |jq '"User ID: " + .loginName + " status: " + .status' + +read -p "Press [Enter] key to delete all users in the above list" + +for item in "${v_array[@]}"; do + echo "Deleting "$item + #Commented out the scary part. Confirm the dry run before removing the octothorpe below + #curl -s --request POST --url https://api.tailscale.com/api/v2/users/$item/delete -u "$apikey:" || (echo "API call failed" >&2; exit 1) +done diff --git a/temp-grant/README.md b/temp-grant/README.md index 812e91e..71c2884 100644 --- a/temp-grant/README.md +++ b/temp-grant/README.md @@ -1 +1,5 @@ +***Note - This is depreciated*** +There is now an expiry available for custom postures, check the Just In Time docs +https://tailscale.com/kb/1443/just-in-time-access + These are the ingredients for a simple mechanism to grant temporary access based on a manual change to a custom posture attribute diff --git a/traveling/README.md b/traveling/README.md index 46ebf05..8b8bd39 100644 --- a/traveling/README.md +++ b/traveling/README.md @@ -1,3 +1,9 @@ +*** Note *** +This type of workflow is probably best handled by our JIT engine and Geolocation policies now, which didn't exist when this was published. +https://tailscale.com/kb/1443/just-in-time-access +https://tailscale.com/kb/1288/device-posture#examples + + Using device posture to manage access for traveling employees. Device posture is a powerful tool to control Tailscale permissions and access to devices on your network. They extend our ACL capabilities and allow admins to use fine-grained controls that can be based on some properties on the device, or custom attributes which can be set through automation tools. @@ -79,4 +85,4 @@ Otherwise, if there are some resources you still want travelers to use, you can "dst": ["autogroup:internet"], }, ], -``` \ No newline at end of file +```