Jak uruchomić skrypt, gdy zmieni się lokalny adres IP?

15

Przed oznaczeniem jako duplikat: nie chodzi o dynamiczny DNS lub podobne rzeczy.

Wiem, jak uruchomić skrypt za każdym razem, gdy moje sieci się zwiększają; wystarczy dodać skrypt do katalogu /etc/NetworkManager/dispatcher.dtakiego jak ten:

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

W moim przypadku myscriptjest to bardzo proste ifconfig -a > ~/Dropbox/myifconfig.txt--- używam go, ponieważ muszę znać moje lokalne IP z dowolnego miejsca na Uniwersytecie i to się często zmienia.

Jak dotąd tak dobrze, system działa dobrze. Niestety, tutaj DHCP jest skonfigurowany tak, że adres IP jest czasem zmieniany bez wyłączania / zwiększania interfejsu. W takim przypadku skrypt nie jest (logicznie) uruchamiany, a plik nie jest aktualizowany.

Nie mogę użyć podejścia DynDNS, ponieważ zmiana dotyczy lokalnego adresu IP, a nie zewnętrznego.

Mógłbym sondować, po prostu umieszczając skrypt w cronie i uruchamiając go co minutę lub pisząc nieco bardziej skomplikowany (... jeśli IP zostanie zmieniony, napisz plik, w przeciwnym razie nic nie rób) i umieszczając go ponownie jako zadanie w tle, ale to nie jest elegancki. Pytanie brzmi:

Czy jest jakiś sposób, aby uruchomić skrypt, gdy zmieni się mój lokalny adres IP?

AKTUALIZACJA 1

Próbowałem umieścić skrypt w /etc/dhcp/dhclient-enter-hooks.d/oparciu o istniejący /etc/dhcp/dhclient-enter-hooks.d/resolvconf, ale nie zostanie on uruchomiony. Podejrzewam (wymagane potwierdzenie), że NM (menedżer sieci) sam negocjuje protokół dhcp, bez wywoływania polecenia dhcp ...

Rmano
źródło
1
wygląda na to, że powinno to być możliwe za pomocą dhclient-enter-hooks.dskryptu ... ale nigdy tego nie próbowałem! Istniejący /etc/dhcp/dhclient-enter-hooks.d/resolvconfskrypt może być pomocny pod względem składni i jakich sygnałów szukać ( "$reason" == "BOUND"być może?)
steeldriver
@steeldriver wydaje się, że skrypt nie został uruchomiony. Podejrzewam, że NM zajmuje się obsługą DHCP ... rozejrzy się. W każdym razie dzięki.
Rmano

Odpowiedzi:

10

Według strony podręcznika NetmorkManager jedno ze zdarzeń to

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

Myślę, że możesz po prostu zmienić

up) 

do

dhcp4-change|up)
Jeffery Williams
źródło
To działa (w pewnym sensie). Skrypt jest uruchamiany nawet trochę za dużo; spowoduje to nawet odnowienie bez zmian adresu IP. Wyobrażam sobie, że będę musiał wykonać trochę więcej skryptów bashowych. Morał: przeczytaj całą zawartość strony man!
Rmano
Poczekaj chwilę (nigdy nie wiesz ...), a następnie przypisz nagrodę. Dzięki!
Rmano
z mojego doświadczenia z 14.04 mogę otrzymywać wydarzenia tylko w górę i w dół w ten sposób. pozostałe zdarzenia nigdy nie uruchamiają skryptów w aktualizacji.d.
init_js
4

Dostarczam skrypt, który nasłuchuje na sygnałach dbus, co pozwoli ci zareagować szybciej niż gdybyś sondował zmiany w obecnej konfiguracji sieci. Pomaga w systemach, w których skrypty / etc / nie są wykonywane, kiedy chcesz (tak jak w moim systemie 14.04).

moje haki wejścia / wyjścia. d nie działają

NetworkManager uruchamia dhclient z flagą, -sf /usr/lib/NetworkManager/nm-dhcp-client.actionktóra wydaje się zastępować normalne zachowanie przechwytywania wejścia / wyjścia. Domyślnym działaniem dhclient jest wywoływanie skryptów /etc/dhcp/dhclient-{enter,exit}-hooks.d. Te w ogóle nie są wywoływane w moim systemie.

moje skrypty dispatcher.d NetworkManager również nie działają

NM wywołuje jednak inny zestaw skryptów w /etc/NetworkManager/dispatcher.dcelu informowania o różnych zdarzeniach. Strona man NetworkManager (8) definiuje dhcp4-changei dhcp6-changeakcje, które wydają się robić dokładnie to, co chcesz. Wbrew temu, co twierdzi strona podręcznika, w moim systemie co najmniej, tylko upi downdziałania się powoływać. Nie mogę zmusić tych skryptów do odpalenia na czymkolwiek innym. Dlatego też nie jest to świetna droga do monitorowania zmian IP.

więc snoop bezpośrednio na sygnałach dbus emitowanych przez NM

nm-dhcp-client.action( źródło ), z wiersza poleceń, po prostu konwertuje wszystkie zmienne środowiskowe ustawione przez dhclient na sygnał dbus. Te zmienne środowiskowe są zdefiniowane w man dhclient-script(8). Jednym ze szczególnie interesujących jest $new_ip_address. Jak sugeruje @Bernhard, możesz zrobić, aby monitorować sygnał i odpowiednio postępować w oparciu o jego zawartość.

Oto program, który podejmie wszystkie dane zdarzenia zasygnalizowane przez ten plik binarny:

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

Dane wyjściowe dbus-monitor nie są łatwe do przeanalizowania w skryptach. Być może łatwiej jest wywołać obecność określonych słów kluczowych, np. new_ip_addressI stamtąd użyć różnych narzędzi, aby uzyskać informacje, które uległy zmianie (np. Ip lub 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"
)
...

Spróbuj!

init_js
źródło
Wielkie dzięki! Na szczęście (dla mnie) jestem z powrotem w domu, gdzie mogę kontrolować mój serwer DHCP ... ale dam mu szansę, ponieważ nauka o DBus jest jedną z rzeczy w mojej kolejce, a twoja to wspaniały początek.
Rmano
3

Podejście ankietowe ze skryptem python. Podstawową ideą jest ciągłe analizowanie wyników ip -4 -o add show <INTERFACE>i porównywanie bieżącego wyniku z poprzednią iteracją

#!/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()
Sergiy Kolodyazhnyy
źródło
1

Chociaż NetworkManager używa dhclient, udostępnia własne pliki binarne jako zamiennik skryptów dhclient. (W celach informacyjnych: można znaleźć plik binarny NM w /usr/lib/NetworkManager/nm-dhcp-client.action).

Być może możesz przyjąć inne podejście: NM wydaje sygnał DBus na wszystkie zdarzenia. Możesz nasłuchiwać w systemie DBus odpowiedniego zdarzenia i uruchomić skrypt w oparciu o to ...

Bernhard
źródło