Архив рубрики: Публикации

Стена огня lvl2. Настраиваем файрвол для отражения атак на примере MikroTik

Содержание статьи




  • Унификация настроек
  • Защищаемся от атак
  • Цепочка Forward
  • Заключение




В этой статье мы рассмотрим, как защищать роутер MikroTik от атак и сканеров портов, а также предотвратим попадание нашей сети в бан-листы. Полученный опыт поможет тебе настраивать и другие виды файрволов.




INFO




Общие принципы безопасной настройки роутера и принципы оптимальной настройки файрвола ты можешь узнать в предыдущих статьях.




Унификация настроек




Если у тебя большая сеть с несколькими филиалами и в каждом из них по два роутера для отказоустойчивости, то правила лучше настроить так, чтобы их можно было легко развернуть на любой железке, независимо от количества и именования портов или типа подключения. Для соединения по PPPoE, например, WAN-интерфейсом будет pppoe-out1, а для DHCP — ether1. Если попытаться экспортировать конфиг файрвола с одного роутера на другой, ничего не выйдет, потому что у второго просто нет интерфейса pppoe-out1. Или представь себе, что в одном филиале локальная сеть висит на ether9, а в другом стоит роутер с пятью портами, из-за чего конфигурация девятого порта просто не встанет и вылетит с ошибкой.




Поэтому мы будем настраивать роутер так, чтобы конфиг можно было без проблем перенести на любой другой роутер. Это немного усложнит первоначальную настройку, но сэкономит кучу времени в будущем.




Мы уже рассматривали списки интерфейсов. Это фича для оперирования несколькими интерфейсами как одним. Создадим листы WAN и LAN, а затем добавим туда нужные интерфейсы. Теперь правила файрвола будем привязывать к интерфейс-листам, а не к отдельным интерфейсам. Перед экспортом правил на другой роутер просто создадим на нем нужные листы, и конфиг встанет без ошибок.




Interface List




Обрати внимание, что для использования в файрволе нам нужны L3-интерфейсы, то есть те, на которых есть IP-адреса. Если ты получаешь интернет по PPPoE, то в WAN-лист надо добавить именно его. Если IP локальной сети прописан на бридже или VLAN’е, то и в лист LAN нужно добавить их, а не физические интерфейсы. Если включить в список и логический, и физический интерфейс, ничего страшного произойти не должно, но это нужно будет учитывать в конфигурации.




Но это еще не все. Понятно, что в каждом филиале у нас будет своя подсеть LAN: где-то 192.168.10.0/24, где-то 192.168.11.0/24. Чтобы не путаться с этими значениями и не менять конфиг при переносе с одного роутера на другой, оперировать будем не адресами и подсетями, а списками адресов. На каждом роутере создаем список LAN и дальше работаем только с ним.




В прошлый раз мы создавали адрес-лист MGMT, в котором открывали доступ к управлению роутером только с определенных адресов. А еще раньше рассматривали решение Port Knocking, которое предоставляет доступ к управлению, только если со стороны клиента выполнить секретные манипуляции. Для доступа к роутеру из доверенной сети (LAN) вполне подходит вариант с адрес-листом, а для доступа снаружи — Port Knocking. Было бы хорошо совместить эти варианты в нашей конфигурации. Еще будет удобно разделить цепочку input на две части: input со стороны интернета и input со стороны локалки. Тогда можно применять разные политики фильтрации к разным сегментам сети. В этом нам помогут пользовательские цепочки.




Все, что пришло снаружи, перекидываем в новую цепочку WAN_INPUT. Все, что изнутри, — в LAN_INPUT:




/ip firewall filter
add action=jump chain=input in-interface-list=WAN jump-target=WAN_INPUT
add action=jump chain=input in-interface-list=LAN jump-target=LAN_INPUT




Теперь политики фильтрации будут разными для разного источника трафика. Для внешнего трафика будем использовать цепочку WAN_INPUT и более жесткие ограничения, для внутреннего — LAN_INPUT и правила попроще. Цепочка input нам больше не нужна, теперь мы все будем делать в новых цепочках. Причем указывать интерфейсы или списки интерфейсов в правилах больше не понадобится. Однако этот подход может использоваться в сложных решениях, например когда у тебя два провайдера с разными политиками фильтрации или локалка поделена на разные VLAN. Но об этом позже.




В статье о безопасной настройке роутера мы настраивали Port Knocking для доступа к управлению роутером. Ограничивать таким образом доступ изнутри локальной сети — излишество. Поэтому поменяем в правилах цепочку с input на WAN_INPUT. Изнутри сети разрешим доступ к WinBox только с нужных адресов: мы уже делали это в статье про основы файрвола. Оставим в правиле только порт WinBox — TCP 8291. А для SSH разрешим подключения из всей нашей сети, но предотвратим возможность брутфорса (да, изнутри сети тоже может произойти брутфорс SSH, потому что отсутствие троянов в ней не гарантировано).




add action=drop chain=LAN_INPUT comment="drop ssh brute forcers" src-address-list=ssh_blacklist
add action=add-src-to-address-list address-list=ssh_blacklist address-list-timeout=1w3d chain=LAN_INPUT connection-state=new dst-port=22 protocol=tcp src-address-list=ssh_stage3
add action=add-src-to-address-list address-list=ssh_stage3 address-list-timeout=1m chain=LAN_INPUT connection-state=new dst-port=22 protocol=tcp src-address-list=ssh_stage2
add action=add-src-to-address-list address-list=ssh_stage2 address-list-timeout=1m chain=LAN_INPUT connection-state=new dst-port=22 protocol=tcp src-address-list=ssh_stage1
add action=add-src-to-address-list address-list=ssh_stage1 address-list-timeout=1m chain=LAN_INPUT connection-state=new dst-port=22 protocol=tcp src-address-list=!ssh_open
add action=accept chain=LAN_INPUT dst-port=22 protocol=tcp




Тут применяется механизм динамических адрес-листов с тайм-аутами. Мы рассматривали их в статье «Защищаем MikroTik. Хитрости безопасной настройки роутера». При первой попытке подключения пакет обработается правилом 5, и адрес хакера попадет в адрес-лист ssh_stage1. Вторая попытка подключения обработается правилом 4 и добавит брутфорсера в лист ssh_stage2. И так далее вплоть до листа ssh_blacklist, где адрес будет храниться десять дней, а весь трафик, идущий с адресов из этого списка, будет дропаться.




В прошлой статье мы создавали правила, разрешающие коннекты established, related и запрещающие invalid. Давай продублируем эти правила и перенесем их в новые цепочки, а из input удалим. В результате мы получим четыре правила вместо двух. На прохождение трафика это не повлияет, зато позволит видеть статистику по трафику с разных сторон. В правиле с established, related поставь галочку untracked. Чуть позже объясню, зачем она. Думаю, адаптировать остальные правила под новую логику не составит труда. В конце каждой цепочки не забудь указать правило дропа.




Должно получиться примерно так




Две цепочки позволят нам уменьшить количество переходов трафика по правилам, а значит, и немного снизить нагрузку на CPU. Счетчики в разных цепочках дадут возможность увидеть чуть более детальную статистику трафика. Хоть правил и стало больше, но они не применяются ко всему объему трафика: при первом джампе весь трафик будет обрабатываться уже новой цепочкой и в другую никогда не попадет. Подобный подход также упрощает поддержку за счет того, что по названию цепочки сразу видно, что это за трафик и откуда он идет. Можно для разных типов трафика создавать свои цепочки, например отдельную цепочку для management-трафика. За возврат трафика в родительскую цепочку отвечает action return.




Защищаемся от атак




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




Есть зарезервированные адреса, которые не используются в интернете. Они называются «богон-адресами». Отсечем пакеты с таких адресов:




/ip firewall address-list
add address=0.0.0.0/8 comment="Self-Identification [RFC 3330]" list=Bogon
add address=10.0.0.0/8 comment="Private[RFC 1918] - CLASS A" list=Bogon
add address=127.0.0.0/16 comment="Loopback [RFC 3330]" list=Bogon
add address=169.254.0.0/16 comment="Link Local [RFC 3330]" list=Bogon
add address=172.16.0.0/12 comment="Private[RFC 1918] - CLASS B" list=Bogon
add address=192.168.0.0/16 comment="Private[RFC 1918] - CLASS C" list=Bogon
add address=192.0.2.0/24 comment="Reserved - IANA - TestNet1" list=Bogon
add address=192.88.99.0/24 comment="6to4 Relay Anycast [RFC 3068]" list=Bogon
add address=198.18.0.0/15 comment="NIDB Testing" list=Bogon
add address=198.51.100.0/24 comment="Reserved - IANA - TestNet2" list=Bogon
add address=203.0.113.0/24 comment="Reserved - IANA - TestNet3" list=Bogon
add address=224.0.0.0/4 comment="MC, Class D, IANA" list=Bogon




Мы ожидаем пакеты только с юникаст-адресов, поэтому запретим все, кроме них.




Drop non unicast




Port Scan Detect — функция, позволяющая обнаружить сканер портов. Как она работает? Портам задается некий условный вес — Weight. Причем для системных портов (до 1024-го) весовой коэффициент низкий (Low ports), а для остальных — высокий (High ports). Если в течение времени Delay Threshold от одного хоста на роутер прилетят пакеты на порты, сумма весов которых окажется больше, чем Weight Threshold, то адрес отправителя будет добавлен в блек-лист. В нашем примере, если с одного хоста за три секунды поступят десять пакетов на порты до 1024-го (общий вес 10 * 2 = 20) и двадцать пакетов на порты выше 1024-го (20 * 1 = 20), общий их вес составит 40. Обрати внимание, что Port Scan Detect работает только для TCP- или UDP-трафика.




Защищаемся от сканеров




Один из самых распространенных видов атак — это атака на отказ в обслуживании, или DDoS. Защититься от нее своими силами практически нереально. Но с помощью простого правила можно отсечь самые простые попытки атаки. Находим хост, который насоздавал к нам больше 100 сессий, и добавляем его в блек-лист. В этом правиле обязательно нужно использовать параметр connection-state=new. Но мы ведь уже разрешили все established, related и untracked, а invalid дропнули, поэтому сюда дойдут только пакеты new. Оставлять или нет этот флажок в правиле — твое дело. Отмечу, что с помощью этой же фичи можно выявлять в своей сети торрентокачальщиков.




Защищаемся от DDoS




ICMP — один из важных протоколов в любой сети. Многие админы любят блокировать его, но это очень плохой подход. Именно ICMP позволяет работать трассировке, указывать на недоступность UDP-портов, отправлять разные служебные сообщения. И если запретить его полностью, можно наловить кучу багов. У каждого сообщения ICMP свое предназначение, и уже по этому параметру нетрудно понять, имеет ли смысл разрешить какие-то типы ICMP изнутри сети или снаружи. Например:




  • ICMP Echo Request — наш любимый пинг, имеет тип 8, код 0;
  • ICMP Echo Reply — ответ на пинг, тип 0, код 0;
  • Destination Unreachable — узел недоступен, тип 3 и коды 0–15 в зависимости от причины недоступности:0 — сеть недоступна;
  • 1 — хост недоступен;
  • 2 — протокол недоступен;
  • 3 — порт недоступен;
  • 4 — необходима фрагментация пакета, но она запрещена (стоит флаг DF — Don’t Fragment).




Остальное легко найти в интернете, а лучше почитать RFC 792.




Создадим цепочку ICMP и отправим в нее весь ICMP-трафик (можно создать две цепочки: для LAN и WAN — и настроить разные политики). Разрешаем только нужные типы сообщений и ограничиваем обработку пятью пакетами в секунду:




/ip firewall filter
add action=jump chain=WAN_INPUT jump-target=ICMP protocol=icmp
add action=jump chain=LAN_INPUT jump-target=ICMP protocol=icmp
add action=accept chain=ICMP comment="Allow Echo Reply (0:0-255), Limit 5pps" icmp-options=0:0-255 limit=5,5:packet protocol=icmp
add action=accept chain=ICMP comment="ICMP - Allow Destination Unreachable (3:0-255), Limit 5pps" icmp-options=3:0-255 limit=5,5:packet protocol=icmp
add action=accept chain=ICMP comment="ICMP - Allow Source Quench (4:0), Limit 5pps" icmp-options=4:0-255 limit=5,5:packet protocol=icmp
add action=accept chain=ICMP comment="ICMP - Allow Echo Request (8:0), Limit 5pps" icmp-options=8:0-255 limit=5,5:packet protocol=icmp
add action=accept chain=ICMP comment="ICMP - Allow Time Exceeded (11:0), Limit 5pps" icmp-options=11:0-255 limit=5,5:packet protocol=icmp
add action=accept chain=ICMP comment="ICMP - Allow Parameter Bar (12:0), Limit 5pps" icmp-options=12:0-255 limit=5,5:packet protocol=icmp
add action=drop chain=ICMP comment="ICMP - Drop All Others" protocol=icmp




Пример правила ICMP




TCP тоже поддерживает кучу флагов, часть которых не может содержаться в одном пакете. Комбинации этих флагов часто используются сканерами портов, чтобы пробить плохо настроенную защиту. Сделаем отдельную цепочку для TCP и дропнем подобные «подозрительные» пакеты:




/ip firewall filter
add action=jump chain=WAN_INPUT comment="Invalid TCP" jump-target=invalid_tcp protocol=tcp
add action=jump chain=LAN_INPUT comment="Invalid TCP" jump-target=invalid_tcp protocol=tcp
add action=jump chain=forward comment="Invalid TCP" jump-target=invalid_tcp protocol=tcp
add action=drop chain=invalid_tcp comment="Invalid TCP - !(FIN/SYN/RST/ACK)" protocol=tcp tcp-flags=!fin,!syn,!rst,!ack
add action=drop chain=invalid_tcp comment="Invalid TCP - FIN/SYN" protocol=tcp tcp-flags=fin,syn
add action=drop chain=invalid_tcp comment="Invalid TCP - FIN/RST" protocol=tcp tcp-flags=fin,rst
add action=drop chain=invalid_tcp comment="Invalid TCP - FIN/!ACK" protocol=tcp tcp-flags=fin,!ack
add action=drop chain=invalid_tcp comment="Invalid TCP - FIN/URG" protocol=tcp tcp-flags=fin,urg
add action=drop chain=invalid_tcp comment="Invalid TCP - SYN/RST" protocol=tcp tcp-flags=syn,rst
add action=drop chain=invalid_tcp comment="Invalid TCP - RST/URG" protocol=tcp tcp-flags=rst,urg
add action=drop chain=invalid_tcp comment="Invalid TCP - Source Port 0" protocol=tcp src-port=0
add action=drop chain=invalid_tcp comment="Invalid TCP - Destination Port 0" dst-port=0 protocol=tcp




Пример с TCP-флагами




То же самое для UDP:




add action=drop chain=invalid_udp comment="Invalid UDP - Source Port 0" protocol=udp src-port=0
add action=drop chain=invalid_udp comment="Invalid UDP - Destination Port 0" dst-port=0 protocol=udp




Цепочка Forward




До сих пор мы в основном смотрели на трафик, прилетевший в input-цепочку, а дальше по каким-то признакам направляли его в разные цепочки. Но весь этот трафик предназначался самому роутеру. Цепочку output используют редко, но ты можешь отфильтровать в ней, например, ICMP-ответы от роутера или IPsec-трафик. Понятно, что большая часть трафика будет попадать в forward — ведь на то он и роутер, чтобы перенаправлять пакеты из одной сети (локалка) в другую (интернет или второй VLAN локалки). И в этой цепочке мы будем управлять трафиком пользователей.




Я не стану детально рассказывать о том, что надо разрешить или запретить, — об основных приемах настройки и так уже написано несколько статей и есть куча примеров в интернете. Рассмотрим более интересный кейс: репутацию сети.




В интернете есть сервисы, содержащие списки спамеров, ддосеров, распространителей нелегального контента. Если на машины в твоей сети попал троян-спамер, то ты тоже окажешься в этих списках. Через какое-то время письма от любого клиента изнутри сети начнут попадать в спам у всех получателей, потом ты будешь добавлен в публичные блек-листы и у пользователей исчезнет доступ ко многим ресурсам. В том числе к сетям партнеров, админы которых пользуются такими списками, чтобы запретить доступ потенциальным вредителям. Представь, что произойдет с твоей премией, когда письмо с многомиллионным контрактом от твоего шефа упадет у контрагента в папку «Спам».




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




  • мы часть DoS- или иного ботнета;
  • мы рассылаем спам;
  • с наших адресов брутфорсят чужие сервисы;
  • мы нарушаем авторские права (раздаем торренты).




Некоторые читатели этой статьи вполне могли участвовать в DDoS-ботнете, сами того не осознавая. Атаки UDP Amplification основаны на некорректных настройках сервисов, когда можно обратиться к ним с просьбой узнать что-то у другого сервера. Например, к нам может прилететь DNS-запрос с просьбой отрезолвить адрес жертвы. И таких, как мы, миллионы. Когда к жертве поступит миллион пакетов в секунду, она не обрадуется, а мы увидим загрузку CPU под 100%, жуткие тормоза и однажды окажемся в блек-листе. Такая же схема работает и с другими UDP-сервисами, например NTP. Вывод простой: блокируй трафик к этим сервисам снаружи. Но это все еще про INPUT.




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




/ip firewall filter
add action=add-src-to-address-list address-list=dns-flood address-list-timeout=none-dynamic chain=forward comment="DNS Flood" connection-limit=100,32 dst-port=53 in-interface-list=LAN protocol=udp
add action=add-src-to-address-list address-list=smb-flood address-list-timeout=none-dynamic chain=forward comment="SMB Flood" connection-limit=100,32 dst-port=445 in-interface-list=LAN protocol=tcp 
add action=add-src-to-address-list address-list=telnet-flood address-list-timeout=none-dynamic chain=forward comment="Telnet Flood" connection-limit=20,32 dst-port=23 in-interface-list=LAN protocol=tcp
add action=add-src-to-address-list address-list=ssh-flood address-list-timeout=none-dynamic chain=forward comment="SSH Flood" connection-limit=20,32 dst-port=22 in-interface-list=LAN protocol=tcp
add action=add-src-to-address-list address-list=snpp-flood address-list-timeout=none-dynamic chain=forward comment="SNPP Flood" connection-limit=20,32 dst-port=444 in-interface-list=LAN protocol=tcp
add action=add-src-to-address-list address-list=msf-indication address-list-timeout=none-dynamic chain=forward comment="Metasploit Indication" connection-limit=20,32 dst-port=4444 in-interface-list=LAN protocol=tcp




Слишком «толстые» потоки тоже могут вызывать подозрения. Залогируем их:




add action=log chain=forward comment="Abnormal Traffic" connection-bytes=80000000 in-interface-list=LAN log-prefix=Abnormal-Traffic




По порту назначения можно определить, к какому сервису обращаются хосты изнутри нашей сети. И если это общеизвестный порт, например СУБД, а все наши базы расположены внутри периметра, логично предположить, что сотни пакетов в секунду к этому порту в интернете с компьютера бухгалтера — не простая ошибка и не личный интерес самого бухгалтера. Дропаем подозрительные пакеты и возвращаемся в родительскую цепочку (последнее правило):




add action=jump chain=forward comment="Jump to Virus Chain" disabled=no jump-target=Virus
add action=drop chain=Virus comment="Drop Blaster Worm" disabled=no dst-port=135-139 protocol=tcp
add action=drop chain=Virus comment="Drop Blaster Worm" disabled=no dst-port=445 protocol=tcp
add action=drop chain=Virus comment="Drop Blaster Worm" disabled=no dst-port=445 protocol=udp
add action=drop chain=Virus comment="Drop Messenger Worm" disabled=no dst-port=135-139 protocol=udp
add action=drop chain=Virus comment=Conficker disabled=no dst-port=593 protocol=tcp
add action=drop chain=Virus comment=Worm disabled=no dst-port=1024-1030 protocol=tcp
add action=drop chain=Virus comment="ndm requester" disabled=no dst-port=1363 protocol=tcp
add action=drop chain=Virus comment="ndm server" disabled=no dst-port=1364 protocol=tcp
add action=drop chain=Virus comment="screen cast" disabled=no dst-port=1368 protocol=tcp
add action=drop chain=Virus comment=hromgrafx disabled=no dst-port=1373 protocol=tcp
add action=drop chain=Virus comment="Drop MyDoom" disabled=no dst-port=1080 protocol=tcp
add action=drop chain=Virus comment=cichlid disabled=no dst-port=1377 protocol=tcp
add action=drop chain=Virus comment=Worm disabled=no dst-port=1433-1434 protocol=tcp
add action=drop chain=Virus comment="Drop Dumaru.Y" disabled=no dst-port=2283 protocol=tcp
add action=drop chain=Virus comment="Drop Beagle" disabled=no dst-port=2535 protocol=tcp
add action=drop chain=Virus comment="Drop Beagle.C-K" disabled=no dst-port=2745 protocol=tcp
add action=drop chain=Virus comment="Drop MyDoom" disabled=no dst-port=3127-3128 protocol=tcp
add action=drop chain=Virus comment="Drop Backdoor OptixPro" disabled=no dst-port=3410 protocol=tcp
add action=drop chain=Virus comment="Drop Sasser" disabled=no dst-port=5554 protocol=tcp
add action=drop chain=Virus comment=Worm disabled=no dst-port=4444 protocol=tcp
add action=drop chain=Virus comment=Worm disabled=no dst-port=4444 protocol=udp
add action=drop chain=Virus comment="Drop Beagle.B" disabled=no dst-port=8866 protocol=tcp
add action=drop chain=Virus comment="Drop Dabber.A-B" disabled=no dst-port=9898 protocol=tcp
add action=drop chain=Virus comment="Drop Dumaru.Y" disabled=no dst-port=10000 protocol=tcp
add action=drop chain=Virus comment="Drop MyDoom.B" disabled=no dst-port=10080 protocol=tcp
add action=drop chain=Virus comment="Drop NetBus" disabled=no dst-port=12345 protocol=tcp
add action=drop chain=Virus comment="Drop Kuang2" disabled=no dst-port=17300 protocol=tcp
add action=drop chain=Virus comment="Drop SubSeven" disabled=no dst-port=27374 protocol=tcp
add action=drop chain=Virus comment="Drop PhatBot, Agobot, Gaobot" disabled=no dst-port=65506 protocol=tcp
add action=drop chain=Virus comment="Drop MemCached flood" disabled=no dst-port=11211 protocol=udp
add action=return chain=Virus comment="Return From Virus Chain" disabled=no




Заключение




Мы рассмотрели более продвинутые методы настройки файрвола. Эту статью не нужно воспринимать как инструкцию по настройке: у каждой сети свои особенности и сервисы. Роутеры у всех тоже разные — у кого-то он спокойно обработает тысячи неоптимизированных правил файрвола, для других сотня правил будет обрабатываться с трудом. Поэтому подходи к настройке файрвола с умом.




В две статьи всё не вместишь, и мы не затронули еще несколько больших тем: таблицы NAT, RAW, IPv6 Firewall, Bridge Firewall, фильтрацию по контенту, определение типа трафика по его содержимому (когда мы меняем порт у HTTP, а файрвол все равно понимает, что внутри HTTP), проксирование трафика.




Все эти темы рассматриваются в официальном обучающем курсе MikroTik — MikroTik Certified Traffic Control Engineer. Но чтобы на него попасть, нужно пройти курс MikroTik Certified Network Associate, где изучаются общие принципы настройки роутера и работа TCP/IP.




Источник: https://telegra.ph/Haker—Stena-ognya-lvl2-Nastraivaem-fajrvol-dlya-otrazheniya-atak-na-primere-MikroTik-09-23



2022-08-08T00:38:40
Network

На коленке: агрегация VPN, или надежная связь на ненадежных каналах

Представьте задачу: необходимо обеспечить стабильным интернетом и покрыть бесшовным Wi-Fi здание площадью 300 м2 с возможной расчетной нагрузкой до 100 человек. На первый взгляд, “вроде изян”. Но стоит добавить пару деталей, и задача усложняется:




  • здание стоит в лесопарковой зоне, где нет оптики, так что наш вариант – мобильная связь;
  • нужно обеспечить регулярные видеотрансляции, то есть добиться стабильного интернета при единственном GSM-провайдере;
  • бюджет ограничен.




Итого: потери и отвалы от базовой станции подкрадываются в самое неподходящее время.




Такие проблемы я встречал у колл-центров без выделенных каналов связи, передвижных репортерских комплексов, критически важных удаленных систем. Трудности могут возникнуть не только в случае с VoIP и стримингом видео, но и с любым запросом на гарантированный канал доставки чувствительного к потерям трафика. К сожалению, не всегда есть возможность подвести оптику и закупить дорогостоящее оборудование.




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




Схема решения вкратце




Итак, при первом столкновении с проблемой отвалов я начал с агрегации частот и убедился, что это не поможет. Смена категории LTE-модема с Cat4 на Cat6 или – еще круче – Cat12 давала преимущество в скорости, но в потерях и отвалах – нет. Пришел к выводу, что нужен второй LTE-провайдер. При этом при переключении не должен потеряться ни один кадр и трансляция не должна отвалиться.




На помощь пришла такая связка: агрегация, она же bonding, и TCP-OpenVPN-туннель поверх этого.




  1. в облаке создал “сервер агрегации” – виртуалку с CLOUD HOSTED ROUTER (CHR) на базе Router OS;
  2. на ней поднял L2TP-сервер с включенным шифрованием IPsec;
  3. поверх L2TP over IPsec создал два EoIP-туннеля;
  4. EoIP-туннели агрегированы bonding-интерфейсом;
  5. вишенка на торте – TCP-шный OpenVPN-туннель.




Итоговая схема:







Вместо виртуальной машины в дата-центре в качестве R1 может выступать любая железка с достаточной производительностью. Например, тот же MikroTik серии CCR, компьютер, размещенный где угодно. Главное – позаботиться о производительности и стабильных каналах связи, использовать схемы активного резервирования (VRRP в помощь).




Поддержка OpenVPN UDP реализована только в 7-й версии RouterOS, поэтому в этой конфигурации безальтернативно используется протокол TCP.




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




Теперь расскажу подробнее о строительстве схемы. Начнем с R1 (облачного маршрутизатора) и – далее – R2 (филиального).




Маршрутизатор R1




  1. Сначала берем второй белый IP в дата-центре. У меня CHR находился за Edge в облаке VMware, так что обязательно пробрасываем порты на Edge UDP 1701, 500 и 4500 NAT-T – IPSec Network Address Translator Traversal. Также делаем разрешающее правило в межсетевом экране Edge.
  2. Добавляем в таблицу firewall filter разрешающее правило доступа к маршрутизатору извне для портов UDP 1701, 500 и 4500. Если у вас белые IP непосредственно на маршрутизаторе без пробросов через Edge, галочку NAT Traversal НУЖНО СНЯТЬ!Проверяем дефолтный IPsec-профиль:







/ip ipsec profile
set [ find default=yes ] dh-group=modp1024 enc-algorithm=3de




  1. Создаем профиль для L2TP-туннелей:







/ppp profile
add change-tcp-mss=no name=profile01 use-compression=no use-encryption=no use-mpls=no use




и настраиваем учетные записи:







/ppp secret
add local-address=172.16.0.1 name=l2tp_R1-R2_ISP1 password=ros7.elements.forever profile=profile01 remote-address=172.16.0.2 service=l2tp
add local-address=172.16.0.5 name=l2tp_R1-R2_ISP2 password=ros7.elements.forever profile=profile01 remote-address=172.16.0.6 service=l2tp




  1. Активируем L2TP-сервер и включаем шифрование IPsec:







/interface l2tp-server server
set authentication=mschap2 caller-id-type=number default-profile=profile01 enabled=yes ipsec-secret=ВАШ КРУТОЙ ПАРОЛЬ use-ipsec=yes




  1. Поднимаем два EoIP-туннеля поверх L2TP/IPsec-туннелей:







/interface eoip
add keepalive=1s,5 local-address=172.16.0.1 mac-address=00:00:00:00:00:A1 name=eoip-tun1_over_l2tp_R1-R2_ISP1 remote-address=172.16.0.2 tunnel-id=1
add keepalive=1s,5 local-address=172.16.0.5 mac-address=00:00:00:00:00:B1 name=eoip-tun2_over_l2tp_R1-R2_ISP2 remote-address=172.16.0.6 tunnel-id=2




Обязательно указываем минимальный keepalive timeout равным 1 секунде и для каждого EoIP-туннеля указываем уникальный ID.




  1. Настраиваем bonding и назначаем на него IP-адрес:







/interface bonding
add lacp-rate=1sec mii-interval=1ms mode=broadcast name=bonding1 slaves=eoip-tun1_over_l2tp_R1-R2_ISP1,eoip-tun2_over_l2tp_R1-R2_ISP2




/ip address
add address=172.16.1.1/30 interface=bonding1




Тут важно заметить, что в поле mode (режим работы bonding-интерфейса) я указал broadcast, чтобы пакеты отправлялись сразу по двум тоннелям. Таким образом потеря пакета на любом из двух интерфейсов не приведет к потере пакета на bonding-интерфейсе. Остальные значения устанавливаем, как на картинке.




Активируем OpenVPN-сервер




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




Создаем /ppp profile и /ppp secret для OpenVPN:










/ppp profile
add change-tcp-mss=no name=profile02 use-compression=no use-encryption=no use-mpls=no use
/ppp secret
add local-address=172.16.2.1 name=ovpn_over_bonding1 password=ros7.elements.forever profile=profile02 remote-address=172.16.2.2 service=ovpn
/interface ovpn-server server
set auth=sha1 certificate=server.crt_0 cipher=aes256 default-profile=profile02 enabled=yes keepalive-timeout=30 port=1194 require-client-certificate=yes




Обязательно прописываем в nat-таблицу межсетевого экрана правило для нашей серой филиальной сети за маршрутизатором R2, чтобы трафик выходил наружу через R1:







/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=WAN src-address=192.168.1.0/24




Обратный маршрут до серой сети за маршрутизатором R2 указываем через OpenVPN-туннель:







/ip route
add check-gateway=ping distance=1 dst-address=192.168.1.0/24 gateway=172.16.2.2




Маршрутизатор R2




  1. Первым делом прописываем маршруты от одного интерфейса LTE-модема до одного белого IP-адреса дата-центра. Запрещаем в настройках межсетевого экрана в цепочке output прохождение пакетов с другого интерфейса:




/ip route
add distance=1 dst-address= 198.51.100.10/32 gateway=lte1
add distance=1 dst-address= 198.51.100.20/32 gateway=lte2
/ip firewall filter
add action=drop chain=output dst-address= 198.51.100.10 out-interface=lte2
add action=drop chain=output dst-address= 198.51.100.20 out-interface=lte1




  1. Приводим в соответствие с R1 дефолтный конфиг /ip ipsec profile:







/ip ipsec profile
set [ find default=yes ] dh-group=modp1024 enc-algorithm=3de




  1. Создаем /ppp profile:







и два L2TP/IPsec-подключения к дата-центру для каждого из провайдеров:







/ppp profile
add change-tcp-mss=no name=profile01 use-compression=no use-encryption=no use-mpls=no use
/interface l2tp-client
add allow=mschap2 connect-to= 198.51.100.10 disabled=no ipsec-secret= ros7.elements.forever keepalive-timeout=30 name=l2tp_to_R1_over_ISP1 password=ros7.elements.forever
    profile=profile01 use-ipsec=yes user=l2tp_R1-R2_ISP1
add allow=mschap2 connect-to= 198.51.100.20 disabled=no ipsec-secret= ros7.elements.forever keepalive-timeout=30 name=l2tp_to_R1_over_ISP2 password=ros7.elements.forever
    profile=profile01 use-ipsec=yes user=l2tp_R1-R2_ISP2




  1. Создаем EoIP-туннели по аналогии с R1, только меняем местами local и remote IP L2TP/IPsec-линков маршрутизатора R2. Bonding-интерфейс такой же, как на R1:







/interface eoip
add keepalive=1s,5 local-address=172.16.0.2 mac-address=00:00:00:00:00:A2 name=eoip-tun1_over_l2tp_R1-R2_ISP1 remote-address=172.16.0.1 tunnel-id=1
add keepalive=1s,5 local-address=172.16.0.6 mac-address=00:00:00:00:00:B2 name=eoip-tun2_over_l2tp_R1-R2_ISP2 remote-address=172.16.0.5 tunnel-id=2
/interface bonding
add lacp-rate=1sec mii-interval=1ms mode=broadcast name=bonding1 slaves=eoip-tun1_over_l2tp_R1-R2_ISP1,eoip-tun2_over_l2tp_R1-R2_ISP2
/ip address
add address=172.16.1.2/30 interface=bonding1




  1. Также импортируем сертификаты, создаем профиль:










Настраиваем OpenVPN-клиента на R2:







/ppp profile
add change-tcp-mss=no name=profile02 use-compression=no use-encryption=no use-ipv6=no use-mpls=no use-upnp=no
/interface ovpn-client
add certificate=client.crt_0 cipher=aes256 connect-to=172.16.1.1 mac-address=00:00:00:00:00:C2 name=ovpn_over_bonding1 password=ВАШ КРУТОЙ ПАРОЛЬ profile=profile02 use-peer-dns=no user="ovpn_over_bonding1 " verify-server-certificate=yes




  1. Туннели загорелись волшебной буквой R, а EoIP – еще и RS. OpenVPN тоже завелся. Теперь можно направлять трафик с компьютера трансляций в наш слоеный бутерброд – в OpenVPN-туннель. Для этого создаем правило /ip firewall mangle и прописываем сразу новую таблицу маршрутизации:







/ip firewall mangle
add action=mark-routing chain=prerouting dst-address-list=google_sites dst-port=1935 new-routing-mark=pc_to_stream-youtube_over_R1 passthrough=yes protocol=tcp src-address=192.168.1.1




  1. Создаем маршрут через наш OpenVPN-туннель с данной таблицей маршрутизации:







/ip route
add check-gateway=ping distance=1 gateway=172.16.2.1 routing-mark=pc_to_stream-youtube_over_R1




И готово!




Траблшутинг




  • При развертывании конфигурации на действующем железе нужно обязательно переключить прямой и обратный маршруты с туннелей L2TP на OpenVPN-туннель. Если, например, переключить только прямой маршрут, а обратный оставить на L2TP вместо OpenVPN, агрегация полностью работать не будет и пакеты все равно будут теряться.
  • Утилиты RouterOS в разделе /tools очень полезны при траблшутинге. Еще неплохо работает связка /tools Packet Sniffer + Wireshark.
  • Не забудьте “поиграться с mtu”, чтобы достичь лучшей производительности туннелей.
  • Качество сигнала никто не отменял. RSRP, RSRQ и SINR покажут, насколько все хорошо. При большом удалении от базовой станции и плохом сигнале помогут внешние направленные антенны.
  • Важно! Если провайдер фильтрует трафик и идет блокировка L2TP, то можно поднять другие туннели в качестве основы для EoIP, например: OpenVPN или SSTP.
  • Чтобы проверить все в деле, можно сымитировать сбой. Отключаем любой из LTE-интерфейсов или создаем потери искусственно: добавляем в межсетевой экран правило частичной блокировки пакетов и указываем при создании нового правила значение в поле random.




Что еще можно улучшить и оптимизировать




  • Не рекомендую заворачивать весь интернет-трафик, так как это вызовет повышенные накладные расходы (утилизация процессоров, каналов и др.). Лучше пользоваться маркировкой для гарантированной доставки действительно необходимого трафика, а все остальное отправлять на LTE-провайдеров. К примеру, я так делал с загрузкой видеофайлов на облачный диск.
  • QOS – хорошая штука, особенно на каналах LTE, и особенно с VoIP. Не забываем про это, чтобы остальной трафик не забил и так не слишком широкий канал.
  • Можно усилить безопасность, если ограничить подключение извне к портам для L2TP и IPsec маршрутизатора R1. Указываем белый IP LTE-провайдера  с помощью firewall и адресных листов. Хоть адрес и из NAT и на нем висит не один клиент, все равно будет лучше. Так как IP динамический, то нужно включить на MikroTik функцию ip – cloud, чтобы DNS-сервера всегда знали актуальный IP, технология DDNS.




Конечно же, у схемы есть коммерческие аналоги с возможностями работы из коробки, например: peplink MAX HD4 LTE и тому подобное оборудование, – агрегирующие соединения. Тут бизнес сам оценивает их стоимость для себя.




Источник: https://uni.dtln.ru/digest/na-kolenke-agregaciya-vpn-ili-nadezhnaya-svyaz-na-nenadezhnyh-kanalah



2022-08-08T00:33:16
Network

Mkrotik и vlan по быстрому.

Купили новый маленький роутер от Mikrotik — RB4011iGS+RM. Решили попробовать как он будет работать в маленькой сетке в качестве роутера (странно? Да? 🙂 ). У него есть 10G SFP+ интерфейс, подключенный непосредственно к процессору. Если включить FastPath, то по идее должен справляться.




SFP+ интерфейс естественно в trank. На всякий пожарный eth6, тоже в транк. Eth с 1-го по 5-й в 1-й vlan, в режиме access mode, что бы подключаться прямо в серверной к коммутаторам, если вдруг чего. Остальные не задействованы.




При обращении к Google с вопросом Mirotik+vlan вываливается куча страниц с описанием настройки vlan. Но, проблема в том, что они блин все устарели! В новых версиях router os все уже не так.




Как сейчас рулить vlan с возможностью маршрутизации? Теперь там все через bridge интерфейс.




В первую очередь добавляем сам мост:




> /interface bridge




/interface bridge> add name=core




Добавим к мосту порты, в которых будут бегать тегированные пакеты:




/interface bridge> port




/interface bridge port> add bridge=core interface=sfp-trunk




/interface bridge port> add bridge=core interface=ether6




Порты, работающие в access режиме:




/interface bridge port> add bridge=core interface=ether1




/interface bridge port> add bridge=core interface=ether2




/interface bridge port> add bridge=core interface=ether3




/interface bridge port> add bridge=core interface=ether4




/interface bridge port> add bridge=core interface=ether5




Там же, в разделе bridge есть возможность указывать какие vlan на каком интерфейсе и режим работы интерфейса.




/interface bridge port> /interface bridge vlan




/interface bridge vlan> add bridge=core tagged=sfp-trunk,ether6,core untagged=ether1,ether2,ether3,ether4,ether5 vlan-ids=1




/interface bridge vlan> add bridge=core tagged=sfp-trunk,ether6,core vlan-ids=1010,1011,1254




Итак, мы добавили vlan 1 к нужным нам интерфейсам и заодно определили режимы работы самих интерфейсов. Так же были определены другие vlan, которые будут приходить на mikrotik и в дальнейшем мы будем заниматься маршрутизацией между этими сетями.




На данном этапе пакеты Ethernet начнут бегать в своих vlan.




Пришло время заняться маршрутизацией.




Обязательно добавляйте интерфейс моста в параметре tagget при добавлении vlan в разделе bridge! Без этого у нас ничего не получиться на 3-м уровне 🙁




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




Как обычно, интерфейсы создаём в разделе interface vlan (не bridge vlan!).




> /interface vlan




/interface vlan> add interface=core name=VLAN-1254 vlan-id=1254




/interface vlan> add interface=core name=VLAN-1010 vlan-id=1010




/interface vlan> add interface=core name=VLAN-1011 vlan-id=1011




Обратите внимание, что vlan-ы мы добавляем к bridge интерфейсу core. Не зря мы включали на этом интерфейсе режим работы tagged.




Осталось добавить ip адреса на интерфейсы:




> /ip address




/ip address> add address=192.168.1.1/24 interface=core network=192.168.1.0




/ip address> add address=192.168.10.1.24 interface=VLAN-1010 network=192.168.10.0




/ip address> add address=192.168.11.1/24 interface=VLAN-1011 network=192.168.11.0




/ip address> add address=192.168.254.1/24 interface=VLAN-1254 network=192.168.254.0




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




Вот и все.




Источник: https://www.kryukov.biz/2019/04/mkrotik-i-vlan-po-bystromu/



2022-08-08T00:24:11
Network

Pfsense и MikroTik, настройка VPN туннеля

Инструкция по настройке VPN туннеля типа IpSec между облачным роутером Pfsense и MikroTik. В результате настройки должно получиться объединение двух сетей, за MikroTik и за Pfsense.







Что такое Pfsense




PfSense — дистрибутив для создания межсетевого экрана/маршрутизатора, основанный на FreeBSD. PfSense предназначен для установки на персональный компьютер, известен своей надежностью и предлагает функции, которые часто можно найти только в дорогих коммерческих межсетевых экранах. Настройки можно проводить через web-интерфейс, что позволяет использовать его без знаний базовой системы FreeBSD. Сетевые устройства с pfSense обычно применяются в качестве периметровых брандмауэров, маршрутизаторов, серверов DHCP/DNS, и в технологии VPN в качестве узла топологии hub/spoke.




Настройка VPN в MikroTik для подключения к Pfsense




Со стороны роутера MikroTik будет настроен стандартный VPN туннель типа IpSec. Больше сведений по настройке VPN типа IpSec представлено в статье:




VPN туннель IpSec состоит из двух фаз:




  • PHASE-1 – идентификация устройств между собой, по заранее определенному IP адресу и ключу.
  • PHASE-2 – определение политики для трафика между туннелей: шифрование, маршрутизация, время жизни туннеля.




Создание профиля для MikroTik IpSec phase-1




Настройка находится в IP→IPsec→Profile




Pfsense и MikroTik, создание профиля для IpSec phase-1




Создание Peer для MikroTik IpSec phase-1




Настройка находится в IP→IPsec→Peers




Pfsense и MikroTik, создание Peer для IpSec phase-1




Определение ключа MikroTik IpSec phase-1




Настройка находится в IP→IPsec→Identities




Pfsense и MikroTik, определение ключа IpSec phase-1




Настройка параметров MikroTik Proposal IpSec phase-2




Настройка находится в IP→IPsec→Proposals




Pfsense и MikroTik, настройка параметров Proposal IpSec phase-2




Создание политики(Policies) MikroTik IpSec phase-2




Настройка находится в IP→IPsec→Policies




Pfsense и MikroTik, создание политики(Policies) IpSec phase-2




Настройка политики(Policies) MikroTik IpSec phase-2




Настройка находится в IP→IPsec→Policies→Action




Pfsense и MikroTik, настройка политики(Policies) IpSec phase-2




/ip ipsec profile
add dh-group=modp1024 enc-algorithm=3des hash-algorithm=md5 lifetime=8h name=Pfsense
/ip ipsec peer
add address=10.10.10.10/32 name=Pfsense profile=Pfsense
/ip ipsec proposal
add auth-algorithms=md5 enc-algorithms=3des lifetime=8h name=Pfsense
/ip ipsec policy
add dst-address=192.168.5.0/24 peer=Pfsense proposal=Pfsense 
sa-dst-address=10.10.10.10 sa-src-address=0.0.0.0 src-address=
192.168.1.0/24 tunnel=yes
/ip ipsec identity
add peer=Pfsense secret=Pt36ENepT3t3




Настройка VPN в Pfsense для подключения к MikroTik




Pfsense имеет удобный web интерфейс, с помощью которого и будет производиться настройка VPN туннеля типа IpSec для связи с роутером MikroTik.




Настройка phase-1 для Pfsense IpSec




Создание phase-1 для Pfsense IpSec







Настройка phase-2 для Pfsense IpSec




Настройка phase-2 для Pfsense IpSec




Настройка phase-2 для Pfsense IpSec, шифрование




Настройка phase-2 для Pfsense IpSec, общие параметры




Настройка Pfsense Firewall




Настройка Pfsense Firewall, разрешение внешнего подключения IpSec




Настройка Pfsense Firewall, обмен трафиком внутри VPN




Результат настройки VPN IpSec между Pfsense и MikroTik




После успешно принятых настроек, проверить соединение VPN типа IpSec между Pfsense и MikroTik можно так:




Pfsense и MikroTik, статус VPN туннеля IpSec




MikroTik и Pfsense, статус VPN IpSec туннеля




Источник: https://xn—-7sba7aachdbqfnhtigrl.xn--j1amh/pfsense-i-mikrotik-nastrojka-vpn-tunnelya/



2022-08-08T00:21:27
Network

Как диагностировать проблемы соединения в Kubernetes при помощи Mizu

Стоит попробовать Mizu – это ПО для мониторинга Kubernetes-трафика. Программа может сильно упростить ежедневную диагностику сетей, да и жизнь в целом.




Одна из наиболее частых задач, с которыми сталкиваются администраторы Kubernetes по ходу тестирования и дебаггинга – проверка коммуникаций между компонентами внутри сети. 




Если вы хоть как-то взаимодействуете c Kubernetes по работе, то наверняка частенько проверяете входящий трафик, чтобы изучить входящие запросы и т.п. Обычно задачи подобного рода решаются при помощи утилиты tcpdump, установленной в конкретный контейнер. Таким образом, проверяются некоторые сетевые аспекты вне контейнеров, но иногда такой подход оказывается довольно сложным из-за специфики окружения или конфигурации системы. 




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




Mizu можно описать как простой, но при этом мощный инструмент для отслеживания трафика в Kubernetes. Он позволяет отслеживать все API-коммуникации между микросервисами независимо от используемого протокола и упрощает процесс дебаггинга соединений.




Установка Mizu




Процесс установки довольно простой. Все что нужно – загрузить бинарный файл Mizu и настроить соответствующие разрешения в системе. Выбор бинарного файла (установщика) зависит от архитектуры устройства. Например, чтобы установить Mizu на компьютер Apple с чипом Intel нужно ввести в терминал команду:




‌curl -Lo mizu github.com/up9inc/mizu/releases/latest/download/mizu_darwin_amd64 && chmod 755 mizu && mv mizu /usr/local/bin




Обычно этого достаточно. Загруженный бинарный файл теперь можно использовать для подключения к кластеру Kubernetes и работы с Kubernetes API, но для этого нужно внести несколько изменений в настройки Докера. 




Вот как это может выглядеть в случае с базовым nginx-сервером. Начать стоит с команды:




‌kubectl run simple-app --image=nginx --port 3000




После развертки базового приложения на основе nginx переходим непосредственно к запуску Mizu. Делается это всего одной командой:




mizu tap




Через пару секунд на экране появится веб-страница с интерфейсом Mizu. Здесь и отображается весь трафик на выбранном сервере. Но для настройки такого поведения необходимо внести изменения в параметры портов. К примеру, если ваше приложение называется ‘my-app’, команда будет выглядеть так:




kubectl expose pod/my-app




После этого деплоим еще один временный сервер, используя готовый образ (при помощи следующей команды):




kubectl run -it --rm --image=curlimages/curl curly -- sh




Теперь можно использовать утилиту curl для отправки запросов непосредственно на nginx-сервер. Например, так:




curl -vvv http://my-app:3000




Уже после первых нескольких запросов вы увидите большой объем полезной информации, отображающейся в интерфейсе Mizu. В первую очередь стоит отметить то, насколько детально описываются все процессы, происходящие внутри Kubernetes. Но что еще важнее, в Mizu есть диаграммы, наглядно показывающие зависимости между запросами с учетом используемого протокола и другой полезной информации. 




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




Источник: https://te.legra.ph/Kak-diagnostirovat-problemy-soedineniya-v-Kubernetes-pri-pomoshchi-Mizu-07-09



2022-08-07T23:59:02
DevOps

🐳 Как изменить конфигурацию запущенных контейнеров Docker

Контейнеры Docker обычно считаются неизменяемыми после начала их работы.




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




В этом руководстве мы покажем вам, как использовать встроенные команды Docker для изменения выбранных параметров запущенных контейнеров.




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




Переименование контейнера




Самым простым изменением является переименование созданного контейнера. Имена присваиваются с помощью флага –name для команды docker run.




Если имя не указано, демон Docker присваивает случайное имя.




Вы можете использовать имена для ссылок на контейнеры в командах Docker CLI; выбор подходящего запоминающегося имени позволяет избежать выполнения команды docker ps для поиска автоматически назначенного имени или ID контейнера.




Команда docker rename используется для изменения имен контейнеров после создания.




Она принимает два аргумента: ID или текущее имя целевого контейнера и новое имя, которое нужно присвоить:




# docker rename <target ID or name> <new name>
docker rename old_name new_name




Изменение политики перезапуска




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




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




Docker поддерживает изменение политик перезапуска “на лету”.




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




docker update --restart unless-stopped demo_container




Приведенный выше пример изменяет политику перезапуска demo_container на unless-stopped.




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




Изменение лимитов аппаратных ресурсов




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




Вы должны передать один или несколько идентификаторов или имен контейнеров, а также список флагов, определяющих ограничения, которые необходимо установить для этих контейнеров.




Флаги доступны для всех ограничений ресурсов, поддерживаемых docker run.




Вот краткий список опций, которые вы можете использовать:




  • –blkio-weight – Изменить относительный вес Block IO контейнера.
  • –cpus – Установить количество процессоров, доступных контейнеру.
  • –cpu-shares – Установить относительный вес доли ЦП.
  • –memory – Изменить лимит памяти контейнера (например, 1024M).
  • –memory-swap – настройка объема памяти, который контейнер может обменять на диск; используйте размер, например 1024M, чтобы установить определенный лимит, или -1 для неограниченной замены.
  • –kernel-memory – Изменить лимит памяти ядра контейнера. Контейнеры, испытывающие недостаток памяти ядра, могут негативно влиять на другие рабочие нагрузки на хост-машине.
  • –pids-limit – настройка максимального количества идентификаторов процессов, разрешенных внутри контейнера, что ограничивает количество процессов, которые могут быть запущены.




Вот пример использования docker update для изменения лимита памяти и количества CPU для двух контейнеров




docker update --cpus 4 --memory 1024M first_container second_container




Все доступные флаги, кроме –kernel-memory, можно использовать с запущенными контейнерами Linux.




Чтобы изменить лимит памяти ядра, необходимо сначала остановить контейнер с помощью docker stop.




Имейте в виду, что ни один из этих флагов в настоящее время не поддерживается для контейнеров на базе Windows.




Однако они будут работать с контейнерами Linux, запущенными на хост-машине Windows.




Когда не следует использовать эти команды?




Команды docker update и docker rename следует использовать с контейнерами, которые вы создали вручную с помощью команды docker run.




Опасайтесь использовать их для контейнеров, созданных с помощью других инструментов, таких как docker-compose.




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




Кроме того, если вы декларативно определяете ограничения на ресурсы в файле docker-compose.yml, повторное выполнение команды docker-compose up приведет к повторному применению этих исходных ограничений к вашему контейнеру.




Поэтому вам следует придерживаться существующего решения для управления контейнерами, если вы его используете.




Для Compose это означает изменение имен контейнеров и лимитов ресурсов в файле docker-compose.yml, а затем выполнение команды docker-compose up -d для автоматического применения изменений.




Это позволит избежать непреднамеренного сиротства контейнеров или возникновения непреднамеренных побочных эффектов.




Что касается других свойств (образа/порты/тома)?




Аппаратные ограничения, политики ресурсов и имена контейнеров – это единственные параметры конфигурации, которые позволяет изменять Docker CLI.




Вы не можете изменить образ запущенного контейнера; вы также не можете легко изменить другие параметры, такие как привязка портов и тома.




Вам следует создать другой контейнер, если эти значения устарели.




Уничтожьте текущий экземпляр и с помощью команды docker run запустите новый контейнер с новым образом и исправленными настройками.




Поскольку контейнеры должны быть без статических данных и эфемерными, вы должны иметь возможность заменить их в любое время.




Используйте тома для хранения постоянных данных контейнера; этот механизм позволяет повторно подключить файлы с состоянием к новому контейнеру, повторив флаги -v, переданные исходной команде docker run:




docker run -v config-volume:/usr/lib/config --name demo example-image:v1

docker rm demo

# Существующие данные в /usr/lib/config сохранены
docker run -v config-volume:/usr/lib/config --name demo2 example-image:v2




Опасная зона: Изменение других свойств контейнера




Хотя вы должны стремиться заменять контейнеры везде, где это возможно, можно изменять свойства существующих контейнеров путем прямого редактирования конфигурационных файлов Docker.




Будьте осторожны при использовании этого метода: он совершенно не поддерживается, и неправильное изменение может привести к поломке вашего контейнера.




Хотя эта опция предоставляет возможность произвольно редактировать существующие контейнеры, она не будет работать во время их работы.




Используйте команду docker stop my-container, чтобы остановить контейнер, который вы хотите отредактировать, а затем продолжайте вносить свои изменения.




Конфигурационные файлы контейнеров имеют следующий путь




/var/lib/docker/containers/<container id>/config.v2.json




Вам нужно знать полный ID контейнера, а не усеченную версию, которую показывает docker ps.




Для этого можно использовать команду docker inspect:




docker inspect <short id or name> | jq | grep Id







Добравшись до config.v2.json контейнера, вы можете открыть его в текстовом редакторе, чтобы внести необходимые изменения.




В JSON хранится конфигурация контейнера, созданная при запуске docker run.




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




Чтобы добавить привязку к порту, найдите в файле ключ PortBindings, затем вставьте новый элемент в объект:




{
    "PortBindings": {
        "80/tcp": {
            "HostIp": "",
            "HostPort": "8080"
        }
    }
}




Здесь порт 80 в контейнере привязан к порту 8080 на хосте.




Аналогично просто добавлять переменные окружения – найдите ключ Env, затем вставьте новые элементы в массив:




{
    "Env": [
        "FOO=bar",
        "CUSTOM_VARIABLE=example"
    ]
}




После завершения редактирования перезапустите службу Docker и ваш контейнер:




sudo service docker restart

docker start my-container




Заключение




Контейнеры Docker должны быть эфемерными единицами, которые вы заменяете, когда их конфигурация устаревает.




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




Docker обрабатывает наиболее распространенные случаи – изменение имени и корректировка лимита ресурсов в реальном времени – с помощью встроенных команд CLI, таких как docker update.




Когда вы хотите изменить другое свойство, всегда старайтесь в первую очередь заменить контейнер.




Это минимизирует риск поломки и соответствует модели неизменяемости Docker.




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




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




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







Источник: https://t.me/i_DevOps https://te.legra.ph/Kak-izmenit-konfiguraciyu-zapushchennyh-kontejnerov-Docker-07-09



2022-08-07T23:55:44
DevOps