Инструменты пользователя

Инструменты сайта


os:linux:common:massovoe_upravlenie_naznacheniem_ip-adresov

Управление массовым назначением IP-адресов

Описание

Иногда требуется управлять множеством IP-адресов на множестве компьютеров в сети. Для такого случая я написал скрипт в помощь. Использование его очень простое:

  • создать файл setip.sh с нижеследующим содержимым;
  • создать файл ip.list, содержащий строки вида: <ip-адрес> <имя_компьютера> <имя_интерфейса>;
  • запускать setip.sh при изменении ip.list.

Результатом работы скрипта будет удаление ненужных, а затем добавление новых IP-адресов.

Внимание: если в файле не будет указан какой-либо локальный интерфейс, операции с ним производиться не будут! Для решения этого, достаточно указать для всех интерфейсов хотя бы один, первичный, IP-адрес, даже если он не будет меняться.

Требования: установленные bash и iproute2.

Решение

Скрипт setip.sh

Для запуска скрипта в режиме тестирования (без реального изменения состояния интерфейсов), запускайте скрипт с ключом -t.

#!/bin/bash

dir="$(dirname $0)"
ipfile="ip.list"
hostname="$(hostname -f)"
tmpdir='/tmp'
test=false

while getopts 't' opt; do
    case $opt in
        't')
            test=true
            ;;
    esac
done

function ipsort()
{
    sort -n -t'.' -k1,1 -k2,2 -k3,3 -k4,4
}

declare iflist=''
declare -A ifpri=()
declare -A ifsec=()

while read ip host iface default; do
    if [ -n "$ip" ] && [ -n "$host" ] && [ -n "$iface" ] && [ "$host" = $hostname ]; then
        [ ${ip:0:1} = '#' ] && continue
        [ -z "$(echo -n $iflist | grep -w $iface)" ] && iflist="$iflist $iface"
        [ -z "$(echo $ip | grep '/')" ] && ip="$ip/32"
        [ -n "$default" ] &&
            ifpri[$iface]="$ip" ||
            ifsec[$iface]="${ifsec[$iface]} $ip"
    fi
done < $ipfile

declare -a cmddel=()
declare -a cmdadd=()

for iface in $iflist; do
    tmpprefix="$tmpdir/$iface"

    ip addr show | grep -w $iface | grep -w 'inet' | cut -d' ' -f6 | ipsort > ${tmpprefix}_cur
    (
        [ -n "${ifpri[$iface]}" ] &&
            echo ${ifpri[$iface]} ||
            echo -n
    ) | sed -e 's/\s/\n/' | ipsort > ${tmpprefix}_new
    (
        [ -n "${ifsec[$iface]}" ] &&
            echo ${ifsec[$iface]} ||
            echo -n
    ) | sed -e 's/\s/\n/' | ipsort >> ${tmpprefix}_new
    diflist="$(diff ${tmpprefix}_cur ${tmpprefix}_new | awk '$1=="<" || $1==">" { print $1$2 }')"

    if [ -n "$diflist" ]; then
        for difline in $diflist; do
            action=${difline:0:1}
            ip=${difline:1}
            case $action in
                '<')
                    cmddel[${#cmddel[@]}]="ip addr del $ip dev $iface"
                    ;;
                '>')
                    cmdadd[${#cmdadd[@]}]="ip addr add $ip dev $iface"
                    ;;
                *)
                    echo "Error: unknown action $action!"
            esac
        done
    fi
done

n=${#cmddel[@]}
while [ $n -gt 0 ]; do
    n=$(($n-1))
    echo ${cmddel[$n]}
    $test || eval ${cmddel[$n]}
done
n=${#cmdadd[@]}
while [ $n -gt 0 ]; do
    n=$(($n-1))
    echo ${cmdadd[$n]}
    $test || eval ${cmdadd[$n]}
done

Пример ip.list

192.168.0.1/24	firsthost	eth0
192.168.0.2/24	secondhost	eth0
192.168.1.1/24	secondhost	eth1
192.168.1.2	secondhost	eth1

При запуске скрипта setip.sh на компьютере secondhost будут произведены следующие действия в указанном порядке:

  1. удаление всех ip-адресов, кроме 192.168.0.2/24 с интерфейса eth0;
  2. удаление всех ip-aдресов, кроме 192.168.1.1/24 и 192.168.1.2/32 с интерфейса eth1;
  3. если на интерфейсе eth0 ещё нет адреса 192.168.0.2/24, добавить его;
  4. если на интерфейсе eth1 ещё нет адреса 192.168.1.1/24, добавить его;
  5. если на интерфейсе eth1 ещё нет адреса 192.168.1.2/32, добавить его.

Дискуссия

Enter your comment
 
os/linux/common/massovoe_upravlenie_naznacheniem_ip-adresov.txt · Последние изменения: 28.11.2009 20:24 (внешнее изменение)

Инструменты страницы