null

Поиск сетевых устройств в подсети

Наверное, многие системные администраторы, сетевые архитекторы, домохозяйки и вечерние уборщицы сталкивались с задачей поиска всех активных сетевых устройств в подсети. 

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

Конечно же, наиболее простым способом является использование прекрасной утилиты nmap.

net_addr=192.168.2.0
mask=24
nmap -sn -n $net_addr/$mask

Но, несмотря на всю свою прекрасность, nmap идёт в базовой поставке разве что в экзотических дистрибутивах Линукса для хакермэнов, типа Kali Linux.

По этой причине также предлагаю рассмотреть вариант поиска узлов, используя только те утилиты, которые (почти) гарантированно будут в любой UNIX подобной системе, а именно "ping" и "arp".

Зачем же нам arp? да потому что некоторые производители операционных систем, такие как Microsoft и Apple, посчитали, что ОС должна по дефолту игнорировать ICMP ECHO в их адрес и вы просто не сможете понять жив хост или нет, используя только ping. Но машинка-то в сети! Поэтому, за редким исключением (NOARP интерфейсы), наша система таки получит информацию о физическом адресе машины, если мы попытались к ней обратиться. 

В связи со всем вышесказанным пишем две простые строчки в терминал и получаем достоверных список всего живого в рамках подсети той машины, с который мы пытаемся что-то найти.

Для Linux:

# пропинговываем всю подсеть
for i in {1..254} ;do (ping -c 1 -w 1 192.168.2.$i >/dev/null &) ;done
# опционально это всё можно расширять, если машинка подключена
# к большему количеству подсетей, чем к одной
# for i in {1..254} ;do (for j in {1..3} ;do (ping -c 1 -w 1 192.168.2.$i >/dev/null &) ;done) ;done

# а теперь получаем список живых узлов
arp -n |awk 'NR>1 && !/incomplete/ {print $1}'
# если хотите с MAC адресом, то 
arp -n |awk 'NR>1 && !/incomplete/ {print $1 " " $3}'
Для FreeBSD:
for i in {1..254} ;do (ping -c 1 -w 1 192.168.2.$i >/dev/null &) ;done
arp -an |awk '!/incomplete/ {print $1}' |sed 's/[()]//g
Для Solaris:
for i in {1..254} ;do (ping 192.168.2.$i 1 >/dev/null &) ;done
arp -an |awk '$NF~/[a-f\d:]/ && !/[MS]/ {print $2 " " $NF}'

ВНИМАНИЕ! АХТУНГИ!

1) Не советую приведённым выше способом принговать большие подсети, типа /16. Это будет равносильно выстрелу себе в ногу. Опытным путём определено, что /20 ещё нормально, но больше не стоит.

2) Этот способ покажет доступные узлы только в рамках подсети той машины, с которой производилось сканирование. Если хотите сканировать дальше, воспользуйтесь простым ping или программами, специально созданными для этой задачи.