Pull to refresh

Comments 25

Тоже давно работаю сетевым инженером. И тоже пару лет назад начал использовать питон для всяких задач автоматизации и мониторинга. После десяти лет перла питон зашёл просто с удовольствием, настолько всё просто и в 5 минут находились ответы на любые вопросы.
Однако, когда несколько месяцев назад попробовал Go, просто испытал восторг.
Go гораздо более интересный язык для вот такого программирования под сетевые задачи непрофессиональным программистом.
Во-первых, быстродействие, Go во много раз быстрее справляется с опросом маршрутизаторов, чем питон.
Во-вторых, многопоточность. В Go она просто отлично реализована. Даже если не считать GIL, не очень мешающий для сетевых задач, всё равно треды и мультипроцесс в питоне выглядят костыльно и неудобно.
Память программы на Go тоже расходуют в разы более экономно на совершенно идентичном функционале с питон скриптами.
Опять же, самодостаточный бинарник против целиком питона + либы.
Роб Пайк, залогиньтесь
И что, часто сетевому админу нужна многопоточность, скорость выполнения скрипта и переносимость?
Да вполне. Работать приходится с сотнями-тысячами устройств. К примеру, если сохранять с них конфигурации, то без многопоточности уйдёт довольно много времени на сбор.
SSH, SNMP обращения к хосту на питоне работают очень медленно в сравнении с гоу. Опять же многопоточность для этих обращений, иначе интервал опроса будет таким большим, что потеряет смысл.
Переносимость для отладки. Можно временно запускать на рабочей станции с виндой, потом перенести на сервер с линуксом.
Во-первых, быстродействие, Go во много раз быстрее справляется с опросом маршрутизаторов, чем питон.
В задаче выше Питон для наиболее ресурсоемких частей кода является, если посмотреть чуть глубже, оберткой под C в модуле re и под C++ в модуле SubnetTree. Что вполне положительно сказывается на скорости работы скрипта.
Так что и производительность все же имеет смысл измерять и сравнивать под конкретные сценарии и ограничения.
И это тоже. Заслуга питона не так редко выходит в более простом синтаксисе биндинга к коду си под капотом для неспециалистов в программировании, которые не потянут работать с си напрямую.

Довольно странное заявление насчет костыльности тредов. Треды как треды, никакой костыльности, кроме GIL, который в таких задачах не должен сильно влиять на результат. Первый раз слышу, чтобы потоки в Python называли костыльными.


multiprocessing — да, может быть костыльным в некоторых ситуациях. Я его использовал только один раз, и в моем случае пришлось отказаться, но у меня была очень специфическая задача. Да и решить проблемы с multiprocessing можно было бы, просто в моем случае проще оказалось переписать на потоках.


Насчет производительности — тоже сомневаюсь. В опросе по сети сетевые задержки всегда будут на первом месте по влиянию на производительность.


Я не против Go, просто мне кажется, что кто-то прочитав может сделать неправильные выводы.

Ну может быть да, треды зря назвал костыльными. Да и GIL, насколько доводилось читать, есть только в CPython, в другие реализациях питона его нет.
Мультипроцессинг откровенно не понравился, очень неудобно.
Но всё же горутины красивее, лаконичнее и понятнее.

Насчёт сетевых задержек да, но как раз этот вопрос и решается многопоточностью.
Но как выше писал, SSH и SNMP на питоне работают намного медленнее.
Если на питоне цикл опроса занимал полторы-две минуты, то на гоу стал занимать 10 секунд,
при прочих равных, алгоритм не менялся никак.

Вроде бы и в CPython началась работа по избавлению от GIL.


Сопрограммы есть и в Python, но я не использовал их, так что мне нечего сказать по сути, кроме того, что они есть. Но это кстати не многопоточность, их нельзя сравнивать с потоками (threads). Не знаю, что сейчас в Go, но когда он появился, в нем вообще не было потоков. Корутины — это не потоки. Сейчас может быть иначе, не следил за развитием Go.


По поводу SSH и SNMP тоже ничего не могу добавить. SNMP в python использовал эпизодически, SSH вообще не приходилось, так что аргументированно спорить не могу.

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

Так и в Python корутины есть. В Python 3 появилась поддержка на уровне языка, в Python 2 были различные third-party реализации. Правда, как уже сказал, ни в Python ни в Go использовать корутины еще не приходилось, поэтому сравнить удобство и производительность не могу.

Почему вы выбрали парсинг текста вместо bgp-based listener?
И какая была основная задача — построить топологию или что-то иное?

Full View в изначальных условиях не было, я его привёл в пример лишь в качестве одного из наиболее частых и возможных случаев тяжёлых таблиц маршрутизации, чтобы обозначить верхнюю границу применимости скрипта не в попугаях.
Основная цель — узнать цепочку промежуточных устройств до любого адреса с любого из имеющихся устройств. Попутно анализируя, какими маршрутами пойдёт пакет (например, должен по EIGRP, а где-то не удаленная статика осталась и т.п.). Или альтернативно — узнать какие фаерволы нужно пройти по дороге.
Вариантов применимости может быть много. Первоначальную же постановку вопроса взял из топика на одном форуме, как и обозначил выше.

Вам про другое говорят. Обычно для задач такого рода включают сервер, который работает как IBGP-пир. Маршрутизаторы сливают на него все маршруты, а анализ префиксов идёт уже на нем.
Обычно для задач такого рода
Род задачи определяется точкой зрения на нее. Помимо внутренних служб, есть еще и внешние консультанты (интеграторы, вендорская техподдержка и т.д.). Для последних анализ и аудит сети, которую видишь впервые, явление несколько более частое. А доступ к оборудованию, как правило, сильно ограничен. Постановка задачи из статьи (напомню, сформулирована не мной) с этой перспективы более характерна и логична.
Кроме того, задача сводится к анализу не только префиксов/путей, а еще и маршрутов:
Пример:
PATHS TO 192.168.204.204 FROM csr1000v-01
Detailed info:
Path 1:
['csr1000v-01', 'csr1000v-03', 'csr1000v-04']
ROUTER: csr1000v-01
Matched route string:
D 192.168.204.0/24
[90/131072] via 192.168.13.203, 00:06:56, GigabitEthernet3
[90/131072] via 192.168.12.202, 00:06:56, GigabitEthernet2
ROUTER: csr1000v-03
Matched route string:
D 192.168.204.0/24
[90/130816] via 192.168.34.204, 00:37:22, GigabitEthernet2

ROUTER: csr1000v-04
Matched route string:
L 192.168.204.204/32 is directly connected, Loopback204

Path 2:
['csr1000v-01', 'csr1000v-02', 'csr1000v-04']
ROUTER: csr1000v-01
Matched route string:
D 192.168.204.0/24
[90/131072] via 192.168.13.203, 00:06:56, GigabitEthernet3
[90/131072] via 192.168.12.202, 00:06:56, GigabitEthernet2
ROUTER: csr1000v-02
Matched route string:
D 192.168.204.0/24
[90/130816] via 192.168.24.204, 00:37:26, GigabitEthernet3
ROUTER: csr1000v-04
Matched route string:
L 192.168.204.204/32 is directly connected, Loopback204

Path search on csr1000v-01 has been completed in 0.000 sec

Откуда сразу видим, что, скажем, на csr1000v-01 пакет на 192.168.204.204 уйдет по маршруту из EIGRP с двумя equal-cost (131072) next-hop'ами через 192.168.13.203 и 192.168.13.202.
D 192.168.204.0/24
[90/131072] via 192.168.13.203, 00:06:56, GigabitEthernet3
[90/131072] via 192.168.12.202, 00:06:56, GigabitEthernet2
И так далее по всей цепочке.
Даже если отбросить все ограничения выше, как добиться передачи аналогичной информации через (i)BGP?
Кстати, да, такой же вопрос. Зачем именно выгружать таблицы маршрутизации в файлы.
Можно в интересующий момент времени запросить данные по конкретному маршруту, как это делается в looking glass.
Если, конечно, не надо это делать сразу на тысячах маршрутизаторов :)
Но регулярно сгружать full-view с тысяч маршрутизаторов это задача, граничащая с безумием.

Статья в целом интересная, но автор не убедил. Пайтон конечно хорош, но вот сама задача несколько надуманна, во первых есть тот же mtr(и нет причин ему не доверять), и потом если это не сложная сеть с большим количеством маршрутизаторов то большая часть трафика уходит на дефолт, для чего такие сложности? Чего-то нам автор не договаривает, может быть это первый шаг к автоматической настройке тех же роутеров или аудита их конфигурации?

может быть это первый шаг к автоматической настройке тех же роутеров или аудита их конфигурации?

Непростая задача даже для вендорского софта. В одиночку нормально не осилить.
Впрочем, вендорский софт та ещё печаль, поэтому приходится изобретать велосипеды.
По хорошему следующим шагом нужно оформить ваш код в виде Python пакета и выложить на pypi.org
Тоже начал погружаться в питон. Многие здесь в коментах отписались что используют ssh.
Коллеги поделитесь опытом, что делаете с паролем на ssh?
Хранить в открытом виде в скрипте очень не хочется.
Да тут как-то ничего особо не придумаешь. Если только сертификаты поднимать для SSH.
Можно создать специального пользователя с ограниченными правами и ограниченным набором допустимых команд. Тогда уже не так принципиально, что в скрипте логин/пароль.
Можно ещё не хранить пароль в скрипте, а вытягивать его из хранимых в системе креденшилсов, но это как password 7 на циске, защита от подглядывания через плечо.
Ну и да, переходите на Go :), там будет просто бинарник, из которого выковырнуть хороший рандомный пароль уже не так просто как из питоновского скрипта, в бинарнике попробуй его найди.

Хранить в бинарнике открытый пароль — это security by obscurity, которая никогда не работает.


Чем не годятся ключи и ssh-agent?

Это да, вариант но имхо не очень удобный.
Я надеялся узнать про крипто какуюнибудь тулзу.

ssh ключи вполне себе удобный вариант, по-моему.


Наверное можно еще смотреть в сторону аппаратных ключей, таких как Yubikey.


Все остальное будет достаточно просто взломать.

Sign up to leave a comment.

Articles