LINUX.ORG.RU

Узнать МАС-адрес до поднятия eth-интерфейса в initrd

 


0

1

Добрый день, Господа!

Возникла большая необходимость собрать initrd-файл, который при загрузки узнавал бы МАС-адрес одной (любой) физической сетевой карты, делал бы не его основании hostname системы и уже после поднимал сетевую карту и шел на DHCP-сервер.

Проблема в том, что поиск МАС-адрес нужно получить на самом начальном этапе загрузки initrd, а на данном этапе сетевая карта eth не подключен как модуль.

Соответственно, МАС-адреса нет ни в /sys, ни в dmesg.

Собственно, в данной ситуации мне нужно либо как-то спросить МАС-адрес у ядра, либо найти точку между поднятием сетевого интерфейса и получением IP по DHCP, чтобы вставить туда свой скрипт преобразования МАС в hostname.

Уважаемые, ни у кого нет идей, как можно выполнить вышеуказанное на данном этапе загрузки?

Благодарю


Кто запускает dhcp-клиента ? вот там и сформировать имя хоста.

За что борьба? hostname можно просто рандомный сделать или взять часть из /sys/class/dmi/id/product_uuid

vel ★★★★★
()
Последнее исправление: vel (всего исправлений: 1)
Ответ на: комментарий от vel

DHCP-клиент - ipconfig

Рендомный делать нельзя - нужно, во-первых, чтобы он не менялся, во-вторых, чтобы его можно было легко вычислить не загружая ОС.

Команда запуска DHCP-клиента находится в файле /scripts/functions, а сам файл запускается через скрипт init.

Суть в том, что при запуске скрипта init сетевой интерфейс еще не определен, а попытки вставить команды в /scripts/functions перед ipconfig пока приводят только к Kernel panic

PIKNIK
() автор топика

А ты hostname выдавай DHCP сервером по MAC-адресу, а не вычисляй.

Для dhcpd это как-то так будет:

host server10 {
  hardware ethernet 00:aa:bb:cc:dd:ee;
  fixed-address 10.0.0.10;
  option subnet-mask 255.255.255.0;
  option host-name «server10»;
  option domain-name-servers 10.0.1.1, 10.0.2.1;
}

Твоя железка будет получать hostname при выдаче IP. Все необходимые действия относящиеся к hostname можешь прописать в скрипте, который твой DHCP-client запускает при получении IP.

Stanson ★★★★★
()
Ответ на: комментарий от Stanson

Не получится.

Готовая сборка будущей системы будет в последствии передан заказчикам, а у него свои DHCP-сервера, на которые у меня нет доступа.

Поэтому нужно, чтобы именно клиент сообщал серверу, что «я такой-то МАС-адрес с таким-то именем хоста хочу получить IP-адрес»

PIKNIK
() автор топика
Ответ на: комментарий от PIKNIK

Тогда без загрузки драйвера сетевухи получить MAC будет проблематично.

Как костыль - брать какой-то ID из другого места, и при подъёме сети указывать MAC сделанный из этого ID.

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 1)
Ответ на: комментарий от PIKNIK

Решил подменить dhcp-клиент на ics-овский.

У клиента ipconfig нет ни строенной help, ни информации в интернете. Гугл вообще с ума сходит - если гуглить «Linux ipconfig», то он либо пытается поправить меня на «Linux ifconfig», либо посылает на майкросотовские сайты. Нашел исходный код программы, ничего полезного и нужного мне в нем не нашел.

Строчка запуска DHCP-клиента ipconfig находится в файле /scripts/functions и выглядит вот так:

ipconfig -t ${ROUNDTTT} "${DEVICE}"

я ее хочу поменять на что-то вроде

 sleep ${ROUNDTTT} && dhclient -H $MACFORNAME "${DEVICE}" || dhclient "${DEVICE}"

Судя по ману http://linux.die.net/man/8/dhclient, у dhclient как раз должна быть опция -H <hostname> которая и отправляет на сервер сведения о имени хоста клиента.

Достаточно незадолго до запуска команды высчитать переменную $MACFORNAME и всё.

Я попробовал перекопировать программу dhclient и пару связных библиотек в initrd c установленной убунты. Программа взаимодействует с DHCP-сервером через BusyBox отлично, но появилась проблема - в той убунтовской версии (4.3.1) нет ключа -H и, соответственно, мой план пока не заработал.

Сейчас рою весь интернет в поиске той версии, откуда сайт linux.die.net выписывал ман.

P.S. Проблема потихоньку из hardware перешла в software. Если мешает - перекиньте ее на другой форум.

PIKNIK
() автор топика
Ответ на: комментарий от PIKNIK

ics-dhcpd - не существует :)

ipconfig - это в оффтопике или какая-то левая утиль. В онтопике либо ifconfig либо ip.

Суть в том, что при запуске скрипта init сетевой интерфейс еще не определен, а попытки вставить команды в /scripts/functions перед ipconfig пока приводят только к Kernel panic

Гм. дык вызови sh из init-скрипта и по-эксперементируй.

Учти, что в initrd обычно вместо sh линк на busybox, а там число доступных команд может быть сильно сокращено.

vel ★★★★★
()
Ответ на: комментарий от PIKNIK

Проблема в том, что поиск МАС-адрес нужно получить на самом начальном этапе загрузки initrd, а на данном этапе сетевая карта eth не подключен как модуль.

AFAIU это можно сделать только так, как делает драйвер сетевой карты, т.е. считать его из EEPROM..., т.е. практически никак :/

в той убунтовской версии (4.3.1) нет ключа -H и, соответственно, мой план пока не заработал.

AFAIK, этот ключ RH специфичен. В качестве альтернативы в dhclient.conf можно заменить

send host-name = gethostname();

на

send host-name "foo";

Вариант?

barti_ddu
()
Ответ на: комментарий от vel

ISC.

Именно поэтому я и хочу поменять ipconfig на dhclient.

То, что он работает я как раз таки и выяснял, запуская в разные моменты загрузки sh и изучая, какие условия для выполнения текущей задачи имеется на том или ином этапе. Пока что метод с dhclient -H кажется наиболее рабочим.

Про dhclient.conf у меня возникали мысли. Просто я еще не успел их опробовать. Сегодня займусь. Хотя ключ -H кажется мне более удобным в плане решения возникшей проблемы.

PIKNIK
() автор топика
Ответ на: комментарий от PIKNIK

Метод использованием с генерацией хостнейма в файл dhclient.conf и последующим выполнением dhclient ${DEVICE} работает... но только в ручную.

Любая попытка подменить ipconfig на dhclient в /scripts/functions приводит неработоспособности initrd. То выкидывает Kernel Panic, то просто «весит» на черном экране.

Что характерно, вручную выполнение команды dhclient отрабатывается отлично.

Вот логи при запуске dhclient вручную на сервере во время работы в initrd:

Apr  4 14:44:34 pxe1 dhcpd: DHCPREQUEST for 10.1.241.162 (10.1.241.2) from 08:00:27:71:42:0a (08002771420a) via eth2
Apr  4 14:44:34 pxe1 dhcpd: DHCPACK on 10.1.241.162 to 08:00:27:71:42:0a (08002771420a) via eth2

Пока скину всё, что делал с initrd

# cp /sbin/dhclient bin/
# cp /lib/i386-linux-gnu/libirs-export.so.91 lib/i386-linux-gnu/
# cp /lib/i386-linux-gnu/libdns-export.so.100 lib/i386-linux-gnu/
# cp /lib/i386-linux-gnu/libisc-export.so.95 lib/i386-linux-gnu/
# cp /lib/i386-linux-gnu/libisc* lib/i386-linux-gnu/
# mkdir etc/dhcp
# cp /etc/dhcp/dhclient.conf etc/dhcp/

dhclient.conf

option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

send host-name "112233445566";
#send host-name = gethostname();
request subnet-mask, broadcast-address, time-offset, routers,
        domain-name, domain-name-servers, domain-search, host-name,
        dhcp6.name-servers, dhcp6.domain-search,
        netbios-name-servers, netbios-scope, interface-mtu,
        rfc3442-classless-static-routes, ntp-servers,
        dhcp6.fqdn, dhcp6.sntp-servers;
timeout 300;

configure_networking()
{
...


                        MACFORNAME=`head -n 1 /sys/class/net/eth0/address | sed 's/\://g'`

                        echo $MACFORNAME > /etc/hostname

                        hostname $MACFORNAME

                        sed -i "s/112233445566/$MACFORNAME/g" /etc/dhcp/dhclient.conf 

#/bin/sh 

      for ROUNDTTT in 2 3 4 6 9 16 25 36 64 100; do

...
   
                case ${IP} in
                none|off)
                        # Do nothing
                        ;;
                ""|on|any)
                        # Bring up device
                        ipconfig -t ${ROUNDTTT} "${DEVICE}"
                        #dhclient ${DEVICE} 
                        ;;
...

PIKNIK
() автор топика
Ответ на: комментарий от PIKNIK

Весь день эксперементировал. Сделал не идеально, но главное - работает.

В общем с iptables тут как в стишке «Зайчик не прост, ох, как зайчик не прост, Он шел один, но привел с собой «хвост»...»

Он не просто получает от DHCP-сервера данные о сети, но создает файл /run/net-ethX.conf, который содержит в себе всю информацию от DHCP-сервера в виде перечня переменных. Эти переменные после используются для продолжения загрузки initrd.

Что самое плохое - этот файл на финале загрузки initrd удаляется и поэтому я так долго гадал, что это за «/run/net-»${DEVICE}".conf" к которому так много условий.

Суть в том, что пытаясь подменить ipconfig на dhclient, файл /run/net-ethX.conf не создавался, переменные из него не присваивались и дальнейшая загрузка стопорилась или паниковала на скриптах, которые эти переменные используют.

Я поискал с помощью grep, где используются те или иные переменные, ужаснулся и решил, что менять их не выход.

В итоге сделал так, хоть и не идеально: 1) закомментировал присвоение переменной HOST в файле /etc/casper.conf, чтобы ipconfig не посылал каждый раз имя хоста «ubuntu» DHCP-серверу и у него не возникало проблем с «кучей убунт». 2) Вернул файл /scripts/functions в дефолтное состояние 3) В файле /script/casper нашел, где идет вызов функции из файла /scripts/functions по настройке сетевого интерфейса и уже после нее вставил генерацию имени и повторное обращение к DHCP-серверу через программу dhclient.

...
    configure_networking

    MACFORNAME=`head -n 1 /sys/class/net/${DEVICE}/address | sed 's/\://g'`

    echo $MACFORNAME > /etc/hostname

    hostname $MACFORNAME

    sed -i "s/112233445566/$MACFORNAME/g" /etc/dhcp/dhclient.conf

    dhclient ${DEVICE}
...

Как не странно, работает достаточно хорошо. Я еще когда начинал делать, думал, что я плюну и просто сделаю не вместо стокового DHCP-клиента свой рабочий, а после. В итоге получилось, что DHCP-сервер 2 раза раздает один и тот же адрес, но ничего страшного в этом я не вижу. Имя узла успешно передается DHCP-серверу на моменте загрузки initrd, DHCP-сервер успешно прописывает это имя в DDNS и я по окончании загрузки initrd уже могу резолвить свою рабочую машину через DNS. Настоящее имя узла, что характерно, до сих пор не поменялось на желаемое, но это не страшно. Мне главное нужно было прописать это имя в DNS, а остальное - чисто косметическое.

В общем спасибо всем за участие и помощь!

PIKNIK
() автор топика
Ответ на: комментарий от PIKNIK

Чуть еще допилил /etc/casper, чтобы после подключения squashfs не сбивался hostname

Теперь МАС-адрес фигурирует в логах DHCP-сервера с самого начала загрузки и до конца. В и DDNS прописывается все самого начала.

Достаточно неплохо получилось.

...
configure_networking

    MACFORNAME=`head -n 1 /sys/class/net/${DEVICE}/address | sed 's/\://g'`

    echo $MACFORNAME > /etc/hostname

    hostname $MACFORNAME

    USERNAME=user
    USERFULLNAME="live user"
    HOST=$MACFORNAME
    BUILD_SYSTEM=Ubuntu


    echo 'export USERNAME="user"' > /etc/casper.conf
    echo 'export USERFULLNAME="live user"' >> /etc/casper.conf
    echo "export HOST=$MACFORNAME" >> /etc/casper.conf
    echo 'export BUILD_SYSTEM="Ubuntu"' >> /etc/casper.conf

    sed -i "s/112233445566/$MACFORNAME/g" /etc/dhcp/dhclient.conf

    dhclient ${DEVICE}

    export DEVICE

    [ -f /etc/casper.conf ] && . /etc/casper.conf
    export USERNAME USERFULLNAME HOST BUILD_SYSTEM

... 
PIKNIK
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.