Como executar um script quando houver uma mudança no seu IP local?

15

Antes de marcar como duplicado: não há sobre DNS dinâmico ou coisas semelhantes.

Eu sei rodar um script toda vez que minhas redes sobem; é uma simples questão de adicionar um script no diretório /etc/NetworkManager/dispatcher.d como este:

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

No meu caso, myscript é muito simples ifconfig -a > ~/Dropbox/myifconfig.txt --- Eu uso porque preciso saber meu IP local de qualquer lugar da universidade, e isso muda com frequência.

Até aí tudo bem, o sistema funciona bem. Mas infelizmente o DHCP aqui está configurado para que o IP seja alterado sem um down / up da interface. Nesse caso, o script não é (logicamente) executado e o arquivo não é atualizado.

Não consigo usar uma abordagem DynDNS porque a alteração está no IP local , não no visível externamente.

Eu poderia pesquisar, simplesmente colocando o script no cron e executá-lo a cada minuto ou escrever um pouco mais complexo (... se o IP for alterado, grave o arquivo, caso contrário, não faça nada) e colocá-lo novamente como tarefa em segundo plano , mas não é elegante. Então a questão é:

Existe alguma maneira de acionar um script quando meu IP local muda?

ATUALIZAÇÃO 1

Eu tentei colocar um script em /etc/dhcp/dhclient-enter-hooks.d/ , com base no /etc/dhcp/dhclient-enter-hooks.d/resolvconf existente, mas ele não será acionado. Eu suspeito (confirmação necessária) que o NM (network manager) está fazendo a negociação dhcp sozinho, sem chamar o comando dhcp ...

    
por Rmano 20.03.2014 / 16:18

4 respostas

10

De acordo com a página man do NetmorkManager, um dos eventos é

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

Eu acho que você pode simplesmente mudar

up) 

para

dhcp4-change|up)
    
por Jeffery Williams 26.03.2014 / 00:22
4

Estou fornecendo um script que escuta sinais de dbus, o que permitirá que você reaja mais rápido do que se estivesse pesquisando alterações na sua configuração de rede atual. Isso ajuda em sistemas onde os scripts / etc / não são executados quando você gostaria que eles fossem executados (como no meu sistema 14.04).

meus ganchos de entrada / saída.d não funcionam

O NetworkManager inicia o dhclient com o sinalizador -sf /usr/lib/NetworkManager/nm-dhcp-client.action , que parece anular o comportamento normal do gancho de entrada / saída. O comportamento padrão do dhclient é chamar scripts em /etc/dhcp/dhclient-{enter,exit}-hooks.d . Aqueles não são chamados no meu sistema.

meus scripts do Dispatcher.d do NetworkManager não funcionam

O NM, no entanto, invoca um conjunto diferente de scripts, em /etc/NetworkManager/dispatcher.d , para informar sobre vários eventos. A página man do NetworkManager (8) define dhcp4-change e dhcp6-change ações que parecem fazer exatamente o que você quer. Apesar do que diz a página de manual, pelo menos no meu sistema, apenas up e down actions são invocadas. Não consigo fazer com que esses scripts disparem em mais nada. Portanto, isso não é uma ótima maneira de monitorar as alterações de IP.

então, bisbilhotar diretamente nos sinais dbus emitidos por NM

nm-dhcp-client.action ( source ), do linha de comando, simplesmente converte todas as variáveis de ambiente definidas pelo dhclient em um sinal dbus. Essas variáveis de ambiente são definidas em man dhclient-script (8). Um de interesse particular é $new_ip_address . O que você poderia fazer, como sugerido por @Bernhard, é monitorar o sinal e agir de acordo com seu conteúdo.

Aqui está um programa que irá espionar todos os dados do evento sinalizados por esse binário:

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

A saída do dbus-monitor não é simples de analisar em scripts. Talvez seja mais fácil desencadear a presença de uma determinada palavra-chave, por exemplo new_ip_address e, a partir daí, usam ferramentas diferentes para obter as informações alteradas (por exemplo, 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"
)
...

Dê uma chance!

    
por init_js 05.09.2016 / 15:17
3

Polling approach com script python. A ideia básica é analisar continuamente a saída de ip -4 -o add show <INTERFACE> e comparar o resultado atual com a iteração anterior

#!/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()
    
por Sergiy Kolodyazhnyy 09.09.2016 / 06:19
1

Embora o NetworkManager esteja usando o dhclient, ele fornece seus próprios binários como um substituto para os scripts do dhclient. (Para referência: você pode encontrar o binário NM em /usr/lib/NetworkManager/nm-dhcp-client.action ).

Talvez você possa adotar uma abordagem diferente: o NM está emitindo um sinal DBus em todos os eventos. Você pode escutar no sistema DBus o evento apropriado e acionar seu script com base nisso ...

    
por Bernhard 25.03.2014 / 18:41