Как запустить скрипт при изменении локального 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 ...

Rmano
источник
1
похоже , это должно быть возможно через dhclient-enter-hooks.dскрипт ... но я никогда не пробовал! Существующий /etc/dhcp/dhclient-enter-hooks.d/resolvconfскрипт может быть полезен с точки зрения синтаксиса и каких сигналов искать ( "$reason" == "BOUND"может быть
,?
@steeldriver кажется, что сценарий не запущен. Я подозреваю, что NM заботится об обработке DHCP ... будет смотреть вокруг. Спасибо, в любом случае.
Rmano

Ответы:

10

Согласно справочной странице для NetmorkManager, одно из событий

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

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

up) 

в

dhcp4-change|up)
Джеффри Уильямс
источник
Это (вроде) работает. Сценарий срабатывает даже слишком много; даже обновление без изменений в IP вызовет его. Я полагаю, мне придется сделать немного больше сценариев Bash. Мораль: прочитайте все содержание справочной страницы!
Rmano
Немного подождем (вы никогда не узнаете ...), а затем назначите награду. Благодарность!
Rmano
по своему опыту 14.04 я могу получать события только таким образом. другие события никогда не запускают сценарии в файле update.d
init_js
4

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

мои входы / выходы не работают

NetworkManager запускает dhclient с флагом, -sf /usr/lib/NetworkManager/nm-dhcp-client.actionкоторый, кажется, переопределяет нормальное поведение входа / выхода. Поведение по умолчанию с dhclient - вызывать скрипты в /etc/dhcp/dhclient-{enter,exit}-hooks.d. Это не вызывается вообще в моей системе.

мои скрипты NetworkManager dispatcher.d тоже не работают

NM, однако, вызывает другой набор скриптов /etc/NetworkManager/dispatcher.dдля информирования о различных событиях. Страница man NetworkManager (8) определяет dhcp4-changeи dhcp6-changeдействия, которые, кажется, делают именно то, что вы хотите. Несмотря на то, что написано в man-странице, по крайней мере, в моей системе только upи downвыполняются действия. Я не могу заставить эти сценарии запускать что-либо еще. Так что это не очень хороший способ отслеживать изменения IP.

Итак, отслеживание непосредственно по сигналам dbus, излучаемым NM

nm-dhcp-client.action( source ) из командной строки просто преобразует все переменные окружения, установленные 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-monitor непросто проанализировать в скриптах. Возможно, легче инициировать наличие определенных ключевых слов, например 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"
)
...

Дать ему шанс!

init_js
источник
Большое спасибо! К счастью (для меня) я вернулся домой, где я могу контролировать свой DHCP-сервер ... но я сделаю это, потому что изучение DBus - одна из вещей в моей очереди, а ваша - прекрасное начало.
Rmano
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-scripts. (Для справки: вы можете найти двоичный файл NM в /usr/lib/NetworkManager/nm-dhcp-client.action).

Возможно, вы могли бы использовать другой подход: NM генерирует сигнал DBus для всех событий. Вы можете прослушать в системном DBus соответствующее событие и запустить свой сценарий на основе этого ...

Бернхард
источник