Ошибка STOP 0x0000009E на узле кластера Exchange

Жил-был обычный кластер Exchange 2010 и, после некоторого роста количества баз в Database Availability Group, один из двух DB-серверов внезапно начал падать с синим экраном и ошибкой 0x0000009E по ночам аккурат во время бэкапа. Но не всегда. Конечно же, он сразу перезагружался и к утру был в строю, но бэкап-то прерывался…

Поиск возможных причин падения показал, что все не так просто. За время существования ОС Windows обязательных и необязательных апдейтов, которые фиксят эту ошибку вышло достаточно, но дальнейшее изучение показало, что все эти апдейты уже установлены. А сервер продолжает падать с завидной регулярностью.

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

Начали тщательно изучать все графики заббикса и увидели, что в момент начала бэкапа среднее время ответа дисковой подсистемы резко вырастает до 6000 мс (я не ошибся с нулями), затем данные от заббикс-агента отсутствуют, а затем, спустя минут 20-30 происходит ребут. В общем, было видно, что после роста количества (но не размера) баз дисковая подсистема перестала справляться с нагрузкой. Но причем тут синий экран?

Ответ кроется в логике работы Cluster Service: если на определенном этапе сервис перестает отвечать на время, превышающее 60 секунд (по умолчанию), то система выпадает в синий экран и перезагружается, предполагая, что с кластером что-то не то и эта нода не живая. За таймаут и действие по умолчанию отвечают два параметра: ClusSvcHangTimeout и HangRecoveryAction. Просмотреть текущие значения этих параметров можно при помощи команды:

cluster /cluster:clustername /prop

Установить таймаут можно командой:

cluster /cluster:clustername /prop ClusSvcHangTimeout=x

где x — время в секундах.

Но мы решили временно, до апгрейда серверов, установить другое действие по умолчанию, а именно «Запись в лог». Делается это так:

cluster /cluster:clustername /prop HangRecoveryAction=x

В данном случае x может быть от 0 до 3: 0 — отключить мониторинг и не делать вообще ничего, 1 — записать в лог, 2 — остановить Cluster Service, 3 — вызвать «синий экран смерти» с ошибкой 0x0000009E

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

Не работает смена истекшего пароля в OWA Exchange 2010

Функционал по смене пароля в Outlook Web App бывает полезным во многих случаях. Например: у вас истек срок действия пароля от рабочей учетной записи, а в офис вы попасть в ближайшее время не сможете, но почту читать и отправлять надо. В нормальных условиях, если это было разрешено, OWA предлагает сменить пароль для учетной записи при авторизации. Однако, установка Rollup 25 на Exchange 2010 sp3 ломает эту возможность. Вместо диалога по смене пароля вы получаете ответ «неправильное имя пользователя или пароль». Можно, конечно, откатить апдейт, но обычно это не самый удобный вариант.

Для исправления этого косяка надо:
1. Открыть IIS на сервере, который обслуживает OWA.
2. Перейти в Default Web Site.
3. В правой панели кликнуть дважды на Modules.
4. В панели действий (Actions) нажать Configure native modules.
5. Выбрать exppw и нажать OK.
6. После этого сделать iisreset и проверить. Возможность смены пароля должна появиться.

Аналог IncludeOptional в веб-сервере nginx

Современные панели управления для веб-серверов, призванные облегчить администрирование оных (либо используемые в целях продажи виртуального хостинга) все еще не позволяют гибко настраивать nginx для каждого аккаунта через веб-интерфейс. Оно и понятно. Возможных настроек существует просто огромное количество и делать для всего этого веб-интерфейс ради каких-то 0,5% пользователей, которым не хватает стандартных настроек — бессмысленно. В качестве лайфхака некоторые панели позволяют администраторам серверов вписывать для конкретных хостов настройки в отдельные файлы, которые обычно остаются пустыми, но при этом все равно создаются в файловой системе. Что делать, если кастомные настройки нужны, а плодить пустые файлы не хочется?

В веб-сервере Apache для этого существовала специальная директива IncludeOptional, которая попросту игнорировалась в случае, если такого файла не было в файловой системе, либо если использовались маски для файлов и ни один файл не попал под маску.

К счастью, разработчики веб-сервера nginx поступили дальновиднее и просто позволили включать директивой include файлы с маской. При этом, естественно, никаких ошибок при отсутствии файлов, попавших под маску тоже не генерируется. Но что делать, если вы хотите включить конкретный файл и не хотите «случайного» включения туда «левого» файла по маске? Использовать небольшую хитрость — задать имя файла в виде include /usr/local/etc/nginx/optional_config_file.con[f]. Т.е. мы якобы задаем маску, но под эту маску попадает только один файл. При этом, в случае отсутствия файла никаких ошибок не появится.

ZFS. Почему заканчивается место в пуле? Подводные камни ZVOL на raidz.

Файловая система ZFS — достаточно продвинутая и многофункциональная. Тут вам и дедупликация, и сжатие, и контрольные суммы, продвинутое кэширование и т.д. Одно из хороших применений ZFS — создание ZVOL на ее основе и дальнейшее расшаривание их по iSCSI для любых целей. Плюсы достаточно очевидны: надежность хранения как на любом RAID, отсутствие дорогих аппаратных RAID-контроллеров, быстрое восстановление массива в случае замены диска (ZFS не перестраивает весь массив, как классические RAID — перестраивается только реально необходимое место). Но потом всплывают малоизвестные минусы…

Итак, при создании ZVOL с параметрами по умолчанию (а именно volblocksize=8k) на raidz и заполнении всего раздела данными мы можем внезапно обнаружить очень немаленький оверхэд по реальному размеру, занимаемому этим разделом в массиве. Причем речь идет не о 10%, которые можно было бы простить «на служебные нужды». Речь легко может идти о 60-70% оверхэда. Да-да, при размере ZVOL в 1 ТБ, он вполне может занять 1.7 ТБ в вашем массиве. И произойдет это ровно в тот момент, когда вы этого ожидаете меньше всего — массив заполнен полезными данными, а найти такое количество места, чтобы быстро сбросить туда всё — нереально.

К сожалению, никаких «магических» способов исправить такую ситуацию, когда она уже случилась — нет. Более того, скорее всего вам придется уничтожить весь zpool для того, чтобы вернуть его к жизни — так как даже при удалении всех zvol в массиве вы не сможете создать такое же количество новых zvol с тем же размером. Т.е. только zfs destroy/zpool destroy/zpool create/zfs create.

А теперь немного цифр. Я провел тесты для определения потерь места на массиве raidz из 8 HDD с разными volblocksize. Ниже в таблице представлены результаты тестов. Методика такая: создаем ZVOL на 5 ГБ с размерами блоков 4k, 8k, 16k, 32k, 64k и 128k. После этого при помощи dd с параметром bs=8k записываем данные на раздел пока dd не скажет, что место закончилось. Далее при помощи команды zfs get all zpool/zvol1 смотрим на параметр used — он-то и расскажет о реально занятом месте.

Размер блока 4k 8k 16k 32k 64k 128k
Занятое место 8,52 ГБ 8,48 ГБ 6,34 ГБ 5,28 ГБ 5,27 ГБ 5,01 ГБ
% 170,4 169,6 126,8 105,6 105,4 100,2

Для моих целей прекрасно подошел размер блока 128к, т.к. мелкие файлы на нем не хранятся и потери в таком случае будут минимальны. Следует учитывать, что эти сведения актуальны для массива raidz из 8 дисков. Если у вас raidz2 или другое количество дисков — данные будут другими. Как вариант, вы можете использовать комбинации stripe и mirror — они лишены этой неприятной особенности.

Route-based IPSEC VPN между Ubuntu 18.04 (libreswan) и Cisco Router

В корпоративном секторе, особенно в больших компаниях с более, чем одним офисом зачастую возникает необходимо в site-to-site VPN-соединениях. Конечно, большинство провайдеров предлагает вам «прямую связь» через их оборудование. Но как-то так сложилось, что надежность этого решения зависит только от самого провайдера и из-за некорректных действий одного-единственного админа может зависеть целостность вашей сети. Такие объединения сетей частенько выполняются просто на уровне отдельного тегированного VLAN. И если кто-то внезапно (вполне может быть по неосторожности) скрестит вашу сеть с другими или просто снимет теги на портах — вы рискуете получить в свою сеть трафик от многих клиентов провайдера, а они, в свою очередь, получат беспрепятственный доступ в вашу сеть. Именно по этой причине доверять стоит только собственноручно поднятому IPSEC VPN. Если что-то пойдет не так — VPN просто развалится и сети будут изолированы друг от друга.

В каких случаях Route-based VPN удобнее, чем обычный site-to-site? Например, если вы хотите предоставить N хостам из одной сети доступ к ресурсам в другой сети, но создавать для этого клиентские соединения неудобно. Также, если у вас много подсетей с одной из сторон (или с обеих) и вы не хотите плодить IPSEC SA (как произойдет в случае обычного Policy-based IPSEC VPN). Или, например, вы хотите пробросить весь трафик нескольких клиентов через роутер в другой стране. Во всех этих случаях полезно и удобно будет использовать Route-based VPN.

Итак, начнем с оборудования. В моем случае это был Cisco Router серии ASR с одной стороны и сервер с Ubuntu 18.04 с другой. Цель — пустить трафик N клиентов в интернет через удаленный сервер. Начнем с Ubuntu:

  1.  Установим libreswan.
    apt-get install libreswan
  2. Разрешим форвардинг пакетов и отключим редиректы.
    echo "net.ipv4.ip_forward = 1" | tee -a /etc/sysctl.conf
    echo "net.ipv4.conf.all.accept_redirects = 0" | tee -a /etc/sysctl.conf
    echo "net.ipv4.conf.all.send_redirects = 0" | tee -a /etc/sysctl.conf
    for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
  3. Применим настройки.
    sysctl -p
  4. Создадим в /etc/ipsec.d/ файл с конфигурацией нашего VPN и поместим в него следующий контент:
    nano /etc/ipsec.d/route-based-ipsec-vpn.conf
    
    config setup
        protostack=netkey
    conn vpn
        authby=secret
        pfs=no
        rekey=yes
        keyingtries=3
        type=tunnel
        auto=start
        ike=aes256-sha1;modp1536
        phase2alg=aes256-sha1;modp1536
        left=11.11.11.11
        right=22.22.22.22
        leftsubnet=0.0.0.0/0
        rightsubnet=0.0.0.0/0
        mark=5/0xffffffff
        vti-interface=vti01
        vti-routing=no

    Если один из ваших роутеров находится за NAT (например left), вам необходимо заменить в директиве left адрес на внутренний адрес интерфейса (left=10.0.0.1) и добавить директиву leftid с реальным адресом (leftid=11.11.11.11).  И, конечно, пробросить порты UDP 500, 1701 и 5000 на этот роутер. В противном случае туннель не поднимется.

    Краткие пояснения по конфигурационному файлу:
    authby=secret — авторизация по паролю, а не по сертификатам;
    vti-interface=vti01 — интерфейс, который будет создан автоматически при создании туннеля;
    vti-routing=no — не создавать маршруты на интерфейс туннеля автоматически.

  5. Далее необходимо придумать сгенерировать стойкий пароль на много символов (все равно вам его запоминать не надо) и внести его в файл.
    nano /etc/ipsec.d/route-based-ipsec-vpn.secrets
    
    11.11.11.11 22.22.22.22: PSK "%908A2R5vX9O694aoxh1"
  6. Делаем ipsec restart и ipsec verify. После ipsec verify у нас должно появиться что-то типа этого:
    Verifying installed system and configuration files
    
    Version check and ipsec on-path                         [OK]
    Libreswan 3.23 (netkey) on 4.15.0-1021-aws
    Checking for IPsec support in kernel                    [OK]
     NETKEY: Testing XFRM related proc values
             ICMP default/send_redirects                    [OK]
             ICMP default/accept_redirects                  [OK]
             XFRM larval drop                               [OK]
    Pluto ipsec.conf syntax                                 [OK]
    Two or more interfaces found, checking IP forwarding    [OK]
    Checking rp_filter                                      [ENABLED]
     /proc/sys/net/ipv4/conf/all/rp_filter                  [ENABLED]
     /proc/sys/net/ipv4/conf/default/rp_filter              [ENABLED]
     /proc/sys/net/ipv4/conf/eth0/rp_filter                 [ENABLED]
     /proc/sys/net/ipv4/conf/ip_vti0/rp_filter              [ENABLED]
      rp_filter is not fully aware of IPsec and should be disabled
    Checking that pluto is running                          [OK]
     Pluto listening for IKE on udp 500                     [OK]
     Pluto listening for IKE/NAT-T on udp 4500              [OK]
     Pluto ipsec.secret syntax                              [OK]
    Checking 'ip' command                                   [OK]
    Checking 'iptables' command                             [OK]
    Checking 'prelink' command does not interfere with FIPS [OK]
    Checking for obsolete ipsec.conf options                [OK]
    

    Если failed нигде не написано — можно жить.

  7. Заставляем трафик прятаться за айпишник нашего интерфейса при выходе наружу (в данном примере внешний интерфейс — eth0) при помощи iptables:
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  8. Прописываем маршруты в нашу удаленную сеть (предположим, что на другом конце есть сети 192.168.0.0/24 и 192.168.10.0/24).
    ip route add 192.168.0.0/24 dev vti01
    ip route add 192.168.10.0/24 dev vti01
  9. На этом этапе настройка Ubuntu закончена и мы переходим к настройке Cisco ASR. Продолжение следует (линк на него будет в конце этой статьи).

При написании этого материала помог личный опыт, статья https://libreswan.org/wiki/Route-based_VPN_using_VTI и гугл.

UPD: Для автоматического прописывания маршрутов можно воспользоваться конфигурацией netplan. Для этого необходимо внести изменения в файл /etc/netplan/50-cloud-init.yaml:

        vti01:
dhcp4: no
addresses: [172.16.0.22/30]
routes:
- to: 192.168.0.0/24
via: 172.16.0.22
- to: 192.168.10.0/24
via: 172.16.0.22

Не забудьте применить изменения командой netplan apply

В этом случае интерфейсу vti01 назначается ip-адрес и через него прописываются маршруты в наши подсети.

Вторая часть статьи с настройкой туннеля ждет вас здесь: https://kulmaks.by/route-based-ipsec-vpn-%d0%bc%d0%b5%d0%b6%d0%b4%d1%83-ubuntu-18-04-libreswan-%d0%b8-cisco-router-%d1%87%d0%b0%d1%81%d1%82%d1%8c-2/