Як запустити скрипт, коли місцевий IP-код зміниться?


15

Перш ніж позначити як дублікат: мова не йде про динамічний DNS або подібні речі.

Я знаю, як запускати сценарій щоразу, коли мої мережі піднімаються вгору; це проста тема додавання сценарію в такий каталог /etc/NetworkManager/dispatcher.d:

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

У моєму випадку myscriptце дуже просто ifconfig -a > ~/Dropbox/myifconfig.txt--- я використовую його, бо мені потрібно знати свій локальний IP звідусіль в університеті, і він часто змінюватиметься.

Поки що добре, система працює нормально. Але, на жаль, DHCP тут налаштований так, що IP-то колись змінюється без пониження / вгору інтерфейсу. У цьому випадку сценарій (логічно) не запускається, а файл не оновлюється.

Я не можу використовувати підхід DynDNS, оскільки зміна є локальним IP, а не зовнішнім.

Я міг би опитувати, просто поставивши скрипт у cron і виконуючи його щохвилини або написати трохи складніший (... якщо IP-адресу змінено, напишіть файл інакше нічого не робити) і знову поставте його як фонове завдання, але це не елегантний. Отже, питання:

Чи є спосіб запустити скрипт, коли мій локальний IP зміниться?

ОНОВЛЕННЯ 1

Я спробував поставити сценарій /etc/dhcp/dhclient-enter-hooks.d/, заснований на існуючому /etc/dhcp/dhclient-enter-hooks.d/resolvconf, але це не буде спровоковано. Я підозрюю (потрібне підтвердження), що NM (менеджер мережі) проводить переговори dhcp сам, не викликаючи команду dhcp ...


1
схоже , це повинно бути можливо через dhclient-enter-hooks.dскрипт ... але я ніколи не пробував! Існуючий /etc/dhcp/dhclient-enter-hooks.d/resolvconfсценарій може бути корисним з точки зору синтаксису та на які сигнали звернути увагу ( "$reason" == "BOUND"можливо?)
steeldriver

@steeldriver здається, що сценарій не спрацьовує. Я підозрюю, що НМ піклується про обробку DHCP ... озирнуться. Все одно, дякую.
Рмано

Відповіді:


10

Як повідомляє сторінка man для NetmorkManager, одна з подій - це

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

Я думаю, ви можете просто змінити

up) 

до

dhcp4-change|up)

Це (сортування) працює. Сценарій спрацьовує навіть трохи занадто багато; навіть оновлення без змін IP-адреси призведе до цього. Я думаю, що мені доведеться зробити трохи більше сценаріїв. Мораль: прочитайте весь вміст чоловічої сторінки!
Рмано

Зачекаємо трохи (ти ніколи не знаєш ...), а потім призначимо щедрості. Спасибі!
Рмано

з мого досвіду 14.04, я можу колись отримувати події тільки вгору і вниз таким чином. інші події ніколи не запускають сценарії в update.d
init_js

4

Я надаю сценарій, який слухає сигнали dbus, що дозволить вам реагувати швидше, ніж якби ви опитувались на зміни вашої поточної конфігурації мережі. Це допомагає в системах, де сценарії / etc / не виконуються тоді, коли ви хотіли б їх (як у моїй системі 14.04).

мої вхідні / вихідні гачки.d не працюють

NetworkManager запускає dhclient з прапора, -sf /usr/lib/NetworkManager/nm-dhcp-client.actionякий, здається, перекриває нормальну поведінку гачка введення / виходу. Типовою поведінкою для dhclient є виклик сценаріїв в /etc/dhcp/dhclient-{enter,exit}-hooks.d. Тих, хто взагалі не дзвонить у мою систему.

мої сценарії NetworkManager discher.dd також не працюють

Однак НМ використовує інший набір сценаріїв /etc/NetworkManager/dispatcher.dдля інформування про різні події. Довідкова сторінка NetworkManager (8) визначає dhcp4-changeта dhcp6-changeдії, які, здавалося б, роблять саме те, що ви хочете. Незважаючи на те, що написано на сторінці, принаймні, у моїй системі, тільки upі downдії викликаються. Я не можу змусити цих сценаріїв запустити щось інше. Тому це не є великим способом моніторингу змін ІР.

таким чином, прослуховуйте безпосередньо на dbus-сигнали, що випромінюються NM

nm-dhcp-client.action( джерело ) з командного рядка просто перетворює всі змінні середовища, встановлені dhclient, у сигнал dbus. Ці змінні середовища визначені в man dhclient-script(8). Особливий інтерес викликає $new_ip_address. Що ви можете зробити, як пропонує @Bernhard, - це контролювати сигнал та діяти відповідно до його вмісту.

Ось програма, яка буде переносити всі дані про події, передані цим бінарним файлом:

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

Вихід dbus-монітора не є простим для розбору в сценаріях. Можливо, це легше запустити на наявність певного ключового слова, наприклад new_ip_address, і звідти використовувати різні інструменти для отримання інформації, яка змінилася (наприклад, ip або 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"
)
...

Дай постріл!


Дуже дякую! На щастя (для мене) я знову вдома, де я можу керувати своїм сервером DHCP ... але я зроблю це, бо дізнатися про DBus - це одне з моїх черг, а ваш - чудовий початок.
Рмано

3

Підхід до опитування за допомогою сценарію python. Основна ідея полягає в постійному аналізі результатів ip -4 -o add show <INTERFACE>і порівнянні поточного результату з попередньою ітерацією

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

Хоча NetworkManager використовує dhclient, він надає власні бінарні файли як заміну для dhclient-скриптів. (Для довідки: ви можете знайти бінарний файл NM за адресою /usr/lib/NetworkManager/nm-dhcp-client.action).

Можливо, ви можете скористатися іншим підходом: NM видає сигнал DBus про всі події. Ви можете слухати в системному DBus для відповідної події та запускати свій сценарій на основі цього ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.