Come eseguire uno script quando si verifica una modifica nell'IP locale?


15

Prima di contrassegnare come duplicato: non si tratta di DNS dinamico o cose simili.

So come eseguire uno script ogni volta che la mia rete sale; si tratta semplicemente di aggiungere uno script nella directory /etc/NetworkManager/dispatcher.dcome questo:

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

Nel mio caso, myscriptè molto semplice ifconfig -a > ~/Dropbox/myifconfig.txt--- lo uso perché ho bisogno di conoscere il mio IP locale da ogni parte dell'Università, e cambierà spesso.

Fin qui tutto bene, il sistema funziona bene. Ma sfortunatamente il DHCP qui è configurato in modo tale che l'IP a volte sia cambiato senza un down / up dell'interfaccia. In tal caso lo script non viene (logicamente) eseguito e il file non viene aggiornato.

Non riesco a utilizzare un approccio DynDNS perché la modifica è nell'IP locale , non in quello visibile esternamente.

Potrei effettuare il polling, semplicemente mettendo lo script in cron ed eseguendolo ogni minuto o scriverne uno leggermente più complesso (... se l'IP viene modificato, scrivere il file altrimenti non fare nulla) e rimetterlo come attività in background, ma non è elegante. Quindi la domanda è:

Esiste un modo per attivare uno script quando cambia il mio IP locale?

AGGIORNAMENTO 1

Ho provato a inserire uno script /etc/dhcp/dhclient-enter-hooks.d/, basato sull'esistente /etc/dhcp/dhclient-enter-hooks.d/resolvconf, ma non verrà attivato. Ho il sospetto (conferma necessaria) che NM (gestore della rete) sta facendo la negoziazione dhcp da solo, senza chiamare il comando dhcp ...


1
sembra che dovrebbe essere possibile tramite uno dhclient-enter-hooks.dscript ... ma non l'ho mai provato! Lo /etc/dhcp/dhclient-enter-hooks.d/resolvconfscript esistente potrebbe essere utile in termini di sintassi e quali segnali cercare ( "$reason" == "BOUND"forse?)
steeldriver

@steeldriver sembra che lo script non sia attivato. Sospetto che NM si occupi della gestione DHCP ... si guarderà intorno. Grazie comunque.
Rmano,

Risposte:


10

Secondo la pagina man di NetmorkManager, uno degli eventi è

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

Penso che tu possa semplicemente cambiare

up) 

per

dhcp4-change|up)

Funziona. Lo script viene attivato anche un po 'troppo; anche un rinnovo senza cambiamenti nell'IP lo attiverà. Immagino che dovrò fare un po 'più di script bash. Morale: leggi tutto il contenuto della pagina man!
Rmano,

Aspetterò un po '(non lo saprai mai ...) e poi assegnerò la taglia. Grazie!
Rmano,

nella mia esperienza del 14.04, posso solo ricevere eventi su e giù in quel modo. gli altri eventi non attivano mai gli script in update.d
init_js il

4

Sto fornendo uno script che ascolta i segnali dbus, che ti consentirà di reagire più rapidamente rispetto a se dovessi eseguire il polling per le modifiche alla tua attuale configurazione di rete. Aiuta su sistemi in cui gli script / etc / non vengono eseguiti quando si desidera (come sul mio sistema 14.04).

i miei hook di entrata / uscita.d non funzionano

NetworkManager avvia dhclient con il flag -sf /usr/lib/NetworkManager/nm-dhcp-client.actionche sembra sovrascrivere il normale comportamento hook di entrata / uscita. Il comportamento predefinito con dhclient è di chiamare gli script/etc/dhcp/dhclient-{enter,exit}-hooks.d . Quelli non vengono chiamati affatto sul mio sistema.

gli script my NetworkManager dispatcher.d non funzionano neanche

NM, tuttavia, invoca un diverso set di script /etc/NetworkManager/dispatcher.dper informare di vari eventi. La pagina man NetworkManager (8) definisce dhcp4-changee le dhcp6-changeazioni che sembrano fare esattamente quello che vuoi. Nonostante quello che dice la pagina di manuale, sul mio sistema, almeno, solo upe downle azioni vengono invocati. Non riesco a far sparare quegli script su nient'altro. Quindi questa non è nemmeno una buona strada per monitorare le modifiche dell'IP.

quindi, curiosare direttamente sui segnali dbus emessi da NM

nm-dhcp-client.action( source ), dalla riga di comando, converte semplicemente tutte le variabili d'ambiente impostate da dhclient in un segnale dbus. Tali variabili di ambiente sono definite inman dhclient-script (8). Uno di particolare interesse è $new_ip_address. Quello che potresti fare, come suggerito da @ Bernard, è monitorare il segnale e agire di conseguenza in base al suo contenuto.

Ecco un programma che snooperà tutti i dati degli eventi segnalati da quel binario:

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

L'output di dbus-monitor non è semplice da analizzare negli script. Forse è più facile innescare la presenza di determinate parole chiave, ad esempio new_ip_address, e da lì utilizzare strumenti diversi per ottenere le informazioni modificate (ad esempio ip o 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"
)
...

Dagli Un colpo!


Molte grazie! Fortunatamente (per me) sono tornato a casa dove posso controllare il mio server DHCP ... ma ci proverò perché conoscere DBus è una delle cose nella mia coda, e il tuo è un inizio meraviglioso.
Rmano,

3

Approccio di polling con script Python. L'idea di base è analizzare continuamente l'output ip -4 -o add show <INTERFACE>e confrontare il risultato corrente con l'iterazione precedente

#!/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 __name__ == '__main__':
    # use while loop if yout want this script to run
    # continuously
    while True:
        try:
            main()
        except KeyboardInterrupt:
            sys.exit()

1

Sebbene NetworkManager stia usando dhclient, fornisce i propri file binari in sostituzione degli script dhclient. (Per riferimento: è possibile trovare il binario NM all'indirizzo/usr/lib/NetworkManager/nm-dhcp-client.action ).

Forse potresti adottare un approccio diverso: NM sta emettendo un segnale DBus su tutti gli eventi. È possibile ascoltare il DBus di sistema per l'evento appropriato e attivare lo script in base a questo ...

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.