- PVSM.RU - https://www.pvsm.ru -
В данной статье приведен опыт инженера-сетевика по развертыванию виртуальной лаборатории EVE-NG [1] в домашних условиях, для целей подготовки к экспертным экзаменам Cisco.
Я постарался собрать все основные вехи настройки, разбросанные по статьям в интернете и попытался добавить в топологию, попутно изучая, ansible — систему управления конфигурациями. Черновик статьи появился случайно, поскольку мне стало жаль терять накопленный опыт и решил сохранять его в отдельный файл. Вот его я и представляю на ваш суд.
Все решения, приведенные в статье, не претендуют на оптимальность, но абсолютно точно работают.
В качестве хостовой я использую следующую систему: Intel Xeon X3240, 32Gb RAM под управлением Gentoo. Настройка KVM на Gentoo дело достаточно тривиальное и, по правде сказать, я не помню с какими подводными камнями мне пришлось столкнуться при её развертывании. Дело было давно.
Основное, что катастрофически сказывается на производительности лабораторного стенда типа EVE-NG, — это параметр ядра, который запускает возможность использования nested virtualization (вложенную виртуальзацию).
Для процессоров Intel:
kvm-intel.nested=1
Подробнее можно прочесть по ссылке [2].
Образы сетевых устройств для подключения находятся в свободном доступе на самом cisco.com, для скачивания достаточно иметь учётную запись начального уровня. Нам понадобятся XRv [3] и CSR [4].
Скачиваем по указанными ссылкам и следуем рекомендациям в how-to [5].
Проблема, с которой я столкнулся при добавлении образов — как называть директории, куда нужно складывать файлы hda.qcow2. Решение, как всегда, — реверс-инжиниринг. Список заголовков, обрабатываемых EVE-NG зашит в файле:
/opt/unetlab/html/includes/init.php
Приведу его здесь:
$node_templates = Array(
'a10' => 'A10 vThunder',
'clearpass' => 'Aruba ClearPass',
'timos' => 'Alcatel 7750 SR',
'veos' => 'Arista vEOS',
'barracuda' => 'Barraccuda NGIPS',
'brocadevadx' => 'Brocade vADX',
'cpsg' => 'CheckPoint Security Gateway VE',
'docker' => 'Docker.io',
'acs' => 'Cisco ACS',
'asa' => 'Cisco ASA',
'asav' => 'Cisco ASAv',
'cda' => 'Cisco Context Directory Agent',
'csr1000v' => 'Cisco CSR 1000V',
'csr1000vng' => 'Cisco CSR 1000V (Denali and Everest)',
'cips' => 'Cisco IPS',
'cucm' => 'Cisco CUCM',
'ise' => 'Cisco ISE',
'c1710' => 'Cisco IOS 1710 (Dynamips)',
'c3725' => 'Cisco IOS 3725 (Dynamips)',
'c7200' => 'Cisco IOS 7206VXR (Dynamips)',
'iol' => 'Cisco IOL',
'titanium' => 'Cisco NX-OSv (Titanium)',
'nxosv9k' => 'Cisco NX-OSv 9K',
'firepower' => 'Cisco FirePower',
'firepower6' => 'Cisco FirePower 6',
'ucspe' => 'Cisco UCS-PE',
'vios' => 'Cisco vIOS',
'viosl2' => 'Cisco vIOS L2',
'vnam' => 'Cisco vNAM',
'vwlc' => 'Cisco vWLC',
'vwaas' => 'Cisco vWAAS',
'phoebe' => 'Cisco Email Security Appliance (ESA)',
'coeus' => 'Cisco Web Security Appliance (WSA)',
'xrv' => 'Cisco XRv',
'xrv9k' => 'Cisco XRv 9000',
'nsvpx' => 'Citrix Netscaler',
'sonicwall' => 'Dell SonicWall',
'cumulus' => 'Cumulus VX',
'extremexos' => 'ExtremeXOS',
'bigip' => 'F5 BIG-IP LTM VE',
'fortinet' => 'Fortinet FortiGate',
//'radware' => 'Radware Alteon',
'hpvsr' => 'HP VSR1000',
'olive' => 'Juniper Olive',
'vmx' => 'Juniper vMX',
'vmxvcp' => 'Juniper vMX VCP',
'vmxvfp' => 'Juniper vMX VFP',
'vsrx' => 'Juniper vSRX',
'vsrxng' => 'Juniper vSRX NextGen',
'vqfxre' => 'Juniper vQFX RE',
'vqfxpfe' => 'Juniper vQFX PFE',
'linux' => 'Linux',
'mikrotik' => 'MikroTik RouterOS',
'ostinato' => 'Ostinato',
'paloalto' => 'Palo Alto VM-100 Firewall',
'pfsense' => 'pfSense Firewall',
'riverbed' => 'Riverbed',
'sterra' => 'S-Terra',
'vyos' => 'VyOS',
'win' => 'Windows (Legacy template)',
'winstation' => 'Windows Workstation',
'winserver' => 'Windows Server',
'vpcs' => 'Virtual PC (VPCS)'
);
То есть, если нам необходимо добавить образ с любым Linux, как мы будем делать ниже, то достаточно создать директорию /opt/unetlab/addons/qemu/linux-что-то-там/ и положить в неё файл образа hda.qcow2.
Под окружением будем понимать всё, что делает нашу жизнь удобнее.
Несмотря на то, что в EVE-NG разработчики внедрили возможность доступа к консолям сетевых устройств по web с использованием HTML5, доступ со сторонних клиентов удобнее и привычнее. Основное удобство, которое предоставляется putty в моём случае, — это возможность использования буфера обмена. Не работает copy/paste в web-консоли.
Итак, процесс выглядит следующим образом:
Установка putty на машине, откуда будет осуществляться доступ. Я работаю на ПК c ubuntu, поэтому:
sudo apt-get install putty
Но этого мало, нужно еще рассказать браузеру, в моём случае это chrome, как реагировать на ссылки вида telnet://. Для этого необходимо создать файл ~/.local/share/applications/telnet.desktop следующего содержания:
[Desktop Entry]
Version=1.0
Name=Telnet
GenericName=Telnet
Comment=Telnet Client
Exec=/usr/bin/putty %U
TryExec=/usr/bin/putty
Terminal=false
Type=Application
Categories=TerminalEmulator;Network;Telnet;Internet;BBS;
MimeType=x-scheme/telnet
X-KDE-Protocols=telnet
Keywords=Terminal;Emulator;Network;Internet;BBS;Telnet;Client;
После этого консоли будут отлично открываться в putty. Задачу перехода на gnome-terminal с вкладками или его аналог оставлю на потом.
Wireshark — насущная необходимость при изучении сетевых технологий. Очень много написано про его использование. Не стану повторяться. Опишу процесс его настройки.
Установка на клиенте:
sudo apt-get install wireshark
Но снова браузер не понимает как обработать ссылку capture://
Объяснять ему это придется в три этапа:
Этап 1:
Как и в случае с консолями, файл ~/.local/share/applications/wireshark.desktop вида:
[Desktop Entry]
Name=Wireshark
Exec=capture_chrom.sh %u
MimeType=x-scheme-handler/capture;
Type=Application
Этап 2:
Обработчик в виде скрипта на bash на клиентской машине в любой директории из списка PATH:
#!/bin/bash
ip=`echo $@ | sed 's/.*//(.*)/(.*)/1/g'`
interface=`echo $@ | sed 's/.*//(.*)/(.*)/2/g'`
ssh root@$ip tcpdump -i $interface -U -w - | wireshark -k -i -
Этап 3:
Ключевой ssh-доступ между клиентской машиной и EVE-NG.
На клиентской машине (вместо ip_eve поставить адрес EVE-NG):
ssh-keygen -t rsa
ssh root@_ip_eve_ mkdir -p .ssh
cat ~/.ssh/id_eve_ng.pub | ssh root@ip_eve 'cat >> .ssh/authorized_keys2'
После этого будет работать захват трафика в wireshark на стороне клиента. Что нам и требовалось.
На этом непритязательный пользователь может остановиться, но нет предела совершенству и мы продолжаем...
Необходимость ansible для виртуальных лабораторных топологий в начале пути была для меня неочевидна. Но со временем, на втором десятке лабораторных часов, приходит мысль — а не автоматизировать ли загрузку стартовых топологий в устройства, не перегружая их, тем самым экономя время?
Итак, с чего начать? С ограничений ansible! Да, они действительно есть. Для меня, как достаточно далекого от программирования, слишком жестоким оказалось предложение на одном из форумов — дописать обработчик телнета самому. Телнет нужен был для решения в лоб — настроить ansible на виртуальной машине EVE-NG и телнетится на консольные порты виртуальных маршрутизаторов. Но не тут-то было — работает только ssh.
Но мы старые инженеры и не привыкли отступать! Если гора не идёт к Магомету, то двинем мы к ней — настроим отдельный инстанс с ububtu в самой топологии, благо для этого есть возможность.
Как разворачивать в KVM образ скаченный с ubuntu.com я приводить не буду. Делал я это на отдельной машине, настраивал и заливал в EVE-NG. После установки нам понадобятся пакеты с telnet-сервером и настройка статического IP-адреса.
У меня не вышло заставить EVE-NG показать мне консоль сервера стандартным способом через клик по девайсу. Чтобы не закапываться глубоко, я пошел в обход — настроил telnet-сервер. SSH v2, конечно, тоже имеется и работает с CSR, но уж очень медленно для интерактивной работы, да и бесполезно — у нас лабораторный стенд, а не продакшн.
Потом необходимость в сервере отпала, но запись в шпаргалке осталась, поэтому приведу и её.
Итак, приступим:
sudo apt-get install xinetd telnetd
После автоматического запуска xinetd, конечно, ничего не произошло, как нам обещали в интернете.
Нужно добавить в /etc/xinetd.d файл telnet следующего содержания:
service telnet
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
}
и перезапустить сервер xinetd:
sudo service xinetd restart
Проверяем телнет локально:
@ansible-server:~$ telnet 127.0.0.1
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Ubuntu 16.04.2 LTS
ansible-server login:
Работает!
Закачиваем полученный образ в виртуальную машину EVE-NG и пробуем собрать топологию.
Теперь мы можем, настроив на соседней цыске в топологии адрес из подсети сервера, до него достучаться по telnet. Всё работает быстро, не в пример SSH.
Здесь всё чрезвычайно просто. Моя топология выглядит следующим образом:
Выделим на каждом маршрутизаторe отдельный порт для управления и подключим к общему хабу с сервером ansible портами Gi2. Выберем подсеть для управления, у меня это 192.168.0.0/24. И назначим IP-адреса на портах в соответствии с номером маршрутизатора.
Эту же информацию занесем в /etc/hosts сервера:
192.168.0.1 R1
192.168.0.2 R2
192.168.0.3 R3
192.168.0.4 R4
192.168.0.5 R5
192.168.0.6 R6
192.168.0.7 R7
192.168.0.8 R8
192.168.0.9 R9
192.168.0.10 R10
192.168.0.11 XR1
192.168.0.12 XR2
192.168.0.20 SW1
На каждом маршрутизаторе настроим SSH v2 согласно ссылки [6]. Всё тривиально, скажу лишь то, что для запуска требумеого нам SSHv2 нужно генерировать ключ более 768 бит, я выбрал размер 2048.
Проверяем доступ с сервера до маршрутизаторов по SSH, заодно собирая в хранилище ключи.
Сохраняем конфигурацию на маршрутизаторе:
R1#wr
Building configuration...
[OK]
И экспортируем в EVE-NG конфигурацию для того, чтобы заново не настраивать при перезагрузках девайсы:
Эта фича в EVE-NG, как и Unetlab до неё, работает с переменным успехом. Но будем надеяться.
Как мы помним [7], структура ansible состоит из двух основных частей — описания девайсов (inventory), и воркбука, собственно с логикой работы системы.
В нашем случае inventory достаточно примитивен и файл его содержащий (/etc/ansible/hosts) принимает вид:
[ios]
R[1:10]
Что раскрывается списком хостнеймов от R1 до R10 (помним, что мы уже прописали /etc/hosts для разрешения имён).
А вот с ворбуком придется повозиться.
Первым этапом, для того, чтобы залить конфигурацию, представляющую для нас лабораторный интерес, на виртуальный маршрутизатор IOS, нам необходимо сделать откат на начальную нулевую, содержащую только IP управления и настройки VTY.
Для этого мы попытаемся использовать модуль ios_command. [8]
Основой всей работы по смене конфигураций в устройствах IOS для нас будет служить функционал команды привилегированного режима маршрутизатора:
configure replace scp://[PATH] force
Нулевые конфигурации будем хранить на сервере в домашнем каталоге нового пользователя под именем router в директории /home/router/default_configs/. Забегая вперед, скажу, что файлы будут иметь имена такие же, как и в inventory, т.е. в нашем случае это R1, R2 и т.д.
Создадим в /opt/ansible файл rollback.yml вида:
- name: rollback
hosts: ios
serial: 1
connection: local
gather_facts: false
remote_user: cisco
tasks:
- name: Performing rollback to default configuration.
ios_command:
commands: configure replace scp://router:cisco@192.168.0.101:~/default_configs/{{ inventory_hostname }} force
timeout: 30
Итак, по порядку:
Название плейбука:
- name: rollback
Название используемого инвентори:
hosts: ios
Количество параллельно конфигурируемых устройств из инвентори. Важная часть последующей оптимизации производительности.
serial: 1
Как я понял, это говорит о соединении с локальным обработчиком заданий. Могу ошибаться.
connection: local
Отключение сбора информации о хостах:
gather_facts: false
Имя пользователя для соединения с устройствами:
remote_user: cisco
Вызов модуля:
ios_command:
Передача команды в устройство из инвентори:
commands: configure replace scp://router:cisco@192.168.0.101:~/default_configs/{{ inventory_hostname }} force
Время ожидания отклика в секундах:
timeout: 30
Ничего особо сложного, как мы видим, но есть одно но!
Попытаемся запустить...
ansible-playbook ./rollover.yml -k -vvvv
Получаем ошибку!
"msg": "ios_command does not support running config mode commands. Please use ios_config instead"
Гугл нам этом не особо много расскажет, поэтому вооружаемся смекалокой и пытаемся найти кто же нам это заявил. И находим файл самого используемого нами модуля: /usr/local/lib/python2.7/dist-packages/ansible-2.3.0-py2.7.egg/ansible/modules/network/ios/ios_command.py, содержащий вот такой код:
if module.check_mode and not item['command'].startswith('show'):
warnings.append(
'only show commands are supported when using check mode, not '
'executing `%s`' % item['command']
)
elif item['command'].startswith('conf'):
module.fail_json(
msg='ios_command does not support running config mode '
'commands. Please use ios_config instead'
)
Явно, что разработчики немного перегнули палку, отнеся все параметры configure к конфигурационному режиму, поэтому дописываем в соответсвующую строку:
elif item['command'].startswith('configure terminal'):
Заработало!
root@ansible-server:/opt/ansible# ansible-playbook ./rollback.yml -k
SSH password:
PLAY RECAP ******************************************************
R1 : ok=1 changed=0 unreachable=0 failed=0
R10 : ok=1 changed=0 unreachable=0 failed=0
R2 : ok=1 changed=0 unreachable=0 failed=0
R3 : ok=1 changed=0 unreachable=0 failed=0
R4 : ok=1 changed=0 unreachable=0 failed=0
R5 : ok=1 changed=0 unreachable=0 failed=0
R6 : ok=1 changed=0 unreachable=0 failed=0
R7 : ok=1 changed=0 unreachable=0 failed=0
R8 : ok=1 changed=0 unreachable=0 failed=0
R9 : ok=1 changed=0 unreachable=0 failed=
Не стану описывать так же подробно, как на предыдущем этапе, просто приведу пример воркбука, который заливает тематическую начальную конфигурацию лабораторных работ одного известного бренда с тремя буквами в названии:
/etc/ansible/hosts
[ios]
R[1:10]
[ios.base.ipv4]
R[1:6]
/opt/ansible/base.ipv4.yml
- name: base.ipv4
hosts: ios.base.ipv4
connection: local
gather_facts: false
remote_user: cisco
serial: 1
tasks:
- name: base.ipv4 configuration load
ios_config:
src: ./IOS-XE-initials/base.ipv4/{{ inventory_hostname }}
Файлы начальных конфигурации лежат в /opt/ansible/IOS-XE-initials/base.ipv4, соответственно. Основное отличие данного сценария — это использование функционала модуля ios_config [9]и передача права ему интерпретировать те команды, которые необходимо выполнить на устройствах.
На этом всё, спасибо за внимание. Если статья достойна продолжения, то следующей темой станет настройка взаимодействия IOS XR и ansible.
Автор: sfinks777
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/virtualizatsiya/247092
Ссылки в тексте:
[1] EVE-NG: http://www.unetlab.com/
[2] ссылке: https://fedoraproject.org/wiki/How_to_enable_nested_virtualization_in_KVM
[3] XRv: https://upload.cisco.com/cgi-bin/swc/fileexg/main.cgi?CONTYPES=Cisco-IOS-XRv&msg=Download+complete
[4] CSR: https://software.cisco.com/download/release.html?mdfid=284364978&softwareid=282046477&release=3.16.5S&relind=AVAILABLE&rellifecycle=ED&reltype=latest
[5] how-to: http://www.unetlab.com/2014/11/adding-cisco-xrv-images/#main
[6] ссылки: http://xgu.ru/wiki/Cisco_SSH
[7] помним: https://habrahabr.ru/post/195048/
[8] ios_command.: https://docs.ansible.com/ansible/ios_command_module.html
[9] ios_config : https://docs.ansible.com/ansible/ios_config_module.html
[10] Источник: https://habrahabr.ru/post/323014/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.