Kibana и Apache

Kibana конечно сама хорошо работает с клиентами. Но лучше спрятать её за нормальным http сервером. Там где мне пришлось развертывать ELK пользуются только Apache, поэтому в качеcтве примера используется данный web сервер.

Сначала в конфигурационном файле kibana.yml определим два параметра:

server.basePath: "/kibana"
server.rewriteBasePath: true

Поскольку Apache выступает фронтендом для разных приложений, доступ к Kibana сделаем через путь http://any.body.com/kibana. В конфиге Apache определим Location.

<Location /kibana>
  ProxyPreserveHost On
  ProxyPass  http://any.ip.com:5601/kibana
  ProxyPassReverse  http://any.ip.com:5601/kibana
</Location>

Собственно, все. Дальше можно включать необходимые вам плюшки web сервера.

Новая книга Андрея Маркелова

Андрей, в прошлом известный преподаватель по RedHat. На данный момент, работающий в народном хозяйстве Швеции в компании Ericsson. Написал новую книгу Введение в технологии контейнеров и Kubernetes. Книга доступна как в печатном виде, так и в формате pdf. Рекомендую.

З.Ы. Регулярно покупаю его книги по OpenStack.

З.З.Ы. Попробовал воспроизвести почти все примеры, которые Андрей описал в книге. Всё работает. Но есть небольшие нюансы, которые в книге не учтены.

При конфигурации кубернетес, в разделе «Подготовка операционной системы» необходимо добавить, что требуется явная загрузка модуля ядра br_netfilter.

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

vim /etc/modules-load.d/k8s.conf
  br_netfilter

и сразу руками загрузить его, что бы не делать перезагрузку системы.

modprobe br_netfilter

Иначе у вас не сработает запись единицы в файл /proc/sys/net/bridge/bridge-nf-call-iptables

И соответственно будет ругаться kubeadm init, при инициализации управляющей ноды.

З.З.З.Ы. Проблема PDF версии книги: символы тире в примерах yaml файлов — это типографские широкие тире. Простой копи-паст не получится.

Еще один пример использования нескольких таблиц маршрутизации

Добавил новый материал в раздел Материалы к курсам.

Два провайдера. Правильная конфигурация таблицы маршрутизации.

Или, что следует сделать в первую очередь при подключении двух и более провайдеров к Linux роутеру.

Странное rancher/docker vs LXC

Решил попробовать модный в кругах девопсов кубернейт/docker. Самое простое развертывание кластера, как мне показалось — использовать rancher, который ставит кубернейт из «коробки». Да и сам запускается в контейнере docker.

Поставил на двух виртуальных машинах. Собрал, запустил. Запустил внутри приложение WordPress (nginx, php, mariadb). Немного удивился, сколько ресурсов съела эта связка. Давно у меня машинка swap на 100% не кушала. Конечно я еще не настолько влез во внутренности. Но всё же. Последний раз такой жор ресурсов с приложением по умолчанию я видел у 1С ERP 🙂

При этом, на той же самой виртуалке LXC контейнер со всем этим добром работает не напрягаясь. В общем буду разбираться. Придётся еще 16 гигов памяти прикупить 🙂

Добавил LVM в первые шаги

Добавил новый материал, посвящённый работе с LVM в «первые шаги» в разделе «Материалы к курсам«.

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

Перенёс перевод параметров ядра Linux.

Со старого wiki перенёс на этот сайт перевод на русский язык конфигурационных параметров ядра Linux. Дела конечно давние, но судя по статистике, народ регулярно заходит на эти страницы.

Заодно вспомнил какие технологии были 10 лет назад. Прикольно 🙂

Осталось перенести «Курс молодого бойца». Но это очень много информации. Так что старый wiki пока поживёт.

postfix и LDAP

Почему мне нравится postfix? Вроде бы sendmail вполне хорошо справляется с обработкой почты. Чем же posfix лучше?

Я предпочитаю хранить информацию о пользователях не в локальных файлах или базах данных типа MySQL, а в LDAP серверах (OpenLDAP, Active Directory и т.п.). И лично для меня решающим фактором перехода с sendmail стало то, как postfix работает с LDAP серверами.

В качестве простого примера можно рассмотреть работу с псевдонимами.

По умолчанию postfix использует всем хорошо знакомый файл /etc/aliases.

alias_maps = hash:/etc/aliases

Но доступ к этому файлу имеет только суперпользователь. Если вы один админ на всю деревню – то особых затруднений это не вызывает. Но если админов несколько? Давать всем пароль root? Вы это серьёзно?

Вот тут то и помогает LDAP, в том числе и возможностью разграничения доступа.

Можно создать ou в котором будут храниться псевдонимы. В текущих схемах OpenLDAP на CentOS я не нашел готовую схему для почтовых псевдонимов. Поэтому для хранения информации о них решил использовать objectClass inetOrgPerson.

У inetOrgPerson три обязательных атрибута: cn, sn и mail. Сn будет использоваться в качестве имени псевдонима и части dn записи. Mail – показывает куда пересылать почту. В простейшем случае в sn можно дублировать информацию из cn.

Например, создадим ou в котором будут храниться псевдонимы:

dn: ou=Aliases,dc=company,dc=ru
objectclass: organizationalUnit
objectclass: top
ou: Aliases

И добавим туда простейший псевдоним:

dn: cn=psevdo,ou=Aliases,dc=company,dc=ru
cn: psevdo
mail: localuser
mail: anotheruser@mail.ru
objectclass: inetOrgPerson
objectclass: top
sn: psevdo

Для того, что бы postfix работал с OpenLDAP следует создать текстовый файл фильтра, например /etc/postfix/ldap_aliases.cf следующего содержания:

# или имя сервера
server_host = 1.2.3.4
# контейнер, где хранятся псевдонимы
search_base = ou=Aliases,dc=company,dc=ru
# искать во всем дереве, начиная с указанного выше контейнера
scope = sub
# запрос к LDAP серверу
query_filter = (&(objectClass=inetOrgPerson)(cn=%u))
# атрибут, который мы должны получить в ответ в результате поиска
result_attribute = mail
# Пользователь, с правами которого мы обращаемся к серверу
bind_dn = cn=proxy user,dc=company,dc=ru
# Пароль этого пользователя
bind_pw = this_is_a_password_proxy_user

В файле main.cf добавляем фильтр поиска:

alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap_aliases.cf

Т.е. у нас остается классический вариант /etc/aliases и к нему добавляется поиск псевдонимов в LDAP сервере.

В дальнейшем разруливаем права доступа в OpenLDAP для админов, пароль root им больше не понадобится.

Кстати, поле sn можно использовать в качестве логического. Для включения выключения псевдонима.

dn: cn=psevdo,ou=Aliases,dc=company,dc=ru
cn: psevdo
mail: localuser
mail: anotheruser@mail.ru
objectclass: inetOrgPerson
objectclass: top
sn: true

Если хотим, что бы псевдоним работал – присваиваем sn значение true. Для отключения – все что угодно кроме true.

Ну и немного изменим query_filter:

query_filter = (&(objectClass=inetOrgPerson)(cn=%u)(sn=true))

Итак мы можем обратиться к LDAP с любым запросом. Попросить вернуть только нужные нам атрибуты. Как такое сделать в sendmail  я не знаю 🙁

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 сервер настраивается обычным образом.

Вот и все.

Open VPN и хитрый роутинг.

Это глава из учебника, предоставляемого к моим дистанционным курсам. (с) 2008, Артур Крюков www.kryukov.biz

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

Рассмотрим задачу, возникшую у одного из слушателей.

Исходные данные.

Существует внутренняя сеть 192.168.1.0/24. Она выходит в Интернет через роутер с внутренним интерфейсом 192.168.1.1 и внешним интерфейсом 120.3.5.8. Этот и все другие IP адреса взяты совершенно случайно и никакого отношения к реальным серверам не имеют.

Где то «в замке у шефа» в буржуинском сегменте Интернет стоит сервер с IP 110.45.45.8, который тоже принадлежит нашей компании.

Задача 1.

Необходимо весь трафик, предназначенный на WEB сервера (80 порт) отправлять только через сервер 110.45.45.8. Трафик между нашей сетью и этим сервером должен быть зашифрован. Весь остальной трафик из нашей сети должен идти обычным образом.

Задача 2.

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

Что тут сказать, параноидальные задачи, но выполнимые. Итак, будем играть в Штирлица и шифроваться.

Настройка VPN.

Материал, описанный в этом разделе необходим для решения обеих задач.

Для шифрования трафика меду двумя серверами мы будем использовать Open VPN. Сервер, выводящий нашу компанию в Интернет, будет работать как VPN клиент. Сервер в Интернет всегда включен, поэтому он будет работать в качестве VPN сервера.

Open VPN настраивается так же как и в предыдущей главе, поэтому не буду повторять материалы этой главы. Просто покажу готовые конфигурационные файлы клиента и сервера.

Конфигурационный файл VPN сервера.

dev tap0
proto udp
mode server
comp-lzo
log-append /var/log/openvpn.log
daemon
ifconfig-pool 192.168.240.2 192.168.240.12
ifconfig 192.168.240.1 255.255.255.0
tls-server
dh /etc/openvpn/dh1024.pem
ca /etc/pki/CA/CA.crt
cert /etc/pki/tls/certs/server.pem
key /etc/pki/tls/private/server.key
port 5000
user nobody
group nobody
persist-tun
persist—key
verb 0

Необходимо подставить реальные файлы ключей и сертификатов.

Что изменилось в файле конфигурации сервера, по сравнению с предыдущей главой? Во-первых, используется 5000 порт, а не 1194. За время, прошедшее с момента написания первой главы, создатели программы стали рекомендовать использовать порт 5000. На самом деле номер порта может быть любой, но мы будем следовать рекомендациям отцов-основателей.

Конфигурационный файл Linux клиента.

remote 110.45.45.8 5000
dev tap
proto udp
ca /etc/openvpn/certs/CA.crt
cert /etc/openvpn/certs/client.pem
key /etc/openvpn/keys/client.key
client
tls-client
comp-lzo
user nobody
group nobody
ping 30
ping-restart 120
ping-timer-rem
persist-key
persist-tun
verb 0

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

Посмотрим, что получится после настройки такого решения.

Таким образом, мы обеспечили шифрование при передаче данных между первым и вторым серверами. Но этого мало! Надо сделать так, что бы VPN сервер мог доставлять пакеты в сеть 192.168.1.0/24. Поэтому в конфигурации VPN клиента добавим команду push, которая внесет изменения в таблицу маршрутизации VPN сервера.

push "route 192.168.1.0 255.255.255.0 192.168.240.2"

В результате конфигурационный файл клиента будет выглядеть так:

remote 110.45.45.8 5000
dev tap
proto udp
ca /etc/openvpn/certs/CA.crt
cert /etc/openvpn/certs/client.pem
key /etc/openvpn/keys/client.key
client
tls-client
comp-lzo
user nobody
group nobody
push «route 192.168.1.0 255.255.255.0 192.168.240.2»
ping 30
ping-restart 120
ping-timer-rem
persist-key
persist—tun
verb 0

Теперь внимательно приглядимся к нашей схеме. У нас получилось два сегмента внутренних сетей:

  • 192.168.1.0/24
  • 192.168.240.0/24

И два! Целых два выхода в Интернет! Через роутер 192.168.1.1 и роутер 192.168.240.1.

Господа, как только у вас появляется больше чем один выход в Интернет, необходимо использовать дополнительные возможности, предоставляемые ядром Linux в области маршрутизации. Эти возможности очень хорошо описаны в документе Linux Advanced Routing & Traffic Control HOWTO:

Настоятельно рекомендую в дальнейшее подробно изучить данный HOWTO!

А теперь займёмся решением задач.

Решение задачи 1.

Напомню, что требуется сделать.

Нам необходимо весь трафик на WEB сервера (порт 80) отправлять в Интернет через удаленный сервер, через интерфейс с IP адресом 110.45.45.8.

Весь остальной трафик из нашей сети должен выходит в Интернет через локальный сервер, через интерфейс с IP адресом 120.3.5.88.

На удаленном сервере нам надо сделать только NAT преобразование. Все пакеты, пришедшие из сети 192.168.1.0/24 или 192.168.240.0/24 (а вдруг у вас на клиентском сервере работает прокси сервер Squid?) пропускать через SNAT.

Поэтому в firewall удаленного сервера надо добавить следующие правила:

iptables –t nat –A POSTROUTING –o eth0 –s 192.168.1.0/24 -j SNAT --to-source 110.45.45.8
iptables –t nat –A POSTROUTING –o eth0 –s 192.168.240.0/24 -j SNAT --to-source 110.45.45.8 

Не забудьте разрешить прохождение этих пакетов через firewall.

iptables –A FORWARD –p tcp --dport 80 –i tap0 –j ACCEPT

Не забудьте разрешить перенос пакетов с одного сетевого интерфейса на другой.

echo 1 > /proc/sys/net/ipv4/ip_forward

В файле /etc/sysctl.conf отредактируйте строку.

net.ipv4.ip_forward = 1

C удаленным сервером все. Займемся локальным сервером. Наша задача отправлять пакеты предназначенные на 80 порт в Интернет через машину 192.168.240.1.

Добавить маршрут в таблицу маршрутизации? Не поможет, в таблице маршрутизации нельзя указывать порты.

Сделать DNAT? Тоже не поможет, нам нельзя менять IP назначения.

SNAT? Тоже ничего не даст.

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

Пришло время включить дополнительные возможности ядра Linux. А вы знаете, что в Linux можно сделать 256 таблиц маршрутизации? И 512 можно! и даже больше 🙂

Для решения нашей проблемы мы добавим еще одну таблицу маршрутизации.

В этой таблице сделаем маршрут по умолчанию на машину 192.168.240.1 через интерфейс tap0.

Все пакеты, приходящие на наш сервер на 80 порт из внутренней сети, а также все пакеты, которые генерируют программы, работающие на нашем сервере на 80 порт, будем передавать в новую таблицу маршрутизации. А там уровень IP все сделает сам.

Создадим новую таблицу маршрутизации с именем www.

echo 430 www >> /etc/iproute2/rt_tables

Таким образом, мы создали таблицу номер 430 с именем www. Номер и имя можно использовать любые. Главное, что бы они уже не использовались в вашей системе. Вы можете сначала посмотреть содержимое файла rt_tables при помощи программы cat.

cat /etc/iproute2/rt_tables

Добавим в таблицу www маршрут по умолчанию.

ip route add default via 192.168.240.1 dev tap0 table www

Таблица создана. Как заставить необходимые нам пакеты попадать именно в неё? Тут следует сделать два действия:

  1. При помощи iptables и действия MARK пометить пакет. Присвоить ему номер от 1 до 64.
  2. При помощи программы ip, все помеченные нужным нам номером пакеты перенаправить в таблицу www.
iptables –t mangle –A PREROUTING –i eth1 –p tcp --dport 80 -j MARK --set-mark 1 
iptables –t mangle –A OUTPUT –p tcp --dport 80 –d ! 192.168.1.0/24 -j MARK --set-mark 1 

Обратите внимание на то, что метки мы ставим в таблице mangle в цепочках PREROUTING (для пакетов, пришедших из внутренней сети) и OUTPUT (для пакетов, которые генерирует программное обеспечение, работающее на нашей машине), до того, как пакеты попадут в таблицу маршрутизации.

ip rule add fwmark 1 table www

Можете посмотреть какие пакеты, каким таблицам будут передаваться.

ip rule show

После перезагрузки компьютера, привязка к таблице и маршруты пропадут. Поэтому мы должны сделать так, что бы при старте они появились снова. Тут все зависит от дистрибутива. Самый простой способ воспользоваться файлом /etc/rc.d/rc.local (или /etc/rc.d/rc.local.local, зависит от системы, которую вы используете). В этом файле надо дописать правила:

ip route add default via 192.168.240.1 dev tap0 table www
ip rule add fwmark 1 table www

Сама таблица www создается только один раз.

Теперь займемся firewall.

Разрешаем хождение пакетов на 80 порт, через интерфейс tap0.

iptables –A FORWARD –p tcp --dport 80 –o tap0 –j ACCEPT

Остальными правилами разрешаете то, что должно выходить через интерфейс eth0. Я не буду писать эти правила. Посмотрите, как это делалось в разделе, посвященном firewall. Единственное добавление — теперь надо явно указывать output интерфейс при помощи параметра –o.

Последнее замечание — NAT преобразования. Нам необходимо делать NAT только на интерфейсе eth0. На интерфейсе tap0 ничего делать не надо. Там пакеты идут без преобразования.

Решение задачи 2.

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

Единственная подсказка — трафик на 22 порт удаленного сервера не пускайте через VPN. Если вдруг не получится, вы хоть сможете подключиться к удаленному серверу. И вторая причина — в этом соединении уже итак все зашифровано J.