Skip to content

Commit 32c99cd

Browse files
committed
v1.0
1 parent 909c350 commit 32c99cd

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

dynamic-dns-in-ufw.sh

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/bin/sh
2+
3+
## Declaring an array with URI's of dynamic IP services
4+
## New line each in double quotes
5+
service=(
6+
"example.dynamic.dns.domain.tld"
7+
)
8+
9+
## The port to be made available
10+
port=22
11+
12+
## The service name which is used in the comments and helps with filtering the rules
13+
## Example: SSH from Dynamic IP
14+
name="SSH"
15+
16+
## If `true` AAAA records will also be fetched from the DNS
17+
## Enabled on by default, if you do not want to check for IPv6 simply set to `false`
18+
ipv6=true
19+
20+
## Declaring an array that will store logs messages
21+
log=()
22+
23+
## When true an error was raised that needs to be reported
24+
error=false
25+
26+
## Gets all the DNS records A and AAAA, then returns them as an array
27+
function get_dns {
28+
log+=("- Fetching DNS...")
29+
30+
## Fetches the A records
31+
a4=($(dig +short +noall +answer +multiline $1 A))
32+
33+
## Will also fetch the AAAA record when IPv6 is enabled
34+
a6=()
35+
if [ "$ipv6" = true ]; then
36+
a6=($(dig +short +noall +answer +multiline $1 AAAA))
37+
fi
38+
39+
dns=("${a4[@]}" "${a6[@]}")
40+
41+
if [ ! ${#dns[@]} -eq 0 ]; then
42+
log+=("-- Successfully fetched DNS records!")
43+
else
44+
log+=("-- No DNS records fetched!")
45+
error=true
46+
fi
47+
}
48+
49+
## Filters the firewall rules and extracts the index and address
50+
function get_existing {
51+
log+=("- Fetching Firewall rules...")
52+
existing=()
53+
54+
while read index ip; do
55+
existing[index]=$ip;
56+
done < <(
57+
ufw status numbered |
58+
grep -e ''"$port"'' |
59+
grep -i ''"$name"' from Dynamic IP ('"$1"')' |
60+
awk '{gsub(/[][]/,""); print $1, $5}'
61+
)
62+
63+
if [ ! ${#existing[@]} -eq 0 ]; then
64+
log+=("-- Successfully fetched existing rules!")
65+
else
66+
log+=("-- No rules fetched!")
67+
fi
68+
}
69+
70+
## Check each service individually
71+
for s in "${service[@]}"
72+
do
73+
log+=("Processing $s...")
74+
75+
get_dns $s
76+
get_existing $s
77+
78+
## Checking if any records exists for addresses in DNS record
79+
for a in "${dns[@]}"; do
80+
81+
log+=("> Checking $a...")
82+
83+
## Create a new rule if nothing was found for the address
84+
if [[ ! "${existing[*]}" =~ "$a" ]]; then
85+
86+
log+=("-> No rules found! Adding...")
87+
create=$(ufw allow from $a to any port $port comment ''"$name"' from Dynamic IP ('"$s"')')
88+
89+
## Make sure it was successfully created, if not log any errors
90+
if [[ $create == *"Rule added"* || $c == *"Skipping adding existing rule"* ]]; then
91+
log+=("--> Successfully added!")
92+
else
93+
log+=("--> Failed! Error: $create")
94+
error=true
95+
fi
96+
else
97+
log+=("OK")
98+
fi
99+
done
100+
101+
## Checking if addresses of any existing rules are in the DNS record
102+
for i in "${!existing[@]}"; do
103+
104+
log+=("> Checking record [$i] -> ${existing[i]}...")
105+
106+
## Delete the record if it's address is no longer in the DNS record
107+
if [[ ! "${dns[*]}" =~ "${existing[i]}" ]]; then
108+
109+
log+=("-> Not found in DNS record! Deleting...")
110+
delete=$(ufw --force delete $i)
111+
112+
## Make sure it was successfully deleted, if not log any errors
113+
if [[ $delete == *"Rule deleted"* ]]; then
114+
log+=("--> Successfully deleted!")
115+
else
116+
log+=("--> Failed! Error: $delete")
117+
error=true
118+
fi
119+
else
120+
log+=("OK")
121+
fi
122+
done
123+
done
124+
125+
## Check if any error have occurred
126+
## Prints the log if there is an error and exits with an error coded
127+
if [ "$error" = true ]; then
128+
for l in "${log[@]}"; do
129+
echo $l
130+
done
131+
exit 1
132+
else
133+
exit 0
134+
fi

0 commit comments

Comments
 (0)