blob: 4be0c17e8c2a6758c76dd7308db85f09c61890c4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#!/bin/bash
# Author/Copyright: Lukas Oertel <git@luoe.dev>
#
# This script fetches Github Actions egress IP addresses from the API and whitelists them for ingress SSH connections using a seperate iptables chain.
# put in the correct port here
SSH_PORT=123456
IPTABLES=/usr/sbin/iptables # -> /etc/alternatives/iptables -> /usr/sbin/iptables-nft (at least on trinity)
CURL=/usr/bin/curl
JQ=/usr/bin/jq
TR=/usr/bin/tr
SHA256SUM=/usr/bin/sha256sum
echo "Fetching Github Actions IPs from Github API..."
GITHUB_META=`${CURL} https://api.github.com/meta 2>/dev/null`
# for debugging purposes (to not hit the rate limit)
# IPS_DUMP="github_actions_ips_v4"
# GITHUB_META=`cat ${IPS_DUMP}`
ACTIONS_IPS=$(echo $GITHUB_META | ${JQ} '.actions[]' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}' | sort)
# use two distinct chains so there is now downtime when updating the rules
# one could iterate over the rules of the list, but it's quicker to just switch chains
GH_ACTIONS_CHAIN1="GH-ACTIONS-1"
GH_ACTIONS_CHAIN2="GH-ACTIONS-2"
# -n does not try to resolve PTR
GH_ACTIONS_CHAIN1_EXISTS=$("${IPTABLES}" -nL "${GH_ACTIONS_CHAIN1}" >/dev/null 2>&1; echo $?)
GH_ACTIONS_CHAIN2_EXISTS=$("${IPTABLES}" -nL "${GH_ACTIONS_CHAIN2}" >/dev/null 2>&1; echo $?)
CURRENT_CHAIN=""
NEW_CHAIN=""
if [ "${GH_ACTIONS_CHAIN1_EXISTS}" == 1 ] && [ "${GH_ACTIONS_CHAIN2_EXISTS}" == 1 ] || [ "${GH_ACTIONS_CHAIN1_EXISTS}" == 0 ]; then
CURRENT_CHAIN="${GH_ACTIONS_CHAIN1}"
NEW_CHAIN="${GH_ACTIONS_CHAIN2}"
else
CURRENT_CHAIN="${GH_ACTIONS_CHAIN2}"
NEW_CHAIN="${GH_ACTIONS_CHAIN1}"
fi
"${IPTABLES}" -N "${NEW_CHAIN}" > /dev/null 2>&1
"${IPTABLES}" -F "${NEW_CHAIN}" > /dev/null 2>&1
echo "Adding IP addresses to new chain..."
for ip in $ACTIONS_IPS; do
"${IPTABLES}" -I "${NEW_CHAIN}" -s $ip -p tcp --dport "${SSH_PORT}" -j ACCEPT
done
# not hitting any of the rules in the GH chain implies the last rule, so no dropping in INPUT needed
#${IPTABLES} -A INPUT -p tcp --dport ${SSH_PORT} -j DROP
${IPTABLES} -A ${NEW_CHAIN} -p tcp --dport ${SSH_PORT} -j DROP
# switch the chains
${IPTABLES} -I INPUT -p tcp --dport ${SSH_PORT} -j ${NEW_CHAIN}
${IPTABLES} -D INPUT -p tcp --dport ${SSH_PORT} -j ${CURRENT_CHAIN} > /dev/null 2>&1
# flush and remove the old chain
# not flushing it before throws an error, even though the chain is not referenced:
# iptables v1.8.7 (nf_tables): CHAIN_USER_DEL failed (Device or resource busy): chain
${IPTABLES} -F ${CURRENT_CHAIN} > /dev/null 2>&1
${IPTABLES} -X ${CURRENT_CHAIN} > /dev/null 2>&1
|