web-dev-qa-db-fra.com

UFW: autoriser le trafic uniquement à partir d'un domaine avec une adresse IP dynamique

J'exécute un VPS que je voudrais sécuriser en utilisant UFW, en autorisant uniquement les connexions au port 80. Cependant, afin de pouvoir l'administrer à distance, je dois garder le port 22 ouvert et le rendre accessible depuis chez moi.

Je sais que UFW peut être configuré pour autoriser les connexions à un port uniquement à partir d'une adresse IP spécifique:

ufw allow proto tcp from 123.123.123.123 to any port 22

Mais mon adresse IP est dynamique, ce n'est donc pas encore la solution.

La question est: j'ai une résolution DNS dynamique avec DynDNS, est-il donc possible de créer une règle en utilisant le domaine au lieu de l'IP?

J'ai déjà essayé ceci:

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

mais j'ai eu ERROR: Bad source address

35
Carles Sala

Je ne pense pas que ce soit possible avec ufw. ufw n'est qu'un frontend à iptables qui n'a pas non plus cette fonctionnalité, donc une approche serait de créer une entrée crontab qui s'exécuterait périodiquement et vérifierait si l'adresse IP a changé. Si c'est le cas, il le mettra à jour.

Vous pourriez être tenté de le faire:

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

Mais cela résoudra le nom d'hôte en IP et l'utilisera pour la règle, donc si l'IP change plus tard, cette règle deviendra invalide.

Idée alternative

Vous pouvez créer un script comme celui-ci, appelé, 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

source: tilisation d'IPTables avec des noms d'hôtes IP dynamiques comme dyndns.org

Avec ce script enregistré, vous pouvez créer une entrée crontab comme ceci dans le fichier /etc/crontab:

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

Cette entrée exécuterait ensuite le script toutes les 5 minutes, vérifiant si l'adresse IP attribuée au nom d'hôte a changé. Si c'est le cas, il créera une nouvelle règle l'autorisant, tout en supprimant l'ancienne règle pour l'ancienne adresse IP.

49
slm

Je sais que c'est vieux mais je l'ai rencontré et j'ai finalement trouvé cette solution qui semble encore meilleure car aucun fichier journal n'est nécessaire et il est très facile d'ajouter des hôtes supplémentaires si nécessaire. Fonctionne comme un charme!

Source: 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
8
Dom

Sur la base des réponses précédentes, j'ai mis à jour ce qui suit en tant que script bash qui fonctionne sur 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
6
Mattias Pettersson

Basé sur toutes les réponses avant de les combiner. Aucun fichier journal requis. Testé sur 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

Vous pouvez ajouter un port aux règles avec le paramètre "port". par exemple.:

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
0
Sebastian