Skip to content

Instantly share code, notes, and snippets.

@eusonlito
Last active February 18, 2023 09:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eusonlito/d4f7ffce2b6a8636ba5efc14ad1a74cc to your computer and use it in GitHub Desktop.
Save eusonlito/d4f7ffce2b6a8636ba5efc14ad1a74cc to your computer and use it in GitHub Desktop.
Update iptables firewall with dynamic DNS updates from cron job
#!/bin/bash
# Set as cronjob
# * * * * * /root/scripts/iptables-ddns.sh >> /root/logs/iptables-ddns.log 2>&1
log () {
echo "[$(date "+%F +%T")] [$1] $2" >> "$LOGS/changes.log"
}
HOSTS="mydynamichost.ddns.net"
LOGS="/root/logs/iptables-ddns/"
PORT=22
if [ ! -d "$LOGS" ]; then
install -d "$LOGS"
fi
for host in $HOSTS; do
LOG="$LOGS/$host"
CURRENT=$(getent hosts "$host" | awk '{print $1}')
if [ "$CURRENT" == "" ]; then
log "$host" "[EMPTY] Current address empty"
continue
fi
if [ -f "$LOG" ]; then
PREVIOUS=$(cat "$LOG")
else
PREVIOUS=""
fi
if [ "$CURRENT" == "$PREVIOUS" ]; then
log "$host" "[SAME] Current and Previous are same ($CURRENT)"
continue
fi
if [ "$PREVIOUS" != "" ]; then
iptables -D INPUT -s "$PREVIOUS" -p tcp -m tcp --dport "$PORT" -j ACCEPT
fi
iptables -A INPUT -s "$CURRENT" -p tcp -m tcp --dport "$PORT" -j ACCEPT
echo "$CURRENT" > $LOG
log "$host" "[UPDATED] $PREVIOUS > $CURRENT"
done
exit 0
@Dieterm5
Copy link

Dieterm5 commented Jan 11, 2023

Can you correct line 22 and 33?

22: if [ "$CURRENT" = "" ]; then
33: if [ "$CURRENT" = "$PREVIOUS" ]; then

(with one '=' in stead of '==')
because with '==' you'll get an error: unexpected operator

---- Edit 1 -----
And one more thing.

This script works very well. But if you do a restart of this device or a restart of the service iptables, then all of the updates by this script will be deleted from iptables as expected, as long the ddns address stays unchanged this script don't add the 'old' ddns address to the iptables.

So I have added the line between 34-35:
iptables -D INPUT -s "$PREVIOUS" -p tcp -m tcp --dport "$PORT" -j ACCEPT
iptables -A INPUT -s "$PREVIOUS" -p tcp -m tcp --dport "$PORT" -j ACCEPT

After those "corrections" all of this works perfectly
(sorry for my broken English)

Thanks for this script anyway <3

@movy
Copy link

movy commented Feb 18, 2023

Thanks, @eusonlito and @Dieterm5. Here's full fixed that opens ALL ports and protocols for your DDNS ip:

#!/bin/bash

# Set as cronjob
# 10	*	*	*	*	/root/scripts/iptables-ddns.sh >> /root/logs/iptables-ddns.log 2>&1

log () {
    echo "[$(date "+%F +%T")] [$1] $2" >> "$LOGS/ddns-changes.log"
}

HOSTS="your-ip.ddns.net"
LOGS="/var/log/"
PORT=22

if [ ! -d "$LOGS" ]; then
    install -d "$LOGS"
fi

for host in $HOSTS; do
    LOG="$LOGS/$host"
    CURRENT=$(getent hosts "$host" | awk '{print $1}')

    if [ "$CURRENT" = "" ]; then
        log "$host" "[EMPTY] Current address empty"
        continue
    fi

    if [ -f "$LOG" ]; then
        PREVIOUS=$(cat "$LOG")
    else
        PREVIOUS=""
    fi

    if [ "$CURRENT" = "$PREVIOUS" ]; then
        echo "$host" "[SAME] Current and Previous are same ($CURRENT)"
        iptables -D INPUT -s "$PREVIOUS" -j ACCEPT
        iptables -A INPUT -s "$PREVIOUS" -j ACCEPT
        continue
    fi

    if [ "$PREVIOUS" != "" ]; then
        iptables -D INPUT -s "$PREVIOUS" -j ACCEPT
    fi

    iptables -A INPUT -s "$CURRENT" -j ACCEPT

    echo "$CURRENT" > $LOG

    log "$host" "[UPDATED] $PREVIOUS > $CURRENT"
done

exit 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment