UFW: consenti il ​​traffico solo da un dominio con indirizzo IP dinamico


32

Eseguo un VPS che vorrei proteggere usando UFW, consentendo connessioni solo alla porta 80. Tuttavia, per poterlo amministrare da remoto, devo tenere aperta la porta 22 e renderla raggiungibile da casa.

So che UFW può essere configurato per consentire connessioni a una porta solo da un indirizzo IP specifico:

ufw allow proto tcp from 123.123.123.123 to any port 22

Ma il mio indirizzo IP è dinamico, quindi questa non è ancora la soluzione.

La domanda è: ho una risoluzione DNS dinamica con DynDNS, quindi è possibile creare una regola utilizzando il dominio anziché l'IP?

Ho già provato questo:

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

ma ho ottenuto ERROR: Bad source address

Risposte:


47

Non credo che questo sia possibile ufw. ufwè solo un frontend a iptablescui manca questa funzionalità, quindi un approccio sarebbe quello di creare una voce crontab che verrebbe periodicamente eseguita e verificherà se l'indirizzo IP è cambiato. Se lo ha, lo aggiornerà.

Potresti essere tentato di farlo:

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

Ma questo risolverà il nome host in un IP e lo userà per la regola, quindi se l'IP cambia successivamente questa regola diventerà non valida.

Idea alternativa

È possibile creare uno script in questo modo, chiamato 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

fonte: utilizzo di IPTables con nomi host IP dinamici come dyndns.org

Con questo script salvato è possibile creare una voce crontab come nel file /etc/crontab:

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

Questa voce eseguirà quindi lo script ogni 5 minuti, verificando se l'indirizzo IP assegnato al nome host è cambiato. In tal caso, creerà una nuova regola che lo consente, eliminando la vecchia regola per il vecchio indirizzo IP.


2
Che sciocco che non pensavo di risolvere periodicamente il nome host. Ho modificato il tuo script (aggiunta registrazione, ecc.) E funziona come un fascino. Grazie!
Carles Sala,

@CarlesSala - felice di aver risolto il tuo problema. Oltre ad accettare puoi anche votare Cool.
slm

1
nota: su Debian 7 ho dovuto cambiare linea Current_IP=$(host $HOSTNAME | cut -f4 -d' ')inCurrent_IP=$(host $HOSTNAME | head -n1 | cut -f4 -d ' ')
Krystian il

Sarò in grado di vedere questo quando si utilizza lo stato ufw dettagliato? Voglio dire, le regole?
Freedo,

@Freedo non è sicuro, provalo e vedi cosa succede.
slm

8

So che questo è vecchio ma l'ho incontrato e alla fine ho trovato questa soluzione che sembra ancora migliore perché non è necessario alcun file di registro ed è molto facile aggiungere host aggiuntivi secondo necessità. Funziona come un fascino!

Fonte: 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

scusa sono un po 'alle prime armi. Dove devo archiviare questo script e dove cambio le cose per riflettere il mio caso specifico?
Freedo,

5

Sulla base delle risposte precedenti ho aggiornato quanto segue come script bash che funziona su 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

Potrebbe anche essere aggiunto per cronfarlo funzionare periodicamente da solo.
Tim Kennedy,

Questo è quello che ho fatto;)
Mattias Pettersson il

Questo script ha un piccolo problema: al primo utilizzo se ti sei dimenticato di eseguire come root, creerà il file di registro ma non aggiungerà le regole. Quindi, se esegui di nuovo come root, dirà semplicemente "l'indirizzo IP non è cambiato". Deve essere eseguito come root la prima volta! Inoltre, sarebbe utile cambiare LOGFILE=$HOME/ufw.logper LOGFILE=$HOME/ufw.$HOSTNAME.logconsentire l'esecuzione di più di uno script contemporaneamente
Guerlando OCs

@GuerlandoOCs come si reimposta se si riscontra questo problema?
Matteo,

0

Basato su tutte le risposte prima di combinarle. Nessun file di log necessario. Testato su 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

È possibile aggiungere una porta alle regole con il parametro "port". per esempio:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.