UFW: Nur Datenverkehr von einer Domain mit dynamischer IP-Adresse zulassen

32

Ich verwende einen VPS, den ich mit UFW sichern möchte und der nur Verbindungen zu Port 80 zulässt. Um ihn jedoch remote verwalten zu können, muss Port 22 geöffnet bleiben und von zu Hause aus erreichbar sein.

Ich weiß, dass UFW so konfiguriert werden kann, dass nur Verbindungen von einer bestimmten IP-Adresse zu einem Port zugelassen werden:

ufw allow proto tcp from 123.123.123.123 to any port 22

Meine IP-Adresse ist jedoch dynamisch, daher ist dies noch nicht die Lösung.

Die Frage ist: Ich habe eine dynamische DNS-Auflösung mit DynDNS. Ist es also möglich, eine Regel mithilfe der Domäne anstelle der IP zu erstellen?

Das habe ich schon probiert:

ufw allow proto tcp from mydomain.dyndns.org to any port 22

aber ich habe ERROR: Bad source address

Carles Sala
quelle

Antworten:

47

Ich glaube nicht, dass dies mit möglich ist ufw. ufwist nur ein Frontend, iptablesdem diese Funktion ebenfalls fehlt. Daher besteht ein Ansatz darin, einen crontab-Eintrag zu erstellen, der regelmäßig ausgeführt wird und überprüft, ob sich die IP-Adresse geändert hat. Wenn dies der Fall ist, wird es aktualisiert.

Sie könnten versucht sein, dies zu tun:

$ iptables -A INPUT -p tcp --src mydomain.dyndns.org --dport 22 -j ACCEPT

Dadurch wird der Hostname jedoch in eine IP-Adresse aufgelöst und für die Regel verwendet. Wenn sich die IP-Adresse später ändert, wird diese Regel ungültig.

Alternative Idee

Sie könnten ein Skript wie so genannt, erstellen iptables_update.bash.

#!/bin/bash
#allow a dyndns name

HOSTNAME=HOST_NAME_HERE
LOGFILE=LOGFILE_NAME_HERE

Current_IP=$(host $HOSTNAME | cut -f4 -d' ')

if [ $LOGFILE = "" ] ; then
  iptables -I INPUT -i eth1 -s $Current_IP -j ACCEPT
  echo $Current_IP > $LOGFILE
else

  Old_IP=$(cat $LOGFILE)

  if [ "$Current_IP" = "$Old_IP" ] ; then
    echo IP address has not changed
  else
    iptables -D INPUT -i eth1 -s $Old_IP -j ACCEPT
    iptables -I INPUT -i eth1 -s $Current_IP -j ACCEPT
    /etc/init.d/iptables save
    echo $Current_IP > $LOGFILE
    echo iptables have been updated
  fi
fi

Quelle: Verwenden von IPTables mit dynamischen IP-Hostnamen wie dyndns.org

Mit diesem gespeicherten Skript können Sie einen Crontab-Eintrag wie folgt in der Datei erstellen /etc/crontab:

*/5 * * * * root /etc/iptables_update.bash > /dev/null 2>&1

Dieser Eintrag führt das Skript dann alle 5 Minuten aus und überprüft, ob sich die dem Hostnamen zugewiesene IP-Adresse geändert hat. In diesem Fall wird eine neue Regel erstellt, die dies zulässt, während die alte Regel für die alte IP-Adresse gelöscht wird.

slm
quelle
2
Wie dumm, dass ich nicht daran gedacht habe, den Hostnamen regelmäßig aufzulösen. Ich habe Ihr Skript geändert (Protokollierung hinzugefügt usw.) und es funktioniert wie ein Zauber. Vielen Dank!
Carles Sala
@CarlesSala - froh, dass es Ihr Problem gelöst hat. Zusätzlich zur Annahme können Sie auch 8-) upvoten.
Slm
1
Hinweis: Unter Debian 7 musste ich Current_IP=$(host $HOSTNAME | cut -f4 -d' ')Current_IP=$(host $HOSTNAME | head -n1 | cut -f4 -d ' ')
Krystian
Kann ich dies sehen, wenn ich ufw status verbose verwende? Ich meine, die Regeln?
Freedo
@Freedo nicht sicher, versuchen Sie es und sehen, was passiert.
slm
8

Ich weiß, dass dies alt ist, aber ich bin darauf gestoßen und bin am Ende auf diese Lösung gestoßen, die sogar noch besser zu sein scheint, da keine Protokolldatei erforderlich ist und es sehr einfach ist, bei Bedarf zusätzliche Hosts hinzuzufügen. Klappt wunderbar!

Quelle: http://rdstash.blogspot.ch/2013/09/allow-host-with-dynamic-ip-through.html

#!/bin/bash

DYNHOST=$1
DYNHOST=${DYNHOST:0:28}
DYNIP=$(host $DYNHOST | grep -iE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" |cut -f4 -d' '|head -n 1)

# Exit if invalid IP address is returned
case $DYNIP in
0.0.0.0 )
exit 1 ;;
255.255.255.255 )
exit 1 ;;
esac

# Exit if IP address not in proper format
if ! [[ $DYNIP =~ (([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ]]; then
exit 1
fi

# If chain for remote doesn't exist, create it
if ! /sbin/iptables -L $DYNHOST -n >/dev/null 2>&1 ; then
/sbin/iptables -N $DYNHOST >/dev/null 2>&1
fi

# Check IP address to see if the chain matches first; skip rest of script if update is not needed
if ! /sbin/iptables -n -L $DYNHOST | grep -iE " $DYNIP " >/dev/null 2>&1 ; then


# Flush old rules, and add new
/sbin/iptables -F $DYNHOST >/dev/null 2>&1
/sbin/iptables -I $DYNHOST -s $DYNIP -j ACCEPT

# Add chain to INPUT filter if it doesn't exist
if ! /sbin/iptables -C INPUT -t filter -j $DYNHOST >/dev/null 2>&1 ; then
/sbin/iptables -t filter -I INPUT -j $DYNHOST
fi

fi
Dom
quelle
Entschuldigung, ich bin ein kleiner Neuling. Wo muss ich dieses Skript speichern und wo ändere ich Dinge, um meinen speziellen Fall widerzuspiegeln?
Freedo
5

Basierend auf früheren Antworten habe ich das Folgende als Bash-Skript aktualisiert, das auf Debian Jessie funktioniert

#!/bin/bash
HOSTNAME=dynamichost.domain.com
LOGFILE=$HOME/ufw.log
Current_IP=$(host $HOSTNAME | head -n1 | cut -f4 -d ' ')

if [ ! -f $LOGFILE ]; then
    /usr/sbin/ufw allow from $Current_IP to any port 22 proto tcp
    echo $Current_IP > $LOGFILE
else

    Old_IP=$(cat $LOGFILE)
    if [ "$Current_IP" = "$Old_IP" ] ; then
        echo IP address has not changed
    else
        /usr/sbin/ufw delete allow from $Old_IP to any port 22 proto tcp
        /usr/sbin/ufw allow from $Current_IP to any port 22 proto tcp
        echo $Current_IP > $LOGFILE
        echo iptables have been updated
    fi
fi
Mattias Pettersson
quelle
Das könnte sogar hinzugefügt werden, cronum es von Zeit zu Zeit selbstständig laufen zu lassen.
Tim Kennedy
Das habe ich getan;)
Mattias Pettersson
Dieses Skript hat ein kleines Problem: Wenn Sie bei der ersten Verwendung vergessen haben, als Root zu arbeiten, wird die Protokolldatei erstellt, die Regeln werden jedoch nicht hinzugefügt. Wenn Sie dann erneut als root ausgeführt werden, wird nur "IP-Adresse hat sich nicht geändert" angezeigt. Es muss das erste Mal als root ausgeführt werden! LOGFILE=$HOME/ufw.logLOGFILE=$HOME/ufw.$HOSTNAME.log
Wäre
@GuerlandoOCs wie setzen Sie zurück, wenn Sie auf dieses Problem stoßen?
Matthew
0

Basierend auf allen Antworten, bevor ich sie kombiniert habe. Keine Protokolldatei erforderlich. Getestet unter Ubuntu 18.04

#!/bin/bash
HOSTNAME=YOUR.DNS.NAME.HERE

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root"
   exit 1
fi

new_ip=$(host $HOSTNAME | head -n1 | cut -f4 -d ' ')
old_ip=$(/usr/sbin/ufw status | grep $HOSTNAME | head -n1 | tr -s ' ' | cut -f3 -d ' ')

if [ "$new_ip" = "$old_ip" ] ; then
    echo IP address has not changed
else
    if [ -n "$old_ip" ] ; then
        /usr/sbin/ufw delete allow from $old_ip to any
    fi
    /usr/sbin/ufw allow from $new_ip to any comment $HOSTNAME
    echo iptables have been updated
fi

Sie können den Regeln mit dem Parameter "port" einen Port hinzufügen. z.B:

if [ -n "$old_ip" ] ; then
    /usr/sbin/ufw delete allow from $old_ip to any port 22
fi
/usr/sbin/ufw allow from $new_ip to any port 22 comment $HOSTNAME
Sebastian
quelle