Типовая настройка DMARC

Что есть DMARC

DMARC это очередной механизм защиты от спама и от несанкционированной рассылки почты с домена. Этот механизм используется для:

  • Информирования почтового сервера получателя о наличии записей DKIM, SPF и их использовании. Частично эта же задача решается ADSP и самим SPF, однако DMARC позволяет охватить оба;
  • Рекомендации почтовому серверу получателя об обработке почты с невалидными DKIM и SPF;
  • Получения обратной связи от серверов получаетелей в формате RFC 5969 и RFC 5070, которые позволяют, в частности, узнать о несанкционированной рассылке с домена.

Как работает DMARC

В DNS-зоне домена создается TXT-запись _dmarc, в которой прописываются его параметры. При доставке почты с домена получающий почтовый сервер использует значения параметров этой записи для обработки полученного письма. Типичный пример записи строится следующим образом:

$ORIGIN example.com.
_dmarc     IN    TXT "tag_0=value_0;tag_1=value_1;...tag_N=value_N"

Текст состоит из пар «переменная=значение» с разделителем «;».

Основные параметры DMARC-записи

Параметров DMARC много и все их можно найти в официальной конфигурации. Ниже наиболее важные.

  • v=, версия. Этот параметр обязательный и должен быть первым со значением DMARC1.
  • p=, policy. Обязательный параметр, который должен быть на втором месте. Рекомендуемые действия MTA получателя для невалидной почты. Возможные значения: none — нет рекомендации почтовику; quarantine — предлагает считать получающему MTA почту с невалидными SPF и DKIM подозрительной и проводить дополнительные проверки; reject — рекомендует отклонять любую почту с невалидными SPF/DKIM.
  • sp=, policy для субдоменов. Опциональный параметр и имеет те же значения, что и p.
  • adkim=, опциональный параметр, в значении s (strict) требует совпадения домена в параметре d= DKIM и отправителя. В r (relaxed, по умолчанию) разрешает использование субдоменов. То есть, почта с user@sub.example.com будет валидной при adkim=r и невалидной при adkim=s.
  • aspf=, опциональный параметр, со значениями s (strict) и r (relaxed, по умолчанию) для SPF, требующий совпадения ответа команды MAIL FROM и заголовка From письма. r разрешает субдомены.
  • pct=, опциональный параметр, доля обрабатываемых DMARC писем. По умолчанию 100 (100 %), и может быть снижена для отладочных целей.
  • fo=, fail policy, опциональный с значением по умолчанию fo=0. В значении 0, отсылает обратный отчёт если все проверки невалидны (DKIM, SPF); в значении 1 — если какая-либо из проверок не валидна. Также возможны значения s и d, соответственно для отчетов по DKIM и SPF.
  • ri=, опциональный, время между отчетами. По умолчанию сутки, т.е. 86400 секунд.
  • rua=, опциональный, список почтовых адресов через запятую, на которые высылать агрегированные отчеты. Если адрес находится в том же домене, работает без дополнительных настроек.
  • ruf=, опциональный, список почтовых адресов через запятую, на которые высылать fail-отчеты (о невалидной почте). Если адрес находится в том же домене, работает без дополнительных настроек.

Типовые конфигурации записей DMARC

С домена отправляется почта, мягкий вариант

Мягкий вариант DMARC-записи не указывает какой-либо явной политики (policy) принимающему почтовому агенту (MTA), что делать с нелегитимной почтой. Принимающий почтовый сервер действует в соответствии со своими настройками и обычно такая почта достигает ящика отправителя. Пример записи, с получением обоих типов отчетов (aggregated & fail):

_dmarc   TXT "v=DMARC1;p=none;fo=1;rua=mailto:admin@example.com;ruf=mailto:admin@example.com"

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

С домена отправляется почта, строгий вариант

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

_dmarc   TXT "v=DMARC1;p=reject;sp=reject;pct=100;aspf=r;fo=1;rua=mailto:admin@example.com;ruf=mailto:admin@example.com"

С домена не отправляется почта вообще

На домене чаще не бывает почты, чем бывает. Такие «беспочтовые» домены лучше сразу настроить, чтобы сторонние сервисы воспринимали почту с них как спам. Ниже пример DMARC-записи в DNS, запрещающей отсылку почты с домена.

_dmarc   TXT "v=DMARC1; p=reject; sp=reject; pct=100; aspf=s"

Естественно, SPF-запись тоже должна быть настроена, в наиболее коротком виде:

@        TXT "v=spf1 -all"

Дополнительно

Полную документацию по DMARC можно получить на их официальном сайте и RFC.
Проверить DMARC-запись вашего домена можно, например, с помощью этого сервиса.

Быстрый анализ производительности Linux-сервера

Производительность — один из наиболее заметных параметров системы. Именно на её недостаток чаще всего жалуются пользователи. Ниже приведены некоторые элементарные способы по анализу производительности системы.

Часто ошибочно считает, что поднять скорость системы можно хорошо «оптимизировав» конфиги. Это редко бывает так. Оригинальные стоковые конфиги репозиторного софта подходят для решения многих задач. Их можно (и нужно) менять для достижения задач конкретного проекта. Естественно, все изменения следует сопровождать тестами производительности, а для этого должны быть соответствующие методики и инструменты.

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

  • Собирайте и анализируйте статистические данные о работе системы. На минимальном уровне это решается различными системами мониторинга, например, munin, Zabbix. В более продвинутом случае — свои плагины к этим системам мониторинга или собственные скрипты. Если пару дней назад всё работало отлично, а сейчас какие-то «тормоза» — мониторинг поможет установить их источник. Кроме этого, мониторинг позволяет обнаружить еще не проявившиеся проблемы, когда используемые ресурсы системы исчерпываются.
  • Журналируйте собственные изменения конфигурации. И сравнивайте динамику производительности (по собранным статистическим данным) до включения новой конфигурации и после нее. Это поможет узнать, какие изменения действительно эффективны, а какие бесполезны или даже вредны. Также, журналирование позволит оперативно обнаружить медленный код в бизнес-приложениях.
  • Не перегружайте систему. На небольших нагрузках кажется, что ресурсов системы очень и очень достаточно впрок. Однако, это не так. Когда загрузка какого-либо из ключевых параметов системы подходит к 100% (это может быть, например, загрузка ЦП, или ввода-вывода или даже наличие свободного места на дисках), «тормоза» системы возрастают нелинейно. В том числе это происходит из-за «накладных расходов», т.е. ресурсов системы не расходуемых на определённые процессы, а теряемые в процессе работы ОС и переключения задач.

Процессорное время (CPU)

Load average легко собираются любым мониторингом круглосуточно и его необходимо анализировать. Максимальное значение LA (в часы наибольшей нагрузки) не должно превосходить возможностей системы, т.е. количества её ядер CPU. В противном случае неизбежно замедление работы приложений, причем с увеличением LA выше возможностей системы будут возрастать потери на переключении контекста.

Когда LA достаточно высок имеет смысл посмотреть на что именно расходуются ресурсы процессора. Простейший способ это сделать — посмотреть процессы с наибольшим процессорным временем (TIME) в выводе утилит top, htop или ps aux. Далее уже пытаться снизить нагрузку именно на этом звене.

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

В тех же top и htop следует обратить внимание на процессы в состоянии D, которое обычно соответствует ожиданию ввода-вывода процесса, а также на заполнение свопа. Но об этом ниже.

Коротко (для скриптов мониторинга) значение LA можно взять из параметров системы:

cat /proc/loadavg

Вручную — легче в top и htop.

Характеристики использования процессорного времени отображается также командой vmstat:

$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0   7596 329216  13260 14506756    0    0  4625    26   42  145  4  1 81 13  0

vmstat принимает 2 аргумента: время в секундах, в течение которого необходимо наблюдать за системой, и количество генерируемых отчетов. Эту утилиту полезно запускать для наблюдения, например для формирования 10 отчетов по 1 минуте каждый:

vmstat 60 10

Колонки us (user) и sy (system) означают соответсвенно процессорное время затраченное на пользовательские процессы (демоны и прикладного ПО) и системное. Для большинства систем нормально, если время распределяется между ними поровну.

in (interrupts) и cs (context switches) это количества прерываний и переключений контекста, и оба эти параметра — накладные расходы системы и их не должно быть много.

Разбивку использования CPU по ядрам можно получить с помощью mpstat, например по всем ядрам

$ mpstat -P ALL
Linux 3.2.0-4-amd64 (sys01) 	01/05/15 	_x86_64_	(16 CPU)

16:09:51     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
16:09:51     all    3.55   18.39    9.83    1.24    0.00    0.50    0.00    0.00   66.49
16:09:51       0    5.85   43.47   11.04    1.62    0.00    6.79    0.00    0.00   31.23
16:09:51       1    4.23   29.35   10.81    1.34    0.00    0.11    0.00    0.00   54.17
16:09:51       2    3.86   24.70   10.17    1.26    0.00    0.11    0.00    0.00   59.90
16:09:51       3    3.66   22.73    9.64    1.10    0.00    0.13    0.00    0.00   62.74
16:09:51       4    6.01   15.49    8.84    4.94    0.00    0.26    0.00    0.00   64.47
16:09:51       5    3.15   12.93    8.29    1.43    0.00    0.08    0.00    0.00   74.13
16:09:51       6    2.93   12.90    8.11    1.08    0.00    0.08    0.00    0.00   74.90
16:09:51       7    2.79   14.15    8.43    0.87    0.00    0.07    0.00    0.00   73.69
16:09:51       8    4.01   24.11    8.93    0.93    0.00    0.04    0.00    0.00   61.98
16:09:51       9    2.89   15.37   10.24    0.84    0.00    0.07    0.00    0.00   70.60
16:09:51      10    2.91   15.56   10.64    0.85    0.00    0.07    0.00    0.00   69.98
16:09:51      11    2.78   15.35   10.61    0.81    0.00    0.09    0.00    0.00   70.36
16:09:51      12    2.89   11.69    8.56    0.84    0.00    0.04    0.00    0.00   75.98
16:09:51      13    3.58   12.81   12.09    0.66    0.00    0.03    0.00    0.00   70.83
16:09:51      14    2.95   12.32   11.24    0.66    0.00    0.03    0.00    0.00   72.80
16:09:51      15    2.36   11.60    9.59    0.59    0.00    0.04    0.00    0.00   75.82

Выводимые параметры утилиты понимающему человеку там очевидны.

Оперативная память (RAM)

Использование оперативной памяти «на ходу» анализируется с помощью утилит htop, vmstat, free. Лучше — смотреть в динамике в мониторинге, том же мунине. Прежде всего необходимо обратить внимание на использование свопа, который в хорошей должен быть почти свободным и не увеличиваться/уменьшаться в определённое время суток.

В выводе

$ free -h
             total       used       free     shared    buffers     cached
Mem:           47G        44G       2.3G         0B       559M        26G
-/+ buffers/cache:        18G        29G
Swap:          15G       3.6G        12G

если окажется мало free-памяти, но много cached — это нормально. Память может быть занята страничным кэшем (cached), который многократно увеличивает скорость дисковых операций. Когда «свободной» (free) памяти действительно много это даже плохо и означает, что она не полностью используется. То же самое относится к выводу vmstat.

Ввод-вывод (IO, input-output)

Статистику по ввода-выводу системы лучше собирать пакетами мониторинга. Параметр системы, на который в первую очередь необходимо обратить внимание — iowait, т.е. ожидание ввода-вывода. Его подробные значения можно получить, например, с помощью mpstat:

mpstat -P ALL

Сводные значения есть также в top, vmstat.

Часто признаком наличия проблем с вводом-выводом является большое количество процессов в состоянии D (uninterruptible sleep), в которое процесс переходит при ожидании ввода-вывода. Это не обязательно означает, что дело именно в I/O, но такая ситуация в любом случае должна быть исследована.

Счетчики чтения-записи с дисковых устройств получаются по

$ vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
       total merged sectors      ms  total merged sectors      ms    cur    sec
sda   90878564 7454833 2829423640 647949492 205895042 265140200 14858972810 2510368504      0 448274
sdb   455801809 14612605 57375867578 2021813576 434699644 365377967 109699014136 4291627964      0 2081456
sdd   94938371 343221533 57971885640 3782143884 34980046 34425685 8816083324 1994769084      0 449787
sdf   83996804 354254620 57971510608 1338153836 35203200 34649634 8822861163 2201253492      0 462982
sde   83274303 354838922 57968955195 1266856936 34793484 34477071 8818425628 2217294360      0 461751
sdc   112569402 325806501 57972989224 4284077532 35217039 34782607 8820518859 2068813212      0 446935
sr0        0      0       0       0      0      0       0       0      0      0
loop0      0      0       0       0      0      0       0       0      0      0
loop1      0      0       0       0      0      0       0       0      0      0
loop2      0      0       0       0      0      0       0       0      0      0
loop3      0      0       0       0      0      0       0       0      0      0
loop4      0      0       0       0      0      0       0       0      0      0
loop5      0      0       0       0      0      0       0       0      0      0
loop6      0      0       0       0      0      0       0       0      0      0
loop7      0      0       0       0      0      0       0       0      0      0
md0   289404098      0 44556083939       0 123718867      0 17627362527       0      0      0

Еще более удобная утилита для этого — iostat. Как и vmstat, она принимает 2 параметра (время наблюдения и количество отчетов). Полезно снять несколько расширенных отчетов за некоторый промежуток времени, например, минуту:

$ iostat -x 60 5
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.83   47.27   21.99    1.52    0.00   21.39

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.50    42.87    7.70   40.28    37.27  1732.40    73.76     5.40  112.63   13.26  131.62   2.05   9.83
sdb               9.52    56.27   85.38   60.47  1459.00  5955.80   101.68    14.10   96.69   13.17  214.63   2.46  35.85
sdd               0.08     0.27    0.08    1.47    11.27    40.27    66.49     0.01    5.59   24.80    4.50   4.90   0.76
sdf               0.22     0.50    0.15    2.35    30.27    53.75    67.21     0.02    6.43   31.11    4.85   4.83   1.21
sde               0.17     0.45    0.15    2.28    24.47    44.45    56.64     0.01    4.77   11.11    4.35   3.12   0.76
sdc               0.17     0.32    0.73    1.53    25.47    49.57    66.21     0.02    8.44   12.91    6.30   4.68   1.06
md0               0.00     0.00    1.75    3.25    91.47    93.52    73.99     0.00    0.00    0.00    0.00   0.00   0.00

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

Сеть (Network)

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

Обязательно необходимо убедиться, что настройки скорости и дуплексного режима верны для сетевой карты. Это можно сделать (и изменить) с помощью утилит ethtool и mii-tool:

ethtool eth0

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

ethtool -s eth0 autoneg off speed 100 duplex full

Полезно посмотреть и другие параметры интерфейсов, грепнув их вывода ядра:

dmesg | grep -i eth

Пиковую загрузку сети лучше (как и многое остальное) мониторить постоянно и автоматически, например, тем же munin. Ориентироваться лучше на пиковую нагрузку — по ней должен быть определённый запас и в её время не должно быть больших значений iowait.

Хорошую статистику по сети и разбивку по типам траффика можно получать с помощью ntop.

Что делать

Многие убеждены, что производительность можно многократно поднять («оптимизировать») чисто софтовыми способами, т.е. изменением настроек операционной системы и прикладного софта. На деле это не всегда так.
Ядра современных дистрибутивов Linux уже хорошо настроены в плане производительности. Если задача типовая и «железо» устраивает — менять ничего не нужно. Изменение каких-либо параметров через sysctl на большинстве серверных задач не повысит скорость работы, а при плохом подгоне даже понизит. Тем более, следует скептически относиться ко всем интернет-советам по оптимизации (в том числе, описанным на этом сайте).

Какие-то параметры работы можно оптимизировать: настройками прикладного софта, перераспределением файловой системы. Но большинстве случаев наилучший способ повысить производительности системы — «железный», т.е. изменением аппаратных характеристик сервера или распределением и балансировкой нагрузки по разным серверам. При высокой нагрузке на I/O поможет использование RAID, программных (mdadm) или аппаратных.

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

BiPrint под Windows 8.1 x64

Есть такая древняя утилита для печати двумерного штрих-кода на платежках BiPrint. К сожалению, утилита очень редко обновляется и, что ещё хуже, — всё ещё используется некоторыми российскими банками.

Проблема возникает при попытке установке BiPrint на новые операционные системы. В частности, на Windows 8.1 x64. Кто пытался поставить BiPrint, знает, что последний требует файл ep200.gpd из драйверов старого Epson-принтера. Этот файл легко найти и скачать, однако, он не подписан Microsoft и нормальным образом не добавляется в систему.

Тем не менее, существует вполне рабочее альтернативное решение. Если коротко, то решается проблема следующим образом:

  1. Качаются подписанные Майкрософтом драйвера для принтера Epson PLQ-20 для ОС Windows 7 x64 и этот принтер добавляется в систему на какой-нибудь LPT-порт.
  2. Качается бипринт-клиент для Windows 7 и терминального сервера. Софтина устанавливается и в настройках указывается использование скачанных выше драйверов.
  3. В BiPrint выбирается любой из реальных принтеров и если вышеописанные шаги выполнены правильно, все работает.

Тестирование каналов связи в Linux

В процессе настройки серверов нередко требуется проверить качество работы и скорость каналов связи. Для этого существует ряд удобных утилит. Ниже описывается работа с двумя полезными утилитами: iperf, mtr.

iperf

Другая наиболее важная характеристика сети — скорость канала. Замерить скорость на прием и на передачу можно с помощью утилиты iperf. Для замера требуется запустить утилиту на одном из хостов в режиме сервера, а на другом — в режиме клиента. Запустим её в режиме сервера:

iperf -s

Если требуется проверять скорость до хоста постоянно, то iperf может быть запущен и в режиме демона с опцией -D.

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

iperf -c example.com -r -P 6

Аналогично можно запустить тестирование на одновременную передачу и приём:

iperf -c example.com -r -P 6

По умолчанию один тест длится 10 секунд. Время теста может быть изменено ключем -t, что бывает полезно для повышения репрезентативности результата. По умолчанию утилита тестирует канал по TCP-соединению. Тип соединения на UDP может быть изменен соответствующим ключом (-u), при запуске клиентской и серверной частей. iperf имеет много других полезных параметров (которые я редко использую) — они все естественным образом приведены в мануале.

mtr

Утилита mtr является аналогом другой широко известной утилиты сетевой диагности traceroute. Наиболее простой способ её применить — запустить с параметром другого хоста:

mtr example.com

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

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

mtr example.com -1000

Отключение toolbar в SyntaxHighlighter

Для вордпресса есть удобный плагин подсветки исходного кода SyntaxHighlighter MT. По умолчанию он отображает так называемый toolbar: маленький зеленый квадратик-ссылка с вопросом в крайнем верхнем углу текста. В документации на сайте разработчика описывается, как его можно отключить. Однако, канонического конфигурационного файла (как и конфигурации в самом WordPress) в плагине не наблюдается. Приходится идти обходным путём, а именно отключать toolbar в самом исходном коде. Сделать это можно, например, в файле brushTypes.js, определяющим типы подсветки для разных языков добавлением

SyntaxHighlighter.defaults['toolbar'] = false;

перед строчкой

SyntaxHighlighter.all();

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

О правильном мониторинге

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

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

Минимум настроек apache2 и nginx веб-серверов для повышения безопасности

Рассмотрим типовую схему веб-сервера: nginx используется в качестве фронтэнда (front-end), apache2 — бэкэнда (back-end). Установка пакетов из репозитариев дает стандартную конфигурацию, которая применима для сервера разработки и тестирования. Однако, стоковая конфигурация изначально подстроена под большой класс задач и требует доработки. В частности, в плане безопасности. Опишем минимум настроек, которые необходимо сделать, если настраиваемый сервер выходит в интернет для широкого использования.

apache2

Отключаем потенциально опасные и просто неиспользуемые модули, а также неиспользуемые подконфиги. Почти всегда можно (и нужно) отключить:

  • модуль autoindex, позволяющий просматривать содержимое директории при отсутствии индексного файла,
  • обработку cgi-bin, которая в deb-based системах лежит в конфиге serve-cgi-bin.conf и используется очень редко,
  • Другие неиспользуемые модули (список которых зависит от выкладываемого кода). Т.е. необходимо перешерстить директории mods-enabled, conf-enabled

На продакшн-сервере пользователю не нужно знать точную версию апача. Вообще, подобной информации должно отдаваться как можно меньше. Формат этой информации регулируется параметром ServerTokens, который по умолчанию обычно выставлен в OS и в результате веб-сервер выдает что-то вроде

Apache/2.4.10 (Debian) Server at ...

Этот параметр, как и некоторые другие настройки безопасности в debian-системах обычно находится в конфиге /etc/apache2/conf-available/security.conf. Переключаем в менее информативную и, соответственно, более безопасную версию:

#ServerTokens Minimal
#ServerTokens OS
#ServerTokens Full
ServerTokens Prod

Аналогичным образом стоит поступить с подписью сервера на «ошибочных» страницах

ServerSignature Off
#ServerSignature On

и трассировкой

TraceEnable Off

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

Код некоторых выкладываемых сайтов может содержать скрытые файлы, вроде .gitignore, .svn и других, раскрывающих стуктуру кода. Их желательно отключить здесь же, в апаче, или в фронт-энде. Можно отключить сразу все скрытые файлы:

<DirectoryMatch "/\.">
	Require all denied
</DirectoryMatch>

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

Некоторые из правил для бэкэнда закрывают те же места, что и в фронтэнде. Даже если каким-то образом будет поломана конфигурация nginx, уязвимость все равно не реализуется.

Отключим доступ к скрытым файлам — в секции виртуалхоста добавляем:

RedirectMatch 404 /\..*$

Такие файлы нередко встречаются в проектах. В частности, системы контроля версий вроде git, svn. Эта метаинформация не должна попадать в прошакш, тем не менее следует превентивно защититься от такой возможности.

Если VirtualHost на сервере не один, то также не плохо будет раскомментировать секцию


   AllowOverride None
   Order Deny,Allow
   Deny from all

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


	AllowOverride All
	Order Deny,Allow
	Allow from all

Я не описываю настройку прав доступа (пользователь:группа) на уровне ОС и файловой системы и использование модуля mpm_itk с директивой AssignUserID. Это тоже должно быть сделано для серверов, на которых такое разделение требуется.

nginx

Отключим отображение скрытых файлов:

location ~ /\. {
	deny all;
}

nginx используется как frontend, и если на нем отдается контент по https, то повышаем его безопасность. Для начала отключаем SSLv3 и другие небезопасные протоколы. Если nginx свежий, то в нем это уже и так отключено, поэтому лучше просто обновиться.
Генерируем параметры обмена ключами Diffie-Hellman (которые могут генерироваться достаточно долго, запаситесь временем)

openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

и затем подключаем их в энжинксе

ssl_dhparam /etc/nginx/ssl/dhparam.pem;

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

ssl_ciphers 'AES256+EECDH:AES256+EDH:!aNULL';

Также имеет смысл включить кеширование

ssl_session_cache shared:SSL:10m;

После всех настроек желательно проверить их корректность в каком-нибудь сервисе, например, этом.

PHP

Как и в случае апача скрываем версию

expose_php = Off

В зависимости от задач можно отключить вывод ошибок:

error_reporting = 0
display_errors = Off

 

Проверки

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

HEAD example.com

Также побродим по сайту, в том числе по страницам, которые генерируют 4xx и 5xx ошибки, проверим, что версии софта не раскрываются и тем более не раскрывается внутренняя структура сервиса.

Завершающие замечания

Если на сервере хостится несколько сайтов, то многие из приведённых выше настроек повышают безопасность лишь частично. Сделать хорошую защиту между виртуалхостами на одной машине принципиально будет достаточно сложно. Если такое требуется — лучше смотреть в сторону виртуализации уровня операционной системы, по образцу OpenVZ или lxc.

Со временем пост будет пополняться.

Работа с пользовательскими crontab

Существует несколько способов управления пользовательскими кронтабами.

Редактирование с помощью crontab

Наиболее простой из них — редактирование файла с помощью crontab:

crontab -u USER -e 

Также возможно выполнение от учетной записи пользователя

crontab -e 

что существенно снижает риск по ошибке записать крон от другого пользователя.

Копирование crontab вручную

Другой способ, обычно применяемый при переносе конфигураций серверов — копирование пользовательских кронтабов, находящихся в директории /var/spool/cron. При синтаксически корректных исходных конфигах способ работает безотказно. Единственное, что необходимо для его работы: «тронуть» (touch) конфиги после выкладки или перезапустить крон. Иначе, они не будут выполняться.

Импрорт в crontab из другого конфига

Метод реализуется командой

crontab -u USER /tmp/old-crontab

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

Способы переноса сиcтем контроля версий

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

Настройка DKIM в exim4

Заставить exim4 подписывать исходящую почту совсем просто. Для этого в конфиг экзима /etc/exim4/exim4.conf.template дополняем следующими строками

#########################
## DKIM SETTINGS

DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_FILE = /etc/mail/${lc:${domain:$h_from:}}.key
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
DKIM_SELECTOR = m01

## DKIM SETTINGS END
########################

По вкусу можно поместить конфигурацию не в шаблон, а в какой-нибудь из conf.d-файлов. Далее, чтобы все работало как надо:

  • Создаем пару ключей с помощью openssl,
  • Прописываем открытый ключ в DNS,
  • Закрытый ключ помещаем в /etc/mail/domain_name.key (вместо domain_name имя домена) и меняем его права и владельца на 0640 и root:Debian-exim,
  • Перезагружаем exim4, отправляем тестовое письмо на адрес с включенной верификацией DKIM-подписи и убеждаемся, что все работает правильно.

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

DKIM_SELECTOR = ${extract{-1}{.}{DKIM_PRIVATE_KEY}}

Кроме настройки DKIM в exim полезно настроить обрезание определённых нежелательных заголовков в целях безопасности. Такими, например, могут быть имена формирующих письмо скриптов или IP-адреса отправителей письма (при отправке по SMTP с другой машины, которая может стоять во внутренней сети), которые раскрывают внутреннюю структуру системы. Для этого в тот же шаблон /etc/exim4/exim4.conf.template рядом с DKIM добавляем фильтр по заголовкам

system_filter = /etc/exim4/filter

Содержимое файла конфигурации фильтра /etc/exim4/filter может быть, например, таким

headers remove X-PHP-Originating-Script
headers remove Received

В конце обязательно релодим экзим и проверяем, что все работает корректно. Проверить почту можно прямо из шелла:

$ echo "This will go into the body of the mail." | mail -s "Hello world" -a "From: me@mydomain.com" myemail@example.com

PS: вышеприведенная конфигурация — Debian-based дистрибутивов. Для RedHat и других файлы конфигов могут быть немного другими.

Формирование DKIM ключей

При администрировании почтовых (да и не только почтовых, но и любых отсылающих почту) серверов время от времени требуется создавать DKIM ключи для почты. Эта, в целом несложная, процедура состоит из генерирования ключей, добавления открытого в DNS TXT-запись домена, а закрытого — в конфиг почтового сервера. Ниже по порядку.

Генерировать ключи удобно с помощью широкоиспользуемой утилиты openssl. Чтобы не делать это каждый раз руками, полезно написать скриптик

#!/bin/sh

if [ "$1" != "" ]; then
	openssl genrsa -out "$1.key" 2048
	openssl rsa -in "$1.key" -out "$1.pub" -pubout -outform PEM
	chmod o= "$1.key"
else
	echo "Usage: $0 domainname"
fi

вызывая который с параметром — доменным именем, для которого формируем ключи, получаем пару ключей: публичный (открытый) и приватный (закрытый). В приведенной конфигурации используется 2048-битный ключ, что несколько безопаснее и потому предпочтительнее.

Публичный ключ доступен всем через DNS. Для этого помещаем его в виде TXT-записи для настраиваемого домена с именем x._domainkey, где x — это селектор. Селектор выбирается произвольно и обычно он «привязан» к серверу. Содержимое записи — это сам публичный ключ и некоторые параметры перед ним. Общий формат записи в DNS:

x._domainkey.mydomain.com.   TXT "v=DKIM1; g=*; k=rsa; p=[PUBLIC_KEY]"

Если текст записи достаточно длинный (а 2048-битный таким является), то его лучше разбить на несколько строк. Например, в DNS-сервере bind9, запись будет выглядеть так:

x._domainkey.mydomain.com.	TXT ( "v=DKIM1; g=*; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUkhw8hQQ4NfKAPkvrQqd04Ta2fyVTfrVdbud62HeSISpDzf1GWPGrN0ikqcTT+6DW5fRwOnGO0VkennMs7+d+WkpTJ6Y63ydrFaK/sa8HoESPBJHqrNfViQzlCt5ZCc4UZN1sLLoO3HukwvLRtM"
				"wKMzxIkavknl86PLcTebS3+ac7lWdPoqJbooHQglizs0YazLqQTLn/L6mqv1OgPCMU44seEp/CZilUchbLvHAsrfK8+AADGm+/U/5qt6/SC31ZN/BmAqtMMKvT8rMFw2qj43DPWSkn9ln5EsyUJhQiORNX3v+9rndZNuw2I90xXbuIflc30gLStXG1Jqg4IAXQIDAQAB" )

Первыми в записи идут опции: версия DKIM, гранулярность, тип ключа. Подробности опций лучше прочитать в соответствующем RTFM для стандарта DKIM.

После добавления открытого ключа в DNS лучше проверить его рабочесть. Из шелла это делается так

$ host -t txt x._domainkey.mydomain.com

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

Приватный ключ добавляется в настройки почтового сервера, которые несколько различаются. Обычно приватные ключи хранятся в /etc/mail, причем для безопасности их права лучше сразу поменять на 0640 и изменить владельца так, чтобы ключ смог читать почтовый демон, но не пользователи системы.

Удаленный шелл с использованием nc

Фундаментальным и очень полезным качеством всех линуксов-юниксов является их модульность и возможность сборки из «кирпичиков» нужных инструментов. Это прекрасно иллюстрируется следующим примером из мануала утилиты netcat. Эта утилита передачи и приема произвольных данных по протоколам tcp/udp позволяет сделать элементарный и полностью рабочий шелл для работы с удалённым хостом. И это только используя эту утилиту и стандартные средства Linux вроде pipe и перенаправления данных.

На удалённой машине создаем трубу

$ rm -f /tmp/f; mkfifo /tmp/f

берем из неё данные, исполняем и результат толкаем в netcat, а его ответ обратно в трубу:

$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f

В результате получаем упрощённую нешифрованную версию ssh.

Пишем логи с помощью logger

Системное администрирование серверов в большой степени основано на регулярно исполняемых скриптах. Естественно, результат исполнения скриптов нужно проверять и иногда — логировать. Наиболее простой способ это сделать — использовать перенаправления ввода-вывода 2>&1 совместно с &>>. Однако, есть альтернативный (и в чём-то более удобный) способ это сделать, напрямую в syslog, с помощью команды logger. Тогда логирование сводится к командам вроде

some_script.sh 2>&1 | logger -i

Отдельная «поддиректория» для блога в WordPress

По умолчанию, в стоковой установке WordPress формирует постоянные ссылки (permalinks) для постов неотличимые по внешнему виду от статических страниц. Если WP используется как CMS это может быть нежелательно. В случае CMS часто бывает логичней выкладывать статические страницы с пермалинками начиная с корня /, а посты — начиная с некоторого слова, подсказывающего, что пост относится к блогу, например /blog. Это возможно сделать стандартными средствами вордпресса.

Для того, чтобы настроить WP, чтобы он добавлял префикс /blog в начале пермалинков делаем следующее:

  • В админке Settings -> Reading есть возможность настроить статические страницы по умолчанию (front pages) для основного сайта и для блога. Для сайта в случае использования WP как CMS она обычно настроена. Если не настроена, то создаём такую или выбираем из существующих. Для блога — создаем новую пустую и ставим к ней пермалинк /blog.
  • Выбираем созданные front pages соотвественно для основного сайта и для блога.
  • В Settings -> Permalinks меняем формат пермалинков для постов на /blog/%postname%. Предлагаемые по умолчанию настройки RewriteRules в .htaccess подходят и для нашего случая, их не трогаем.
  • Там же меняем базовый URL для категорий и тегов, например на blog/category и blog/tags.
  • Меняем внутренние линки на посты на новые, а также добавляем 301 редиректы со старых постов на новые.

После этого всё работает.

В интернетах находятся и другие how-to по данному вопросу. То, что выше — короткая выжимка из этого.

Хорошие курсы по криптографии

Почти все MOOC при всех их преимуществах грешат одним недостатком — низкий уровень (что напрямую следует из требуемой для рекламы университетов популярности). Тем не менее, на курсере встречаются и действительно хорошие курсы. Например, по шифрованию:
Cryptography I
Cryptography II

Нельзя сказать, что это курсы продвинутого уровня, однако, они понятным языком покрывают обширные и весьма непростые разделы криптографии. Симметричное, несимметричное шифрование, хеши, MAC, HMAC, алгоритмы обмена ключами (Diffie-Hellman), введение в TLS/IPSec и многое другое. Причем, не только фактологически, но с объяснением внутренних связей, причин-следствий. Совмещение теории с практикой в хорошем смысле.
В общем, кто занимается Computer Security, Computer Science эти курсы будут полезны.

ssh/scp под Windows

Несколько решена проблема с доступом ssh/scp из под Windows. Cофтина позволяет монтировать ssh как логический том (sshfs). С её помощью может получиться неплохое решение для удалённых бэкапов из Windows под любые никсы. Жаль, что пока нет решения под Windows 8 и серверную 2012.

Удаление очень больших директорий в Linux

Современные файловые системы вроде ext3/ext4, xfs позволяют создавать в директориях очень большое количество файлов. В ряде случаев (обычно по ошибке или недосмотру) это реализуется на практике и тогда некоторые операции с такой директорией становятся очень медленными. Это касается прежде всего операций, требующих сортировку списка содержимого директории. Такая сортировка, например, происходит при вызове листинга ls, который по умолчанию сортируется, что естественным образом приводит к очень медленному исполнению команды. Также, большая директория очень медленно удаляется rm, поскольку последний формирует листинг.

Чтобы ускорить (а иногда и просто осуществить) удаление большой директории нужно отключить сортировку. Команда rm при удалении берет полностью список файлов, поэтому удалять очень большую директорию «в лоб» с помощью «rm -rf» очень неоптимальный вариант. Большую директорию удобнее удалять частями: листингом без сортировки некоторого количества файлов и их удалением. Сортировка в ls отключается параметром -U, что приводит к такой команде частичного удаления

ls -UA -1 . | head -n 1000 | xargs rm -f

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

while [ true ]; do ls -UA -1 . | head -n 100 | xargs rm -f 2>/dev/null; sleep 1; done

Альтернативный способ — изменить ionice процесса удаления.

Быстрый способ посмотреть релиз Linux

Наипростейший способ посмотреть информацию о ядре Linux и некоторую информацию о системе это команда uname:

$ uname -a
  Linux sonne 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt2-1 (2014-12-08) x86_64 GNU/Linux

Более подробную информацию о системе можно насобирать в /etc. При этом краткая информация о релизе содержится в файле, который в разных дистрибутивах Linux называется по разному: lsb-release, redhat-release, os-release, centos-release, system-release. Поскольку файл везде оканчивается на -release, то можно не помнить всё это и получать информацию одной командой

cat /etc/*-release

Запуск крона чаще раза в минуту

Наибольшая частота, с которой cron запускается — 1 минута. При администровании серверов бывают ситуации, когда требуется более частый вызов, но конфиг crontab не позволяет этого сделать. Задача решается окольным способом, с помощью вызова нескольких инструкций и использования sleep. Например:

* * * * * /usr/bin/python /usr/local/bin/doit.py
* * * * * sleep 30; /usr/bin/python /usr/local/bin/doit.py

То же можно сделать и в одной строчке, если одну инструкцию исполнять за другой

* * * * * /usr/bin/python /usr/local/bin/doit.py; sleep 30; /usr/bin/python /usr/local/bin/doit.py

Также, можно контролировать возвращаемый инструкцией код и уменьшить количество исполнений в случае ошибки в скрипте. В этом случае точка с запятой меняется на &&.

Защита от DDoS при помощи geoip

Основная задача любой оптимизации состоит в минимизации частоты исполнения медленного кода. Применительно к администрированию web-серверов, медленно генерируемые страницы должны запрашиваться нечасто, или такие страницы необходимо сделать быстро генерируемыми. Для многих «простых» сайтов на известных CMS и обвешанными плагинами любая страница генерируется с использованием значительных ресурсов. Это играет злую шутку на большой мусорной нагрузке, например при умном, но узким DDoS: даже такой сможет обвалить сайт.
В случае, если DDoS идёт из определённых стран, например из Китая и Индии (что происходит в большинстве случаев), то появляется быстрое и эффективное решение для защиты региональных сайтов — фильтр входящих запросов по географии и ответ только на запросы с нужных стран. Тогда, «вредные» запросы не доходят до backend, медленный код не исполняется и ресурсы серверы не тратятся, в результате чего сервер для локальных запросов сервер не падает и обычно даже работает с незаметным замедлением.

Делается это правилом вроде

$IPTABLES -A HTTP -m geoip ! --src-cc RU -j DROP

Перед этим правилом определяется стандартным образом цепочка HTTP (-p tcp --dport 80).

Способ, естественно, не годится на случай широких DDoS, нацеленных на заполнение канала (особенно udp-траффиком). Но для слабых, основанных на генерировании нагрузки, DDoS, он вполне годится.

PS: Естественно geiop модули к iptables должны быть поставлены заранее. Тогда этот способ будет действительно быстрым.