Postfix настройка OpenDKIM

В этой записи я опишу процесс настройки OpenDKIM на Arch Linux. Следует отменить, этот этап настроек следует выполнять очень внимательно. Можно запутаться на этапе подготовки к генерации ключей. Поэтому я выделил эту задачу в отдельный пост.

Устанавливаем OpenDKIM и копируем базовый настройки файл:

pacman -S opendkim
install -d /etc/opendkim
cp /usr/share/doc/opendkim/opendkim.conf.sample /etc/opendkim/opendkim.conf

Далее уберите знак комментирования для перечисленных параметров /etc/opendkim/opendkim.conf. Приведите его состояние к следующему виду:

Mode                    sv
SendReports yes
KeyTable                refile:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
Socket                  local:/run/opendkim/opendkim.sock
UMask                   002

Автоперезапуск при падении opendkim:

mkdir -p /etc/systemd/system/opendkim.service.d
cat > /etc/systemd/system/opendkim.service.d/restart.conf <<'EOF'
[Service]
Restart=on-failure
RestartSec=5s

StartLimitIntervalSec=300
StartLimitBurst=5
EOF

Применяем настройки:

systemctl daemon-reload
systemctl restart opendkim

Убиваем процесс opendkim, что бы убедится что он подымится снова:

pkill -9 opendkim
sleep 2
systemctl status opendkim --no-pager

Создайте файл /etc/opendkim/SigningTable. Селектор можно выбрать любой, у меня - mail, домен - codebeer.ru меняете на ваш.

*@codebeer.ru mail._domainkey.codebeer.ru

Создайте файл /etc/opendkim/KeyTable

mail._domainkey.codebeer.ru  codebeer.ru:mail:/etc/opendkim/keys/codebeer.ru/mail.private

Аналогично селектор указываете такой же, как в предыдущем пункте, у меня mail, домен codebeer.ru, вы меняете значения на свои.

Создайте файл /etc/opendkim/TrustedHosts

127.0.0.1
::1
localhost
.codebeer.ru

Домен codebeer.ru меняете на ваш.

Далее генерируем ключи.

pacman -S perl
mkdir -p /etc/opendkim/keys/codebeer.ru
opendkim-genkey -b 2048 -d codebeer.ru -D /etc/opendkim/keys/codebeer.ru -s mail -v

Назначаем права на файлы:

chown -R opendkim:opendkim /etc/opendkim/keys/codebeer.ru
chmod 0400 /etc/opendkim/keys/codebeer.ru/mail.private

Добавляем в DNS TXT запись с именем mail._domainkey и значением:

cat /etc/opendkim/keys/codebeer.ru/mail.txt

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

"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuxfSSuNL66k9K7d/maqp39cMANuqlHthD+4w7F9ck0NOFbKoYwJxFL7XiZi2tQPM/8HdITuKPG/a9n2qiLtTWzKzv5bsoY4bnjkCzycRcV/uK8XrfZg6yni3UmaFuN10q6bJVZ77ePRIjqQGiHUrgTqTiS6X/EmxiMmPNUf5BQhDKw/N3rdf2gm8suVVP1je+YZrVqdnXesyEJl3SqBuIGZrp8x9BD5abkF4069BsSOm5OqLsr6Eioc/7zWTETraNcGbPROtNKQenEEmWnPpGFYgxtxcagSadm05vjVtKUIukGABot2UleLVsZDwiFGfnSmStvWXQmFWlu1Rtne9cwIDAQAB"

Тест ключа:

[root@mx opendkim]# opendkim-testkey -d codebeer.ru -s mail -vvv
opendkim-testkey: using default configfile /etc/opendkim/opendkim.conf
opendkim-testkey: checking key 'mail._domainkey.codebeer.ru'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Подключаем Postfix к OpenDKIM

Редактируем файл /etc/postfix/main.cf, нужно добавить в конец файла:

milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:/run/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Установите права на сокет, для этого добавьте postfix в группу opendkim:

gpasswd -a postfix opendkim

Добавляем OpenDKIM в автозагрузку и перезапускаем Postfix:

sudo systemctl enable --now opendkim
sudo systemctl restart postfix

Postfix настройка TLS шифрования

Продолжаем настройку нашего почтового сервера. Далее нам понадобится настроить автоматический выпуск сертификатов Let’s Encrypt. Для этого установим необходимые пакеты:

pacman -Syu certbot certbot-nginx nginx

Далее необходимо создать конфигурационный файл Nginx. Создадим каталог для конфигов Nginx:

mkdir -p /etc/nginx/conf.d

Далее необходимо добавить include в nginx.conf

nano /etc/nginx/nginx.conf

Внутри блока http { ... } в конце файла добавь строку:

include conf.d/*.conf;
cat > /etc/nginx/conf.d/mx.codebeer.ru.conf <<'EOF'
server {
      listen 80;
      listen [::]:80;
      server_name mx.codebeer.ru;

      root /var/lib/letsencrypt;

      location ~ /.well-known/acme-challenge {
         allow all;
      }
}
EOF

Применить настойки:

systemctl enable nginx
systemctl daemon-reload
systemctl restart nginx

Убьём процесс nginx, systemd должен поднять снова:

pkill -9 nginx
sleep 2
systemctl status nginx --no-pager

Применяем настройки Nginx:

nginx -t && systemctl restart nginx

Далее выпускаем сертификат для нашего домена:

# certbot --nginx -d mx.codebeer.ru

Сертификат и ключ будет хранится по указанному пути:

/etc/letsencrypt/live/mx.codebeer.ru/fullchain.pem
/etc/letsencrypt/live/mx.codebeer.ru/privkey.pem

Дале включаем автоматический перевыпуск сертификата:

systemctl enable --now certbot-renew.timer
systemctl status certbot-renew.timer --no-pager
systemctl list-timers | grep certbot

После этого systemd будет запускать обновление сертификата по расписанию.

Включаем автоперезапуск nginx при падении

mkdir -p /etc/systemd/system/nginx.service.d
cat > /etc/systemd/system/nginx.service.d/restart.conf <<'EOF'
[Service]
Restart=on-failure
RestartSec=3s

StartLimitIntervalSec=300
StartLimitBurst=5
EOF

Включаем submission порт 587 и smtps порт 465 в Postfix

Нужно внести изменения в master.cf

nano /etc/postfix/master.cf

Добавить в файл:

submission     inet     n    -    y    -    -    smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_tls_wrappermode=no
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth

Прописываем TLS сертификат для Postfix:

postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/mx.codebeer.ru/fullchain.pem"
postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/mx.codebeer.ru/privkey.pem"

Чтобы отключить небезопасные версии SSL/TLS, добавьте в конец файла /etc/postfix/main.cf:

smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

Далее отключим авторизацию для порта 25. Это нужно что бы подключаться к серверу можно было только через порты с шифрованием.

smtpd_sasl_auth_enable = no
smtpd_tls_auth_only = yes

Применяем настройки:

postfix reload
systemctl restart postfix

Следующий этап настройки Postfix настройка OpenDKIM

Настройка Postfix на Arch Linux

Последнее время, мне приглянулся дистрибутив Arch Linux. Вообще я симпатизирую «rolling release» философии — поддержка постоянного актуального состояния системы. Я пока не проверил на практике, насколько стабильно работает Arch Linux, но в целом идея замечательная. Сервера я использую в рабочих целях, поэтому, необходимо обеспечить стабильную работу системы. Проблема в том, что установка обновлений, есть угроза что-то сломать. Для компенсации этого недостатка, я намерен компенсировать регулярными бэкапами, что которые и так у меня регулярно выполняются. Сейчас я использую Alma Linux. Но мне надоели форки RHEL, поэтому, возникла задача на практике пощупать Arch Linux и понять, насколько эта система подходит мне для рабочей среды.

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

IPv4 у меня настроен на этапе установки Arch Linux, поэтому, мне останется только прописать настройки IPv6. На этом этапе я остановлюсь более подробно. В моем случае IPv6 адрес 2001:41d0:11c:c700::/56, а шлюз fe80:0000:0000:0000:0000:0000:0000:0001. В сокращенном виде шлюз fe80::1, его я и буду использовать далее.

Настройка IPv6

Сейчас нам необходимо прописать IPv6 на уровне настроек сети. У меня настройки хранятся в файле 20-ens18.network, имя конфига может отличаться от вашего.

nano /etc/systemd/network/20-ens18.network

В секцию [Network] нужно добавить IPv6 адрес и параметр IPv6AcceptRA=no

[Network]
Address=2001:41d0:11c:c700::777/64
IPv6AcceptRA=no

Далее ниже еще одну дублирующую секцию [Route]

[Route]
Gateway=fe80::1
GatewayOnLink=yes

В итоге конфиг стал выглядеть следующим образом:

[Match]
Name=ens18

[Network]
Address=51.51.5.15/32
Gateway=100.64.0.1
DNS=1.1.1.1
DNS=8.8.8.8

Address=2001:41d0:11c:c700::777/64
IPv6AcceptRA=no

[Route]
Gateway=100.64.0.1
GatewayOnLink=yes

[Route]
Gateway=fe80::1
GatewayOnLink=yes

Сохраняем файл и применяем настройки командой:

systemctl restart systemd-networkd

Далее набор команд для проверки, что IPv6 поднялся:

# ip -6 addr show dev ens18
2: ens18:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    altname enp0s18
    altname enx020000772c58
    inet6 2001:41d0:11c:c700::777/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::ff:fe77:2c58/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever


# ip -6 route
2001:41d0:11c:c700::/64 dev ens18 proto kernel metric 256 pref medium
fe80::/64 dev ens18 proto kernel metric 256 pref medium
default via fe80::1 dev ens18 proto static metric 1024 onlink pref medium

# ping -6 -c 3 2001:4860:4860::8888
PING 2001:4860:4860::8888 (2001:4860:4860::8888) 56 data bytes
64 bytes from 2001:4860:4860::8888: icmp_seq=1 ttl=112 time=4.73 ms
64 bytes from 2001:4860:4860::8888: icmp_seq=2 ttl=112 time=4.50 ms
^C
--- 2001:4860:4860::8888 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 4.496/4.612/4.728/0.116 ms
# ping -6 -c 3 2001:4860:4860::8888
PING 2001:4860:4860::8888 (2001:4860:4860::8888) 56 data bytes
64 bytes from 2001:4860:4860::8888: icmp_seq=1 ttl=112 time=4.52 ms
64 bytes from 2001:4860:4860::8888: icmp_seq=2 ttl=112 time=4.52 ms
64 bytes from 2001:4860:4860::8888: icmp_seq=3 ttl=112 time=4.52 ms

--- 2001:4860:4860::8888 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 4.515/4.519/4.522/0.003 ms

Как вы можете видеть из вывода, сеть поднялась, IPv6 работает.

Мы настраиваем почтовый сервер, поэтому нам необходимо прописать AAAA запись в DNS для нашего IPv6 адреса. В моем случае это mx.codebeer.ru. И далее проверимь досутпность нашего IPv6 по домену mx.codebeer.ru из сети. Для этого можно использовать сервис https://dnschecker.org/ping-ipv6.php

Настройка DNS записей

Нужно создать A и MX записи для нашего почтового домена. Я не буду подробно описывать этот процесс.

Далее вторая по важности это прописать SPF запись:

"v=spf1 mx ~all"

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

Как создать записи DKIM и DMARC, я расскажу в следующей статье.

Установка Postfix

Устанавливаем Postfix, включаем автозапуск, проверяем статус:

pacman -Syu postfix
systemctl enable --now postfix
systemctl status postfix --no-pager

Убедимся, что имя хоста соотвествует нашему почтовому домену:

# cat /etc/hostname
mx.codebeer.ru

Приводим /etc/hosts к следующему виду:

127.0.0.1   localhost
::1         localhost
51.51.5.15 mx.codebeer.ru mx

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

postconf -e "inet_interfaces = all"
postconf -e "myhostname = mx.codebeer.ru"
postconf -e "mydomain = codebeer.ru"
postconf -e "myorigin = \$mydomain"
postconf -e "mydestination = \$myhostname, localhost.\$mydomain, localhost, \$mydomain"
postconf -e "mynetworks = 127.0.0.0/8 [::1]/128"
postconf -e "home_mailbox = Maildir/"
postconf -e "smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
postconf -e "message_size_limit = 36700160"
postconf -e "mailbox_size_limit = 0"

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

# ls -l /etc/postfix/aliases*
-rw-r--r-- 1 root root 11516 Dec  7 15:08 /etc/postfix/aliases
-rw-r--r-- 1 root root 20480 Feb  2 14:29 /etc/postfix/aliases.lmdb

Если нужно что бы Postfix работал только через IPv4 протокол, нужно отредактировать параметр в файле /etc/postfix/main.cf

inet_protocols = ipv4

Применяем настройки Postfix:

systemctl restart postfix

Проверка, что Postfix слушает 25 порт:

# ss -lntp | grep ':25'
LISTEN 0      0            0.0.0.0:25        0.0.0.0:*    users:(("smtpd",pid=4713,fd=6),("master",pid=4428,fd=13))

Отправляем тестовое письмо на свою почту. Адрес в конце команды нужно поменять на свой.

echo "Test from mx.codebeer.ru" | sendmail -v [email protected]

Включить автоматический запуск Postfix в случае падения

Необходимо создать drop-in файл :

mkdir -p /etc/systemd/system/postfix.service.d
cat > /etc/systemd/system/postfix.service.d/restart.conf <<'EOF'
[Service]
Restart=on-failure
RestartSec=5s

StartLimitIntervalSec=300
StartLimitBurst=5
EOF

Применяем настройки:

systemctl daemon-reload
systemctl restart postfix

Проверяем работает ли автоматическое поднятие сервиса:

pkill -9 master
sleep 2
systemctl status postfix --no-pager

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

journalctl -u postfix -n 200 --no-pager

Следующий этап настройки Postfix настройка TLS шифрования

Включаем поддержку Brotli в Nginx

Этот алгоритм сжатия появился совсем недавно, связи с чем о использовании Brotli еще мало упоминаний в сети. Для начала необходимо упомянуть о том, что этот Brotli из себя представляет. Если кратко, Brotli — алгоритм сжатия данных основанный на современном варианте алгоритма LZ77. Brotli был разработан и представлен компанией Google в 2015 году как специализированный алгоритм для сжатия веб-шрифтов. В дальнейшем была представлена версия Brotli, которая содержала улучшения направленные на сжатие всего интернет-трафика (HTML, CSS, JS).

Сейчас момент Brotli используют для ускорения загрузки веб-страниц, его поддержка включена по умолчанию в Chrome 51+, Firefox 47+ и мобильным Chrome. По сравнению с gzip, алгоритм Brotli показывает сравнимую скорость, но при этом имеет лучшие показатели сжатия данных. Следует отметить, что Brotli несовместим с gzip и работает только для HTTPS-ресурсов.

На данный момент нет официального модуля для поддержки Brotli в Nginx. Зато мы имеем возможность использовать сторонние модули, которые параллельно развиваются Google и Cloudflare. В данном посте я расскажу о сборке Nginx с включенным модулем Brotli от Cloudflare. Если интересно, то исчерпывающую информацию по работе алгоритма Brotli можно найти в блоге Cloudflare.

Процесс аналогичен сборке Nginx с любыми другими модулями. Для начала необходимо скачать исходники Nginx. Добавим в файл /etc/apt/sources.list официальный репозиторий для mainline-ветки Nginx:

deb http://nginx.org/packages/mainline/debian/ codename nginx
deb-src http://nginx.org/packages/mainline/debian/ codename nginx

Скачиваем и устанавливаем PGP-ключ, после чего не забудьте обновить индекс пакетов apt:

cd /tmp/ && wget http://nginx.org/keys/nginx_signing.key && apt-key add nginx_signing.key
apt-get update

Устанавливаем пакет dpkg-dev и все необходимые для сборки Nginx зависимости:

apt-get install dpkg-dev
apt-get build-dep nginx
apt-get build-dep git autoconf libtool

Скачиваем исходники Nginx:

cd /usr/src
apt-get source nginx

Получаем код модуля ngx_brotli_module:

git clone https://github.com/cloudflare/ngx_brotli_module.git

В каталог с модулем ngx_brotli_module необходимо загрузит исходники библиотеки libbrotli:

cd /usr/src/ngx_brotli_module
git clone https://github.com/google/brotli.git

Перед началом сборки и компиляции необходимо внести изменения в конфигурационный файл:

nano /usr/src/nginx-1.11.5/debian/rules

Необходимо добавить путь к исходникам ngx_brotli_module в содержимое переменно CFLAGS:

config.status.nginx: config.env.nginx
        cd $(BUILDDIR_nginx) && \
        CFLAGS="" ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=/usr/src/ngx_brotli_module --with-cc-opt="$(CFLAGS)" --with-ld-opt="$(LDFLAGS)"
        touch $@

Дополнительно рекомендую собрать Nginx c поддержкой APLN. Переходим к компиляции и сборке deb-пакета Nginx:

cd /usr/src/nginx-1.11.5
dpkg-buildpackage -rfakeroot -uc -b

Если в процессе не было ошибок, то в рабочем каталоге мы увидим собранные deb-пакета Nginx.

Для активации режима сжатия Brotli указываем следующие параметры:

brotli on;
# уровень компрессии от 1 до 11
brotli_comp_level 6;
# минимальный размер файла для использования сжатия
brotli_min_length Num;

Когда Brotli включен, он получает приоритет наl gzip, если браузер не поддерживает Brotli, данные сжимаются при помощи gzip. Теперь остается только проверить поддерживает ли наш сайт сжатие Brotli с помощью онлайн сервиса Brotli Test.

Очистить журнал systemd

Дата: 10.11.2016Метки:

На сегодняшний день systemd стал де-факто стандартом для современных Linux-систем. Его компонент journal cобирает все системные сообщения: сообщения ядра, служб и приложений. После чего происходит их запись в виде бинарных файлов. Для просмотра и управления файлами логов используется утилита journalctl.

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

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

journalctl --disk-usage

Что бы ограничить бесконтрольное хранение журнала, нам необходимо выполнить настройку ротации логов. С помощью опций −−vacuum-size и −−vacuum-time мы можем соответственно установить предельно допустимый размер и срок хранения для хранимых на диске логов.

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

journalctl --vacuum-size=1G

Подобным образом образом работает опция −−vacuum-time. Команда установит для логов срок хранения, по истечении которого они будут удалены автоматически:

journalctl --vacuum-time=1years

Дополнительно нужно прописать настройки ротации логов в конфигурационный файл:

vi /etc/systemd/journald.conf

Настройки ротации логов включают следующие параметры:

# Максимальный объём логов на диске
SystemMaxUse=
# Объём свободного места на диске после сохранения логов
SystemKeepFree=
# Объём файла лога, по достижении которого он должен быть удален
SystemMaxFileSize=
# Максимальный объём, который логи могут занимать в /run
RuntimeMaxUse=
# Объём свободного места, которое должно оставаться в /run после сохранения логов
RuntimeKeepFree=
# Объём файла лога, по достижении которого он должен быть удален из /run.
RuntimeMaxFileSize=

Применяем настройки без перезапуска системы:

systemctl restart systemd-journald

Автоматическая установка Debian

Установку Debian можно полностью автоматизировать путем использования специального файла с заранее указанным сценарием ответов на все вопросы инсталлятора. Данный способ автоматической установки называется Debian Preseed. Далее созданный файл-сценарий ответов preseed.cfg запаковывается в initrd установочного iso-образа Debian.

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

В файле сценариев для своих нужд я использовал такие переменные параметры, как: ($IP), ($NETMASK), ($GATEWAY). Ниже привожу пример моего файла сценария Debian Preseed. Внимание! Особенно обратите внимание на блок ### Partitioning, вначале которого я полностью забиваю нулями содержимое диска. Данные будут полностью стерты со всех дисков в системе, будьте крайне осторожны.

### Localization
d-i debian-installer/locale string en_US
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us

### Network configuration
d-i netcfg/choose_interface select auto
d-i netcfg/disable_autoconfig boolean true
# IPv4
d-i netcfg/get_ipaddress string ($IP)
d-i netcfg/get_netmask string ($NETMASK)
d-i netcfg/get_gateway string ($GATEWAY)
d-i netcfg/get_nameservers string ($NAMESERVER)
d-i netcfg/confirm_static boolean true
# Hostname
d-i netcfg/get_hostname string ($HOSTNAME)

### Mirrors
d-i mirror/country string manual
d-i mirror/http/hostname string ($MIRROR)
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string ($HTTPPROXYv4)
d-i mirror/suite string stable

### Account setup
d-i passwd/root-login boolean true
d-i passwd/make-user boolean false
d-i passwd/root-password-crypted password ($PASS_CRYPT)
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false

### Clock
d-i clock-setup/utc boolean true
d-i time/zone string ($TIMEZONE)
d-i clock-setup/ntp boolean false

### Partitioning
d-i partman/early_command string \
for DISK in $(list-devices disk); do \
    parted -s ${DISK} mklabel gpt; \
    parted -s ${DISK} mklabel msdos; \
        dd if=/dev/zero of=${DISK} bs=512 count=1; \
done;

d-i partman-auto/method string regular
d-i partman-basicfilesystems/no_swap boolean false
d-i partman-auto/expert_recipe string                         \
      root ::                                                 \
              5000 5000 -1 ext4                               \
                      method{ format } format{ }              \
                      use_filesystem{ } filesystem{ ext4 }    \
                      mountpoint{ / }                         \
              .                                               \
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman/mount_style select uuid

### Apt setup
d-i apt-setup/contrib boolean true
d-i apt-setup/services-select multiselect security, volatile
tasksel tasksel/first multiselect minimal
d-i pkgsel/include string openssh-server
popularity-contest popularity-contest/participate boolean false

### Grub
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i grub-installer/bootdev string default

### Finish install
d-i finish-install/keep-consoles boolean true
d-i finish-install/reboot_in_progress note

d-i preseed/late_command string \
        sed -i '/^PermitRootLogin/c PermitRootLogin yes' /target/etc/ssh/sshd_config ;\
        if [ -n "($SSHPUBKEYS)" ]; then \
                mkdir -p /target/root/.ssh ;\
                chmod 700 /target/root/.ssh ;\
                echo "($SSHPUBKEYS)" > /target/tmp/keyfile ;\
                cat /target/tmp/keyfile | /target/usr/bin/base64 -d > /target/root/.ssh/authorized_keys ;\
                in-target rm -f /tmp/keyfile ;\
        fi ;\
        sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT/c GRUB_CMDLINE_LINUX_DEFAULT="quiet"' /target/etc/default/grub ;\
        sed -i '/^GRUB_TIMEOUT/c GRUB_TIMEOUT=0' /target/etc/default/grub && in-target update-grub

Сборка rpm пакета Nginx в Centos 7

На данный момент в официальном репозитории Nginx размещены пакеты без поддержки технологии APLN. Возможно, вы успели заметить, что в актуальной версии Chrome ваши сайты перестали работать по протоколу HTTP/2. Связано это с тем, что для сборки Nginx используется старая версия OpenSSL. Хочешь HTTP/2, значит придется собирать Nginx из исходников вручную.

Основной недостаток установки программ при помощи make install — это неудобное управление. Вместо этого мы рассмотрим сборку rpm пакетов из исходников. Все действия я буду производить в дистрибутиве CentOS 7, а в качестве примера буду использовать Nginx 1.11.3.

Устанавливаем все необходимое для сборки и компиляции:

yum groupinstall -y "Development Tools" && yum install rpmdevtools nano yum-utils

Собирать пакеты можно из-под любого пользователя, но делать это из-под root не рекомендуется. Создадим для сборки пакета пользователя builder:

useradd builder
usermod -a -G builder builder

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

rpmdev-setuptree

Для настройки репозитория yum необходимо создать файл:

nano /etc/yum.repos.d/nginx.repo

Копируем в файл следующие строки:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

[nginx-source]
name=nginx source repo
baseurl=http://nginx.org/packages/mainline/centos/7/SRPMS/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Загружаем пакет с исходниками и запускаем установку rmp:

cd /tmp
yumdownloader --source nginx
rpm -Uvh nginx*.src.rpm

Установим все необходимые для сборки Nginx зависимости:

yum-builddep nginx

Скачиваем и распаковываем исходники OpenSSL:

cd /usr/src/
wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz
tar -xvzf openssl-1.0.2h.tar.gz

В параметрах сборки необходимо указать путь к исходникам OpenSSL:

nano ~/rpmbuild/SPECS/nginx.spec

Для примера привожу фрагмент моего файла:

--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-ipv6 \
--with-openssl=/usr/src/openssl-1.0.2h \

Запускаем сборку пакета:

cd ~/rpmbuild/SPECS/
rpmbuild -ba nginx.spec

После завершения сборки переносим rpm из папки:

cd ~/rpmbuild/RPM/
ls
nginx-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-debuginfo-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-geoip-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-image-filter-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-njs-1.11.3.0.1.0-1.el7.centos.ngx.x86_64.rpm
nginx-module-perl-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-xslt-1.11.3-1.el7.centos.ngx.x86_64.rpm

И запускаем установку командой:

rpm -Uvh nginx*.rpm

Failed to execute ban jail ‘sshd’ action ‘iptables-multiport’

Связи с тем, что для выхода в интернет я использую статический IP, мне достаточно редко приходится использовать fail2ban на своих серверах. Я предпочитаю просто закрыть доступ к SSH в iptables. После настройки VMmanager, был автоматически установлен пакет fail2ban. После чего в логах стали регулярно появляться ошибки следующего содержания:

2016-08-13 05:43:23,463 fail2ban.actions        [1011]: NOTICE  [sshd] Ban 91.224.160.106
2016-08-13 05:43:23,565 fail2ban.action         [1011]: ERROR   iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]' -- stdout: ''
2016-08-13 05:43:23,565 fail2ban.action         [1011]: ERROR   iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]' -- stderr: ''
2016-08-13 05:43:23,565 fail2ban.action         [1011]: ERROR   iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]' -- returned 1
2016-08-13 05:43:23,565 fail2ban.CommandAction  [1011]: ERROR   Invariant check failed. Trying to restore a sane environment
2016-08-13 05:43:23,667 fail2ban.action         [1011]: ERROR   iptables -w -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd
iptables -w -F f2b-sshd
iptables -w -X f2b-sshd -- stdout: ''
2016-08-13 05:43:23,667 fail2ban.action         [1011]: ERROR   iptables -w -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd
iptables -w -F f2b-sshd
iptables -w -X f2b-sshd -- stderr: "iptables v1.4.21: Couldn't load target `f2b-sshd':No such file or directory\n\nTry `iptables -h' or 'iptables --help' for more information.\niptables: No chain/target/match by that name.\niptables: No chain/target/match by that name.\n"
2016-08-13 05:43:23,667 fail2ban.action         [1011]: ERROR   iptables -w -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd
iptables -w -F f2b-sshd
iptables -w -X f2b-sshd -- returned 1
2016-08-13 05:43:23,667 fail2ban.actions        [1011]: ERROR   Failed to execute ban jail 'sshd' action 'iptables-multiport' info 'CallingMap({'ipjailmatches':  at 0x182b050>, 'matches': u'2016-08-13T05:43:07.237432 skvm1.powervps.ru sshd[850]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:09.504130 skvm1.powervps.ru sshd[852]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:11.811482 skvm1.powervps.ru sshd[856]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:14.043115 skvm1.powervps.ru sshd[858]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:22.962543 skvm1.powervps.ru sshd[878]: Invalid user support from 91.224.160.106', 'ip': '91.224.160.106', 'ipmatches':  at 0x181ded8>, 'ipfailures':  at 0x182b0c8>, 'time': 1471056203.463139, 'failures': 5, 'ipjailfailures':  at 0x182b140>})': Error stopping action

Сначала я грешил на использования ключа iptables -w в добавляемых правилах.

nano /etc/fail2ban/action.d/iptables-common.conf

В конце файла вы увидите параметр lockingopt и комментарий к нему:

# Option:  lockingopt
# Notes.:  Option was introduced to iptables to prevent multiple instances from
#          running concurrently and causing irratic behavior.  -w was introduced
#          in iptables 1.4.20, so might be absent on older systems
#          See https://github.com/fail2ban/fail2ban/issues/1122
# Values:  STRING
lockingopt = -w

Тогда я решил проверить версию установленного пакета:

# iptables --version
iptables v1.4.21

Но причина была не в этом. После продолжительного гугления, проблема оказалась связана с конфигом jail.local, в который вносит изменения VMmanager в процессе установки. Чтобы починить fail2ban, откройте файл:

nano /etc/fail2ban/jail.local

Закомментируйте содержимое файла, и добавьте строки как в примере ниже:

# ISPsystem start
#[sshd]
#maxretry = 5
#enabled = true
# ISPsystem end

[DEFAULT]
bantime = 3600
banaction = iptables-multiport

[sshd]
maxretry = 5
enabled = true

После перезапуска fail2ban, с довольным видом любуемся на результат:

2016-08-14 10:36:01,828 fail2ban.jail           [23203]: INFO    Jail 'sshd' started
2016-08-14 10:36:01,947 fail2ban.actions        [23203]: NOTICE  [sshd] Ban 78.47.79.193

Failed to get D-Bus connection: Connection refused

Дата: 02.08.2016Метки:

С данной проблемой столкнулся в Debian 8, когда мне понадобилось создать новый сервис для запуска rtorrent в режиме демона. При попытке запуска нового сервиса я получил ошибку:

$ systemctl --user enable rtorrent
Failed to get D-Bus connection: Connection refused

Как оказалась проблема кроется зависимостях для systemd:

$ apt-cache depends systemd
systemd
  Depends: libacl1
  Depends: libaudit1
  Depends: libblkid1
  Depends: libcap2
  Depends: libcryptsetup4
  Depends: libkmod2
  Depends: libpam0g
  Depends: libselinux1
  Depends: libsystemd0
  Depends: util-linux
  Depends: mount
  Depends: initscripts
  Depends: sysv-rc
    openrc
  Depends: udev
  Depends: acl
  Depends: adduser
  Depends: libcap2-bin
  PreDepends: libc6
  PreDepends: libgcrypt20
  PreDepends: liblzma5
  PreDepends: libselinux1
  Suggests: systemd-ui
  Recommends: libpam-systemd
  Recommends: dbus
  Conflicts: 
  Breaks: lsb-base
  Breaks: lvm2
  Breaks: systemd-shim

Из рекомендованных зависимостей для systemd в Debian 8 был установлен только пакет dbus. Выполните установку пакета libpam-systemd, после чего необходимо перезагрузить систему. После чего проблема с запуском systemd должна быть решена.

Создаем ECDSA сертификаты Let’s Encrypt

Дата: 21.07.2016

Как показывает практика, использование ECDSA сертификатов позволяет добиться примерно в два раз большего количества соединений на одной аппаратной платформе. К недостаткам использования ECDSA сертификатов следует отнести проблему с поддержкой браузерами. Но данная проблема легко решается если мы будем использовать ECDSA и RSA сертификаты одновременно.

Перед тем как начать проверьте, что в системе установлен git, в противном случае необходимо запустить установку командой:

apt-get install git

Выберите каталог, в который будут загружены файлы клиента Let’s Encrypt. В этой статье я буду использовать каталог /usr/local. Переходим в указанный каталог, а затем загружаем и запускаем клиент Let’s Encrypt:

cd /usr/local
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help

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

mkdir -p /usr/local/letsencrypt/live-ecdsa/codebeer.ru/letmp

Перед тем как создать файл ключа, важно правильно выбрать тип кривой. Большинство современных браузеров поддерживает кривые secp256r1, secp384r1, secp521r1. Я буду использовать 256-битная кривую prime256v1, которая по современным меркам обеспечивает достаточной секретности. Список кривых OpenSSL можно вывести командой:

openssl ecparam -list_curves

Создаем приватный ключ:

cd /usr/local/letsencrypt/live-ecdsa/codebeer.ru
openssl ecparam -genkey -name secp256r1 > key-256r1.pem

Теперь создаем свой CSR:

openssl req -new -sha256 -key key-256r1.pem -subj "/CN=codebeer.ru" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:codebeer.ru,DNS:www.codebeer.ru")) -outform der -out csr-256r1.der

Переходим в каталог letmp и создаем ECDSA Let’s Encrypt сертификат:

cd letmp
/usr/local/letsencrypt/letsencrypt-auto certonly -a webroot --email [email protected] --webroot-path /www/codebeer.ru/ --csr /usr/local/letsencrypt/live-ecdsa/codebeer.ru/csr-256r1.der --renew-by-default --agree-tos

Если вы используете веб-сервер Nginx, то во время создания сертификата клиент Let’s Encrypt вы можете получить такую ошибку:

 Failed authorization procedure. www.codebeer.ru (http-01): urn:acme:error:unauth orized :: The client lacks sufficient authorization :: Invalid response from htt p://www.codebeer.ru/.well-known/acme-challenge/oVRUfF1DISR8zRpq1Vju4C7XrYm2YULSe 5TVRfmGy64: "<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>", codebeer.ru (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://codebeer.ru/.well -known/acme-challenge/yKovcd-Eemc6ezWUWNKiL3MKgs6htk06lfuQmYeBwdA: "<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>"

IMPORTANT NOTES:
 - The following errors were reported by the server:

 Domain: www.codebeer.ru
 Type: unauthorized
 Detail: Invalid response from
 http://www.codebeer.ru/.well-known/acme-challenge/oVRUfF1DISR8zRpq1Vju4C7XrYm 2YULSe5TVRfmGy64:
 "<html>
 <head><title>403 Forbidden</title></head>
 <body bgcolor="white">
 <center><h1>403 Forbidden</h1></center>
 <hr><center>"

 Domain: codebeer.ru
 Type: unauthorized
 Detail: Invalid response from
 http://codebeer.ru/.well-known/acme-challenge/yKovcd-Eemc6ezWUWNKiL3MKgs6htk0 6lfuQmYeBwdA:
 "<html>
 <head><title>403 Forbidden</title></head>
 <body bgcolor="white">
 <center><h1>403 Forbidden</h1></center>
 <hr><center>"

 To fix these errors, please make sure that your domain name was
 entered correctly and the DNS A record(s) for that domain
 contain(s) the right IP address.

В этом случае вам нужно добавить в конфиг виртуального следующие строки:

location ~ /.well-known {
    allow all;
}

Если все прошло успешно, в каталоге letmp появятся следующие файлы:

0000_cert.pem  0000_chain.pem  0001_chain.pem

Копируем их содержимое в один файл:

cat 0001* > /usr/local/letsencrypt/live-ecdsa/codebeer.ru/chain.pem

Теперь необходимо указать путь к сертификату и ключу в конфиге nginx:

ssl_certificate /usr/local/letsencrypt/live-ecdsa/codebeer.ru/chain.pem;
ssl_certificate_key /usr/local/letsencrypt/live-ecdsa/codebeer.ru/key-256r1.pem;