web-dev-qa-db-fra.com

Comment exécuter un script en cas de changement de votre adresse IP locale?

Avant de marquer comme un doublon, il s’agit du pas du DNS dynamique ou de choses similaires.

Je sais comment exécuter un script chaque fois que mon réseau est mis en place; il suffit d'ajouter un script dans le répertoire /etc/NetworkManager/dispatcher.d comme celui-ci:

#!/bin/bash

IF=$1
STATUS=$2

case "$2" in
        up)
        logger -s "NM Script up $IF triggered"
        su rmano -c /home/romano/bin/myscript 
        ;;
        down)
        logger -s "NM Script down $IF triggered"
        ;;
        *)
        ;;
esac

Dans mon cas, myscript est un très simple ifconfig -a > ~/Dropbox/myifconfig.txt --- Je l’utilise parce que j’ai besoin de connaître mon adresse IP locale de partout dans l’Université, et elle changera souvent.

Jusqu'ici tout va bien, le système fonctionne bien. Mais malheureusement, le DHCP est ici configuré pour que l’adresse IP soit modifiée sans down/up de l’interface. Dans ce cas, le script n'est pas exécuté (logiquement) et le fichier n'est pas mis à jour.

Je ne peux pas utiliser une approche DynDNS car la modification est dans = locale IP, pas dans celle visible de l’extérieur.

Je pourrais interroger, en mettant simplement le script dans cron et l'exécuter à la minute près ou en écrire un autre légèrement plus complexe (... si l'adresse IP est modifiée, écrivez le fichier sinon ne faites rien) et le remettant comme tâche n'est pas élégant. La question est donc:

Est-il possible de déclencher un script lorsque mon adresse IP locale change?

MISE À JOUR 1

J'ai essayé de mettre un script dans /etc/dhcp/dhclient-enter-hooks.d/, basé sur le /etc/dhcp/dhclient-enter-hooks.d/resolvconf existant, mais il ne sera pas déclenché. Je soupçonne (confirmation nécessaire) que NM (gestionnaire de réseau) est en train de négocier lui-même, sans appeler la commande dhcp ...

15
Rmano

Selon la page de manuel de NetmorkManager, l’un des événements est

dhcp4-change
          The DHCPv4 lease has changed (renewed, rebound, etc).

Je pense que vous pouvez simplement changer

up) 

à

dhcp4-change|up)
10
Jeffery Williams

Je fournis un script qui écoute les signaux dbus, ce qui vous permettra de réagir plus rapidement que si vous deviez rechercher les modifications apportées à votre configuration réseau actuelle. Cela aide sur les systèmes où les scripts/etc/ne sont pas exécutés quand vous le souhaitez (comme sur mon système 14.04).

mes entrées/sorties hooks.d ne fonctionnent pas

NetworkManager démarre dhclient avec l’indicateur -sf /usr/lib/NetworkManager/nm-dhcp-client.action qui semble remplacer le comportement de hook d’entrée/sortie normal. Le comportement par défaut avec dhclient est d'appeler des scripts dans /etc/dhcp/dhclient-{enter,exit}-hooks.d. Ceux-ci ne sont pas appelés du tout sur mon système.

Mes scripts NetworkManager dispatcher.d ne fonctionnent pas non plus

Cependant, NM appelle un ensemble de scripts différent, dans /etc/NetworkManager/dispatcher.d, pour informer de divers événements. La page de manuel NetworkManager (8) définit les actions dhcp4-change et dhcp6-change qui sembleraient faire exactement ce que vous voulez. Malgré ce que dit la page de manuel, du moins sur mon système, seules les actions up et down sont appelées. Je ne peux pas obtenir ces scripts pour tirer sur autre chose. Ce n’est donc pas une excellente solution pour surveiller les changements d’IP.

donc, snoop directement sur les signaux dbus émis par NM

nm-dhcp-client.action ( source ), à partir de la ligne de commande, convertit simplement toutes les variables d'environnement définies par dhclient en un signal dbus. Ces variables d'environnement sont définies dans man dhclient-script (8). $new_ip_address est particulièrement intéressant. Comme le suggère @Bernhard, vous pouvez surveiller le signal et agir en conséquence en fonction de son contenu.

Voici un programme qui surveillera toutes les données d'événement signalées par ce binaire:

#!/bin/bash -e

#
# This script listens for the org.freedesktop.nm_dhcp_client signal.
# The signal is emitted every time dhclient-script would execute.
# It has the same contents as the environment passed to
# dhclient-script (8). Refer to manpage for variables of interest.
#

# "org.freedesktop.nm_dhcp_client" is an undocumented signal name,
# as far as I could tell. it is emitted by nm-dhcp-client.action,
# which is from the NetworkManager package source code.
# 

# detail: todo cleanup subprocess on exit. if the parent exits, 
#       the subprocess will linger until it tries to print
#       at which point it will get SIGPIPE and clean itself.
#       trap on bash's EXIT signal to do proper cleanup.


mkfifo /tmp/monitor-nm-change

(
    dbus-monitor --system "type='signal',interface='org.freedesktop.nm_dhcp_client'"
) > /tmp/monitor-nm-change &

exec </tmp/monitor-nm-change
rm /tmp/monitor-nm-change

while read EVENT; do
    #change this condition to the event you're interested in
    if echo "$EVENT" | grep -q BOUND6; then
        # do something interesting
        echo "current ipv6 addresses:"
        ip addr show | grep inet6
    fi
done

La sortie de dbus-monitor n’est pas simple à analyser dans les scripts. Peut-être est-il plus facile de déclencher la présence de certains mots clés, par exemple. new_ip_address, et à partir de là, utilisez différents outils pour obtenir les informations qui ont changé (par exemple, ip ou ifconfig).

# example output data from dbus-monitor for that signal
...
dict entry(
string "new_routers"
variant             array of bytes "192.168.2.11"
)
dict entry(
string "new_subnet_mask"
variant             array of bytes "255.255.255.0"
)
dict entry(
string "new_network_number"
variant             array of bytes "192.168.2.0"
)
dict entry(
string "new_ip_address"
variant             array of bytes "192.168.2.4"
)
dict entry(
string "pid"
variant             array of bytes "12114"
)
dict entry(
string "reason"
variant             array of bytes "REBOOT"
)
dict entry(
string "interface"
variant             array of bytes "eth0"
)
...

Donner un coup de feu!

4
init_js

Approche de polling avec le script python. L'idée de base est d'analyser en continu la sortie de ip -4 -o add show <INTERFACE> et de comparer le résultat actuel à l'itération précédente

#!/usr/bin/env python3
import subprocess
import sys

def get_ip():
    # Simple function that parses output
    # of ip command and returns interface ip
    # replace wlan7 with your interface
    command = 'ip -4 -o addr show wlan7'.split()
    ip = None
    try:
        ip = subprocess.check_output(command).decode().split()[3]
    except IndexError:
        return
    finally:
        if ip:
           return ip

def main():
    # do while loop
    # Exits only when change occurs
    address = get_ip()
    while address == get_ip():
          address = get_ip()

    # Trigger script once we're out of loop
    subprocess.call(['zenity','--info','--text','IP CHANGED'])


if __== '__main__':
    # use while loop if yout want this script to run
    # continuously
    while True:
        try:
            main()
        except KeyboardInterrupt:
            sys.exit()
3

Bien que NetworkManager utilise dhclient, il fournit ses propres fichiers binaires en remplacement des scripts dhclient. (Pour référence: vous pouvez trouver le binaire NM à l'adresse /usr/lib/NetworkManager/nm-dhcp-client.action).

Vous pourriez peut-être adopter une approche différente: NM émet un signal DBus pour tous les événements. Vous pouvez écouter l'événement approprié dans le DBus système et déclencher votre script en fonction de cela ...

1
Bernhard