Como executar um script quando há uma alteração no seu IP local?

15

Antes de marcar como duplicado: não se trata de DNS dinâmico ou algo semelhante.

Eu sei como executar um script toda vez que minhas redes são ativadas; é simples adicionar um script no diretório /etc/NetworkManager/dispatcher.dcomo 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 o uso porque preciso conhecer meu IP local de qualquer lugar da Universidade, e ele mudará frequentemente.

Até aí tudo bem, o sistema funciona bem. Infelizmente, porém, o DHCP aqui está configurado para que o IP seja alterado em algum momento sem uma redução / redução da interface. Nesse caso, o script (logicamente) não é executado e o arquivo não é atualizado.

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

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

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

ATUALIZAÇÃO 1

Tentei inserir um script /etc/dhcp/dhclient-enter-hooks.d/, com base no existente /etc/dhcp/dhclient-enter-hooks.d/resolvconf, mas ele não será acionado. Eu suspeito (confirmação necessária) que NM (gerenciador de rede) está fazendo a negociação dhcp por si só, sem chamar o comando dhcp ...

Rmano
fonte
11
parece que deveria ser possível através de um dhclient-enter-hooks.dscript ... mas nunca tentei! O actual /etc/dhcp/dhclient-enter-hooks.d/resolvconfroteiro pode ser útil em termos de sintaxe e que sinais de olhar para ( "$reason" == "BOUND"talvez?)
steeldriver
@steeldriver parece que o script não foi acionado. Eu suspeito que o NM cuida do tratamento do DHCP ... vai olhar em volta. Obrigado mesmo assim.
Rmano 20/03

Respostas:

10

De acordo com a página de manual 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)
Jeffery Williams
fonte
Funciona (mais ou menos). O script é acionado até demais; mesmo uma renovação sem alterações no IP o acionará. Eu imagino que vou ter que fazer um pouco mais de scripts bash. Moral: leia todo o conteúdo da página de manual!
Rmano 26/03
Vai esperar um pouco (você nunca sabe ...) e depois atribuir a recompensa. Obrigado!
Rmano 26/03
na minha experiência em 14.04, só posso receber eventos para cima e para baixo dessa maneira. os outros eventos nunca acionam scripts no update.d
init_js 5/09
4

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

meus hooksd de entrada / saída não funcionam

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

meus scripts do dispatcher do NetworkManager.d também não funcionam

NM, no entanto, invoca um conjunto diferente de scripts, in /etc/NetworkManager/dispatcher.d, para informar sobre vários eventos. A página do manual NetworkManager (8) define dhcp4-changee dhcp6-changeações que parecem fazer exatamente o que você deseja. Apesar do que a página de manual diz, pelo menos no meu sistema, apenas upe as downações são invocadas. Não consigo fazer com que esses scripts disparem em mais nada. Portanto, este também não é um ótimo caminho para monitorar alterações de IP.

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

nm-dhcp-client.action( fonte ), na 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 particular interesse é $new_ip_address. O que você pode fazer, conforme sugerido por @Bernhard, é monitorar o sinal e agir de acordo com o conteúdo.

Aqui está um programa que espionará todos os dados de eventos 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 acionar a presença de determinadas palavras-chave, por exemplo new_ip_address, e a partir daí usar ferramentas diferentes para obter as informações que foram 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"
)
...

Experimente!

init_js
fonte
Muito obrigado! Felizmente (para mim) estou de volta em casa, onde posso controlar meu servidor DHCP ... mas vou tentar, porque aprender sobre o DBus é uma das coisas na minha fila e a sua é um começo maravilhoso.
Rmano
3

Abordagem de sondagem com script python. A idéia básica é analisar continuamente a saída 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()
Sergiy Kolodyazhnyy
fonte
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 ouvir no DBus do sistema o evento apropriado e acionar seu script com base nisso ...

Bernhard
fonte