[SCRIPT] Ip dynamique & Iptables

Fermé
caledo120 Messages postés 7 Date d'inscription mardi 9 mai 2006 Statut Membre Dernière intervention 31 août 2012 - 12 août 2009 à 03:24
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 - 12 août 2009 à 12:42
Bonjour,

Voici un script qui va vous permettre d'ajouter votre adresse dynamique (dyndns, ...) automatiquement dans Iptables.

Fichier : update_iptables.sh

#!/bin/bash
#************************************************#
#           UPDATE IPTABLE  v0.2                #
#                                                #
#           written by Caledo120                 #
#           Contact : 120@caledonien.org         #
#                12/02/2009                      #
#                                                #
#************************************************#
# - > Permet d'update votre ip DYNS, dans IPTABLES.
#************************************************#
# - > PATH & VAR
# Emplacement du dossier du script
CHROOT_PATH="<ROOT_PATH>"
IP_SERVEUR="<IP WAN DU SERVEUR >";

# ne pas modifier
DOSSIER_LOG="${CHROOT_PATH}/log"
FICHIER_FUNCTION="${CHROOT_PATH}/start.sh"
TOTAL_TRUE=0; TOTAL_FALSE=0;
if [ ! -f ${FICHIER_FUNCTION} ]; then exit 1; fi

# - > OPTIONS
DEBUG="TRUE" 
debugReverseArray="TRUE"
NOTIF_MAIL="FALSE";

if [ "${NOTIF_MAIL}" == "TRUE" ]
then
	NOTIF_MAIL_COMMUN="TRUE" # Permet de grouper les logs.
fi
##########################################################################################################
#****************************************#
#******** <TITRE >  *********************#
#****************************************#

TITRE="<TITRE DE LA TACHE> : ${URL_DYNDNS}";
# IP_IPTABLES = Renseignez les url en dyndns (peux importe le domaine), séparer par un espace les url
# exemple : IP_IPTABLES=(toto.ath.cx tata.dyndns.org);
IP_IPTABLES=(<VOS DYNDNS>)
# PORT_IPTABLES = Renseignez les ports à ouvrir
# exemple : PORT_IPTABLES=(22 3000 3128 10000);
PORT_IPTABLES=(<PORTS>)
# Permet d'autoriser la régle en sortie (FILTER OUTPUT)
REGLE_OUTPUT="TRUE"; 
# Votre interface réseau : exemple : eth0
INTERFACE_RESEAU="eth0"
#ne pas modifier
source ${FICHIER_FUNCTION};



#************************************#
#******** FIN ***********************#
#************************************#
#ne pas modifier
if [ "${NOTIF_MAIL_COMMUN}" == "TRUE" ]
then
	echo "TOTAL UPDATE  == > $TOTAL_TRUE" >> "${DOSSIER_LOG}/commun_update.log"
	notification ${TOTAL_TRUE} "${DOSSIER_LOG}/commun_update.log" "vincent@canl.nc" "MAJ IPTABLES COMMUN" >> "${DOSSIER_LOG}/commun_update.log"
fi
test -f "${DOSSIER_LOG}/commun_update.log" && rm -f "${DOSSIER_LOG}/commun_update.log"


Fichier : start.sh

#************************************************#
#**************** LIB / FUNCTION ****************#
#************************************************#
if [ ! -d ${DOSSIER_LOG} ]; then mkdir ${DOSSIER_LOG} || exit;  fi;

# - > Permet d'inserer un saut de ligne dans le log
br ()
{
	echo " ";
}

# - > Permet de personnaliser le log en fonction des etats & resultats, du backup
# ARG P1(return_status) P2(message)
status()
{
	if [ "${1}" != '' ] && [ "${2}" != '' ]
	then

		case ${1} in
			0)
				echo "[- TRUE -] -- > ${2}"
			;;
			1)
				echo "[- FALSE -] -- > ${2}"
				let TOTAL_FALSE++;
			;;
			2)
				echo "[- NOTICE -] -- > ${2}"
			;;
			3)
				echo "[- DIE -] -- > ${2}";
				let TOTAL_FALSE++;
				exit 1
			;;
			4)
				echo "[- TRUE -] -- > ${2}"
				TOTAL_TRUE=$((${TOTAL_TRUE}+1));
			;;
		esac
	else
		status 1 "fct 'status' Paramètre Manquant P1(${1}) P2(${2})"
		let TOTAL_FALSE++;
		return 1
	fi
}
function check_ip()
{
    echo "$1" | egrep -q "^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$"
    return_check=$?
    #if [ ${return_check} != 0 ]; then echo "IP -> ${1} <- INVALIDE !!"; fi
    return ${return_check}
}

reverseArray()
{
	
	if [ ${debugReverseArray} == "TRUE" ]; then echo "fcy(reverseArray) ARG1 (${arrayToReverse[*]})"; fi
	iReverse=0;
	while [ $iReverse -lt ${#arrayToReverse[*]} ]
	do
		newReverseArray[$iReverse]=${arrayToReverse[`expr ${#arrayToReverse[*]} - $iReverse - 1`]}
		let iReverse++
	done
	if [ -z ${newReverseArray} ]; then return 0; fi
	if [ ${debugReverseArray} == "TRUE" ]; then echo "fcy(reverseArray) newReverseArray=(${newReverseArray[*]})"; fi
	return 1;
}

# Permet de supprimer une adresse IP dans iptables
# ARG1 = Direction e/s IPTABLES  (FILTER Input/Output)
# ARG2 = Ip a supprimer
supprimeIpIptables ()
{
	echo "Supprime IP IPTABLE ARG1(${1}) ARG2(${2})";

	direcionInputeOutput=${1};
	adresseIp=${2}

	arrayToReverse=($(iptables --list ${direcionInputeOutput} --numeric --line-numbers |grep ${adresseIp} |awk '{print $1}'))
	reverseArray $arrayToReverse
  # echo ${newReverseArray[*]}

	i=0;
	while [ $i -lt ${#newReverseArray[*]} ]
	do
		echo "${chrootBinIptables} -D ${direcionInputeOutput} ${newReverseArray[${i}]}"
		${chrootBinIptables} -D ${direcionInputeOutput} ${newReverseArray[${i}]}
		let i++
	done
	echo
}

# ARG1(IP) ARG2(PORT) ARG3(NOM DE LA CHAINE IPTABLES} ARG4{INTERFACE RESEAU})
maj_ipdyn_iptables ()
{
	##################################################
	# TEST ARGUMENTS && INITIALISATION DES VARIABLES
	##################################################
	#echo "1 $1 & 2 $2 & 3 $3 & 4 $4"
	! test -z ${1} && ! test -z ${2} && ! test -z ${3} && ! test -z ${4} || echo "fct 'maj_ipdyn_iptables' Paramètre Manquant P1(${1}) P2(${2}) P3(${3} P4(${4})"
	IP_CHECK=${1}; PORT=${2}; CHAINE_IPTABLES=${3}; INTERFACE=${4}; error_count=0; true_count=0

	######################################################################################
	# 1. Detection du format de < IP_CHECK >
	# ---------------------------------------
	# Peux être :
	#   * Une adresse IP : < 0.0.0.0 >
	#   * Un nom DNS < mondyndns.dyndns.org >
	######################################################################################
	LOG_DYN="${DOSSIER_LOG}/${IP_CHECK}.ip"

	# SI < IP_CHECK > == une adresse IP
	check_ip ${IP_CHECK} && ADR_IP="${IP_CHECK}";
	# SINON on test de resoudre l'IP en nom DNS
	if [ -z "${ADR_IP}" ]
	then
		ADR_IP=`host ${IP_CHECK} | cut -d \  -f 4`
	fi

	# Test du format de l'IP
	check_ip ${ADR_IP} || status 3 "Problème de test du format de l'ip < ${IP_CHECK} -- > < ${ADR_IP} > > !!!"

	if [ ! -f "${LOG_DYN}" ]; then echo ${ADR_IP} > ${LOG_DYN} || status 3 "Problème de creation du fichier log < ${LOG_DYN} > !!!"; fi;

	#################################################################
	# 2. On test que l'ip ne soit pas deja enregistre dans IPTABLES #
	#################################################################
	echo "${IP_ARRAY}" ${PORT_ARRAY} "${REGLE_OUTPUT}" "${INTERFACE_RESEAU}"   >> debug_txt
	${chrootBinIptables} -L -n | grep $ADR_IP |grep ${PORT} &>/dev/null
	if [ ${?} != 0 ]
	then
		echo '~~';
		echo "### UPDATE de ${IP_CHECK}"; 

		# Récuperation de l'ancienne adresse IP
		OLD_IP=$(/bin/cat ${LOG_DYN});
		# Sauvegarde de l'Ip courante
		echo ${ADR_IP} > ${LOG_DYN};

		if [ ! -z "${OLD_IP}" ] && [ "${OLD_IP}" != "${ADR_IP}" ]
		then
			# Avant de mettre a jour la nouvelle adresse, on supprime l'ancienne règle associe à l'IP
			supprimeIpIptables 'INPUT' ${OLD_IP}; status ${?} "Suppression de l'ancienne règle de INPUT (${OLD_IP} -- > ${IP_CHECK})"; br
			supprimeIpIptables 'OUTPUT' ${OLD_IP}; status ${?} "Suppression de l'ancienne règle de OUTPUT (${OLD_IP} -- > ${IP_CHECK})"; br
	 	fi

		# Mise en place de la règle pour la nouvelle IP
		COMMUN="-m state --state new -p tcp --dport ${PORT} -d ${IP_SERVEUR} -s ${ADR_IP} -j ACCEPT";
	if [ ${REGLE_OUTPUT} == "TRUE" ]
	then	  	
	${chrootBinIptables} -t filter -A OUTPUT ${COMMUN} 1>/dev/null
	fi
		${chrootBinIptables} -t filter -A INPUT -i ${INTERFACE_RESEAU} ${COMMUN} 1>/dev/null

	  return_iptable=${?}
	  #echo "/sbin/iptables -t filter -I ${CHAINE_IPTABLES} -i  ${INTERFACE} -m state --state new -p tcp --dport ${PORT} -d ${IP_SERVEUR} -s ${ADR_IP} -j ACCEPT";
	  
	  if [ ${return_iptable} == 0 ]; then return_iptable=4; else return_iptable=1; fi;
	  if [ ${return_iptable} != 0 ]; then status ${return_iptable} "Creation de la nouvelle regle < ${IP_CHECK} -- > ${ADR_IP}:${PORT} >"; fi;

	  	test_iptables_chaine=$(${chrootBinIptables} -L -n | grep $ADR_IP |grep ${PORT});
		status ${?} "Test de la regle : ${test_iptables_chaine}";
		echo '~~';

	else
		if [ "${DEBUG}" == "TRUE" ]
		then
		 # On affiche la règle associe à l'IP dans IPTABLES
		 status 2 "${IP_CHECK} -- > ${ADR_IP}:${PORT} | IP DEJA DANS IPTABLES"
		fi
    test_iptables_chaine=$(${chrootBinIptables} -L -n | grep $ADR_IP |grep ${PORT}); status 2 "${test_iptables_chaine}" 1>/dev/null
	fi

	
	return ${TOTAL_TRUE}
}

# ARG1(compteur) ARG2(fichier_log_notif) ARG3(adresse email de notification)
notification ()
{
	if [ "${NOTIF_MAIL}" == "TRUE" ]
	then
		! test -z ${1} && ! test -z ${2} || echo "fct 'notification' Paramètre Manquant P3(${3} P4(${4})"
		! test -z ${3} || ! test -z ${4} || echo "fct 'notification' Paramètre Manquant P3(${3} P4(${4})"

		compteur=${1}; fichier_log_notif="${2}"; mail_to="${3}"; sujet="${4}"

		if [ ${compteur} -ne 0 ] && [ $(/bin/cat "$fichier_log_notif" |wc -l) != 0 ]
		then
			/bin/mail "${mail_to}" -s "${sujet}" < "$fichier_log_notif"
			echo "Envoi du mail au destinaire suivant : < ${mail_to} >";
		fi
	fi
}
#************************************************#
#******** INITIALISATION  ***********************#
#************************************************#
chrootBinIptables=`/usr/bin/which iptables` || status 3 "Probleme pour trouver l'executable < iptables>"
echo "
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ < ${TITRE} > ~~
# ~~ < PORT ${PORT_IPTABLES[*]} > ~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
" > "${DOSSIER_LOG}/${PORT_IPTABLES}.log"

count_return_true=0;

i_ip=0;
while [ $i_ip -lt ${#IP_IPTABLES[*]} ];
do
	IP_ARRAY=${IP_IPTABLES[$i_ip]};
	
	i_port=0;
	while [ $i_port -lt ${#PORT_IPTABLES[*]} ];
	do
		PORT_ARRAY=${PORT_IPTABLES[$i_port]};
		$(maj_ipdyn_iptables "${IP_ARRAY}" ${PORT_ARRAY} "${REGLE_OUTPUT}" "${INTERFACE_RESEAU}" >> "${DOSSIER_LOG}/${PORT_IPTABLES}.log")
		count_return_true=$((${?}))

		TOTAL_TRUE=$((${count_return_true}));
		let i_port++
	done
	#
	if [ "${NOTIF_MAIL_COMMUN}" == "TRUE" ]
	then
		/bin/cat "${DOSSIER_LOG}/${PORT_IPTABLES}.log" >> "${DOSSIER_LOG}/commun_update.log"
	fi
	
	let i_ip++
done
echo '~~' >> "${DOSSIER_LOG}/${PORT_IPTABLES}.log"
if [ "${NOTIF_MAIL_COMMUN}" == "FALSE" ]
then
	echo "TOTAL UPDATE  == > $TOTAL_TRUE" >> "${DOSSIER_LOG}/${PORT_IPTABLES}.log"
	notification ${count_return_true} "${DOSSIER_LOG}/${PORT_IPTABLES}.log" "vincent@canl.nc" "MAJ IPTABLES ${PORT_IPTABLES}" >> "${DOSSIER_LOG}/${PORT_IPTABLES}.log"
fi

#if [ "${DEBUG}" == "TRUE" ]; then /bin/cat "${DOSSIER_LOG}/${PORT_IPTABLES}.log"; fi;

/bin/cat "${DOSSIER_LOG}/${PORT_IPTABLES}.log";
/bin/rm -f "${DOSSIER_LOG}/${PORT_IPTABLES}.log"


N'oubliez pas de faire un chmod +x update_iptables.sh

Bonne journée

1 réponse

jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
12 août 2009 à 12:42
0