UFW: Zezwalaj na ruch tylko z domeny z dynamicznym adresem IP


32

Korzystam z VPS, który chciałbym zabezpieczyć za pomocą UFW, pozwalając na połączenia tylko z portem 80. Aby jednak móc administrować nim zdalnie, muszę pozostawić port 22 otwarty i mieć do niego dostęp z domu.

Wiem, że UFW można skonfigurować tak, aby zezwalał na połączenia z portem tylko z określonego adresu IP:

ufw allow proto tcp from 123.123.123.123 to any port 22

Ale mój adres IP jest dynamiczny, więc nie jest to jeszcze rozwiązanie.

Pytanie brzmi: mam dynamiczne rozpoznawanie DNS w DynDNS, więc czy można utworzyć regułę przy użyciu domeny zamiast adresu IP?

Próbowałem już tego:

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

ale mam ERROR: Bad source address

Odpowiedzi:


47

Nie sądzę, aby było to możliwe ufw. ufwjest tylko nakładką, iptablesktórej również brakuje tej funkcji, więc jednym z podejść byłoby utworzenie wpisu pliku crontab, który okresowo uruchamiałby się i sprawdzał, czy adres IP się zmienił. Jeśli tak, zaktualizuje go.

Możesz mieć ochotę to zrobić:

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

Ale to rozwiąże nazwę hosta na adres IP i użyje go w regule, więc jeśli adres IP później się zmieni, reguła stanie się nieważna.

Alternatywny pomysł

Możesz stworzyć taki skrypt, tzw 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

źródło: Używanie IPTables z dynamicznymi nazwami hostów IP, takimi jak dyndns.org

Po zapisaniu tego skryptu możesz utworzyć wpis pliku crontab w pliku /etc/crontab:

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

Wpis ten uruchamiałby następnie skrypt co 5 minut, sprawdzając, czy adres IP przypisany do nazwy hosta się zmienił. Jeśli tak, to utworzy nową regułę, pozwalając na to, jednocześnie usuwając starą regułę dla starego adresu IP.


2
Jak głupio było, że nie myślałem o okresowym rozwiązywaniu nazwy hosta. Zmodyfikowałem twój skrypt (dodałem rejestrowanie itp.) I działa jak urok. Dziękuję Ci!
Carles Sala

@ CarlesSala - cieszę się, że rozwiązałeś problem. Oprócz akceptacji możesz również głosować 8-).
slm

1
uwaga: na Debianie 7 musiałem zmienić linię Current_IP=$(host $HOSTNAME | cut -f4 -d' ')naCurrent_IP=$(host $HOSTNAME | head -n1 | cut -f4 -d ' ')
Krystian

Czy będę mógł to zobaczyć, gdy używam pełnego statusu ufw? Mam na myśli zasady?
Freedo,

@Freedo nie jestem pewien, spróbuj i zobacz, co się stanie.
slm

8

Wiem, że to stare, ale natknąłem się na to i ostatecznie skończyłem z tym rozwiązaniem, które wydaje się jeszcze lepsze, ponieważ nie jest potrzebny plik dziennika i bardzo łatwo można dodać dodatkowe hosty w razie potrzeby. Działa jak marzenie!

Źródło: 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

przepraszam jestem trochę początkujący. Gdzie muszę przechowywać ten skrypt i gdzie zmieniać rzeczy, aby odzwierciedlić mój konkretny przypadek?
Freedo,

5

Na podstawie poprzednich odpowiedzi zaktualizowałem następujący skrypt bash, który działa na Debian Jessie

#!/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

Można to nawet dodać, aby cronokresowo działało samodzielnie.
Tim Kennedy

Tak właśnie zrobiłem;)
Mattias Pettersson

Ten skrypt ma mały problem: przy pierwszym użyciu, jeśli zapomniałeś uruchomić się jako root, utworzy plik dziennika, ale nie doda reguł. Następnie, jeśli uruchomisz ponownie jako root, powie tylko „adres IP się nie zmienił”. Za pierwszym razem musi być uruchomiony jako root! Dobrze byłoby też zmienić, LOGFILE=$HOME/ufw.logaby LOGFILE=$HOME/ufw.$HOSTNAME.logzezwalać na uruchamianie więcej niż jednego skryptu w tym samym czasie
Guerlando OC,

@GuerlandoOCs jak zresetować, jeśli napotkasz ten problem?
Matthew

0

Na podstawie wszystkich odpowiedzi, zanim je połączyłem. Plik dziennika nie jest wymagany. Testowane na 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

Możesz dodać port do reguł za pomocą parametru „port”. na przykład:

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.