Отключение обновлений Windows 10

Беда современных ОС от MS в том, что они считают себя умнее пользователя и обновляются когда это совсем не вовремя. И дело не только в том, что обновления не всегда полезны, а прежде всего это прерывает рабочий процесс. Оставил ПК на ночь с запущенными задачами, а он за ночь взял и сам перезагрузился. И на утро НИЧЕГО не осталось.

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

Идём более длинным путём. Качаем PsExec, распаковываем и запускаем через cmd с правами администратора. Далее запускаем Планировщик:

psexec -i -s "C:\Windows\system32\mmc.exe" "C:\Windows\system32\taskschd.msc" /s

Далее отключаем неугодные задания из Microsoft\Windows\UpdateOrchestrator.

Всё. С внезапными обновлениями и перезагрузками покончено.

Запуск nodejs через systemd

Приложения nodejs собираются обычно на коленке и для них нет стандартного способа запуска как демон. Наиболее короткий и корректный способ сделать это сейчас — через systemd. Для этого создаем свежий конфиг в /etc/systemd/system/, называем по имени приложения, например /etc/systemd/system/myapp.service с содержимым:

[Service]
WorkingDirectory=/opt/myapp/
ExecStart=/usr/bin/node /opt/myapp/app.js
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=myapp
User=igogoo
Group=igogoo
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Обычно в /etc кладутся не сами конфиги, а симлинки на действительные конфиги в /lib/systemd/system/, но поскольку наш демон кастомный, а директория /etc бэкапится полностью, создадим его прямо здесь.
Далее релодим конфигурацию и включаем демона на автостарт

systemctl daemon-reload
systemctl enable node-app.service

Теперь возможны стандартные операции вроде

systemctl start myapp
systemctl stop myapp
systemctl restart myapp
systemctl status node-app.service

Перезапускаем виртуалку, проверяем, что всё работает. Готово.

Исправление графиков munin

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

Графики munin хранит в rrd-формате в /var/lib/munin. Чтобы исправить заходим туда и конвертируем rrd в xml:

cd /var/lib/munin/localdomain
cp x.xml x.xml.bak
rrdtool dump x.rrd > x.xml

Открываем получившийся xml, удаляем оттуда ненужное и конвертируем обратно:

rrdtool restore x.xml > x.rrd

Обновление с небезопасного репозитария

Иногда нужно поставить какой-нибудь старый или просто сторонний софт с «левых» репозитариев. Для этого apt настойчиво требует добавить в систему открытые части ключей для сверки подписей, что делать не всегда нецелесообразно. Но в последних версиях дебиановцы очень «позаботились» о пользователях и просто не позволяют качать софт и даже вообще получать его списки с левых репозитариев, что уже совсем негоже. Да, небезопасно. Да, в общем случае не правильно. Но не разрабам дистра решать как действовать в той или иной ситуации. К сожалению, приходиться обходить это отмычкой, невольно вспоминая что-то похожее в Windows стародавних версий.

Отмычка такая. Добавляем кастомный конфиг /etc/apt/apt.conf.d/99custom такого содержания:

Acquire::Check-Valid-Until "false";
Acquire::AllowInsecureRepositories "true";
Acquire::AllowDowngradeToInsecureRepositories "true";

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

Дебиановские установочные образы non-free firmware

Иногда возникает необходимость скачать несвежий устанвщик дебиана с версией несвободных пакетов. Свежий постоянно располагается по ссылке:
https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/current/amd64/iso-cd/

А «несвежий» можно загрузить по ссылке из из архива:
https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/archive/

Изменение PATH в Debian buster

В дистрибутиве Buster зачем-то подчистили переменную PATH от важных и полезных путей, в частности /usr/sbin. В итоге полезные и весьма нередко используемые команды вроде dpkg-reconfigure, fdisk, blkid и многие другие стали недоступны без указания точного пути. Интерпретатор пишет command not found и усё на этом.

Возвращаем к обратному добавлением в .bashrc:

export PATH=$PATH:/usr/sbin

После следующего логина всё работает

SSLError: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocol

В новом дебиане при попытке законнектиться к очень старым сайтам из питона (и не только) периодически вылезает ошибка «SSLError: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocol». Вылезает она из-за отсутствия поддержки более-менее современных протоколов серверами с теми сайтами. Работать с этими сайтами надо, а повлиять никак, поэтому единственный доступный выход — это обойти ограничение. На глобальном уровне это делается правкой секции в /etc/ssl/openssl.cnf:

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=1

на

[system_default_sect]
MinProtocol = None
CipherString = DEFAULT

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

Обновление с репозитария без подписи

Начиная примерно с дистрибутива buster стандартный установщик дебиана apt-get требует подписи всех используемых репозитариев. Обычный способ использования репозитария — добавление его подписи в систему. Это, однако, не всегда удобно и целесообразно. Иногда нужно что-то взять из сторонних репозитариев не добавляя подписи в систему. Это можно сделать разово при обновлении с помощью опции

apt-get update --allow-unauthenticated

Намного удобнее сделать это навсегда в отдельном списке репозитариев по типу:

deb [arch=amd64 allow-insecure=yes] http://www.deb-something-exampe.org buster main

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

UPD: Обновленный и более хороший способ

rsync на нестандартном порту с докачкой

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

Первая часть задачи — заставить rsync работать с докачкой, без дотошного сравнения файлов и быстро. Это делается ключом --append-verify, который докачивает файл полность и затем сравнивает контрольную сумму. Если она расходится, то файл копируется заново. Это практически идеальный вариант для закачки многогигабайтовых образов по тонкому каналу.

Вторая часть — заставить rsync подключаться на другой порт. Прямой опции, кторая позволяет так делать нет, но можно указать опцию для ssh, через ключ «-e».

В итоге получается команда вроде

rsync -av --append-verify -e "ssh -p 55667" backup-srv:/data/backup/ /data/backup-srv

Отключение аутентификации Nginx для заданных ip-диапазонов

Удобный инструмент для защиты разного рода тестовых/разработческих сайтов — аутентификация на уровне веб-сервера по паролю. Она закрывает сайты от ненамеренного индексирования поисковиками и от входа третьих лиц. В Nginx такая делается директивой auth_basic, которая дополняется файлом с пользователями и паролями. Кто-то из разработчиков заходит со статических адресов, поэтому в им аутентификация не нужна и её можно отключить. Делается это следующим образом:

satisfy  any;
allow XX.XX.XX.XX/ZZ;
allow YY.YY.YY.YY/WW;
allow ...
deny   all;

auth_basic            "restricted area";
auth_basic_user_file  htpasswd/example.com;

Таким образом пользователи со статических адресов могут заходить на сайт без ввода паролей. Таким же образом можно открыть сайт для интернет-тестеров разных возможностей сайта, в частности оптимизации (google pagespeed, gtmetrix), безопасности и т.п.

Обновления security для Debian

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

На практике это работает следующим образом. Обычно security-ветки уже есть в /etc/apt/sources.list. Мы на основе его создадим отдельный файл, в который поместим только ветки безопасности:

cd /etc/apt
cp sources.list sources.list.d/security.list

Далее из первого файла удалим security-источники, а во втором только их и оставим. Если в исходном файле нет security-источников совсем, тогда просто добавляем их в новый файл /etc/apt/sources.list.d/security.list. Нужны будут security-ветки для нужных репозитариев, обычно это stable.

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

apt-get update
apt-get upgrade -o Dir::Etc::SourceList=/etc/apt/conf.d/security.list

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

md127

После изменения конфигурации софтового рейда, mdadm-устройств некоторые из них именуются странным образом вроде md127. Это уже с изменённым /etc/mdadm/mdadm.conf.

Решается генерацией initramfs заново:

sudo update-initramfs -u

При следующей загрузке устройства именуются как надо.

Вход в BIOS на ноутбуках HP серий 250/260 G*

Последние ноубуки с UEFI BIOS имеют нетривиальный вход в собственно настройки биоса. Каждый производитель придумывает свой хитрый способ. В такие моменты с теплотой вспоминаешь старые компьютеры, на которых вход был унифицированный с помощью Del.

На днях разбирался с Hewlett Packard HP 260 G2. Он имеет UEFI BIOS, зайти в который ещё надо знать как. Нашёл этот способ и чтобы не забыть сохраню.

Как попасть в BIOS. Сразу после включения Power нажимаем (и отпускаем) ESC, а после быстро F10, которую лучше держать.
Ка попасть в меню загрузки (Boot Order). Аналогично нажимаем ESC, а затем F9.

Управление supervisorctl без рутовых прав

Для разных самописных процессов, которые нужно запускать как демон, есть прекрасный инструмент supervisor. Управление запуском процесса в нём происходит с помощью конфигов предельно простого синтаксиса (и в тоже время покрывающих почти все необходимости) в /etc/supervisor.d/ и команд наподобие:

supervisorctl start myapp
supervisorctl stop myapp
supervisorctl restart myapp

т.е. интерфейс полностью аналогичный управлению демонами в ОС.

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

sudo supervisorctl restart myapp

Но если это виртуальная машина, в которой supervisor нужен именно для приложений от этого пользователя, то можно сделать и в обход root совсем. Для этого необходимо поправить в /etc/supervisor/supervisord.conf:

[unix_http_server]
file=/var/run/supervisor.sock
chmod=0770
chown=someuser:someuser

После этого supervisor будет управляться из под пользователя. У способа есть недостаток, что теперь supervisor заточен на приложения этого пользователя/группы, но часто это не является препятствием.

Ускорение raid5 md-массивов на запись

RAID5/6-массивы дисков — типичное решение для файловых архивов, к которым много запросов на чтение и мало на запись. Их слабое место: медленные операции записи, в которых для расчёта контрольной суммы требуется чтение со всех томов данных массива. Это приводит не только к медленной записи на массив новых данных, но и к медленному исполнению всех операций предполагающих модификацию раздела, в частности операции удаления. А если ещё и используется дешёвый вариант рейда на основе mdadm, без всяких батареек, кешей и специализированного софта для рейдов, то удаление большого количества файлов становится ну оочень медленной задачей.

Отчасти это можно исправить. raid5 при записи много читает, читает даже больше чем пишет. При удалении модифицируемые данные это структуры затрагиваемых файлов и директорий, в общем-то небольшого количества данных, но изменяемых многократно. Учитывая, что XFS (и другие устойчивые файловые системы тоже) делают это безопасно для отключения питания, т.е. собственно коммитом и через журнал. Поэтому, хороший прирост скорости удаления даёт изменение кеша чтения mdadm:

    echo 16384 > /sys/block/md?/md/stripe_cache_size

Параметр stripe_cache_size по умолчанию имеет значение 256 (страниц по 4Kb), что в большинстве случаев достаточно мало. Максимальное значение — 32768, при этом скорость достаточно хорошая уже при значениях 8192-16384. При увеличении параметра надо учитывать, что это значение в страницах для каждого устройства в рейде и он в результате может занимать весомую часть ОЗУ. Тем не менее, даже если ОЗУ не много, увеличение чаще имеет смысл.

Кроме этого способа, можно увеличить производительность вынесением журнала на отдельный раздел (и тогда раздел данных становится несколько зависимым от другого) или включением разных опций вроде nobarrier, которые сделают ФС быстрой но потенциально нерабочей в случае отключения питания. Это скорее не для продакшн-систем.

Поддомены по маске в CORS

В веб-проектах в последнее время всё активнее и активнее используется размещение разного контента по разным поддоменам. Например, типична ситуация, когда статические файлы размещают на отдельных поддоменах для работы с CDN или использование поддоменов для разных языковых версий сайта, или же для разных географических локаций. Основная часть ресурсов обычно едина для всех отдельных сайтов, как правило это картинки css/js и прочая статика. Чтобы кросс-запросы между поддоменами корректно принимались браузером в плане безопасности, необходимо настроить для CORS заголовки в ответе веб-сервера.

Домены с которых разрешено загружать контент указываются на ресурсе-источнике в заголовке Access-Control-Allow-Origin. В нём можно перечислить явно домены, с которых можно запрашивать контент, или разрешить со всех астериском ‘*’. К сожалению, разрешить поддомены по маске, например *.example.com, простым укаазанием этой маски в заголовке не удастся. Т.е. можно разрешить или всё или перечислять все домены. Что делать если этих доменов много или их неопределённый список и логичнее включить доступ по маске?

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

  set $cors "";
  if ($http_origin ~* (\.example\.com|\.example\.ru)) {
      set $cors "true";
  }

  if ($cors = "true") {
    add_header 'Access-Control-Allow-Origin' "$http_origin";
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS, DELETE';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
  }

  proxy_pass http://backend:8080/;

Его целесообразно вынести в отдельный snippet и включать в те location, с которых берёрется контент для остальных поддоменов. При этом мы не затрагиваем бэкэнд, что экономит производительность.

libmariadbclient18 perl

После обновления MariaDB до версии 10.2 в debian-дистрибутивах в perl-приложениях возникает ошибка

install_driver(mysql) failed: Can't load '/usr/lib/x86_64-linux-gnu/perl5/5.24/auto/DBD/mysql/mysql.so' for module DBD::mysql: /usr/lib/x86_64-linux-gnu/libmariadbclient.so.18: version `libmariadbclient_18' not found (required by /usr/lib/x86_64-linux-gnu/perl5/5.24/auto/DBD/mysql/mysql.so) at /usr/lib/x86_64-linux-gnu/perl/5.24/DynaLoader.pm line 187

Оказывается, это баг MariaDB, о котором можно прочитать в соответствующей статье, в ней же есть и решение. Практическое решение это откат библиотеки libmariadbclient18 до предыдущей версии, в которой она слинкована правильно. При использовании apt/apt-get и официальных репозитариев Марии для этого нужно добавить в файлик /etc/apt/preferences строки

Package: *
Pin: release o=MariaDB,n=stretch
Pin-Priority: 1001

Package: libmariadbclient18
Pin: release o=Debian,n=stretch
Pin-Priority: 1002

и после этого даунгрейдить libmariadbclient18.

PS: Ошибка точно затрагивает мониторинг параметров mysql от Munin, поэтому если «потерялись» графики базы после обновлениях, то причиной является наверняка та, что описана выше.

Поменять почтовый адрес root

Важной частью стабильной работы сервера является мониторинг событий на нём. Кроме специализированных утилит вроде logcheck и прочих автоматических анализаторов логов, есть более простые способы получаения важных событий. В частности, многие демоны и прикладные программы используют отправляют сообщения об ошибках и других важных событиях на почтовый адрес суперпользователя root@hostname самого сервера. В настроенном «из коробки» сервере эта почта складывается или в директорию в домашней директории пользователя или в файл /var/mail/$USER. В обоих случаях почта хранится локально, прочитать её можно вручную локально на сервере, что редко кто делает. Перенаправим эти сообщения на другой почтовый ящик, который регулярно проверяется и читается. Это можно сделать следующими основными способами.

/etc/aliases

Это глобальный способ для любого пользователя в системе. /etc/aliases содержит почтовые алиасы алиасы локальных пользователей. Добавляя/изменяя срочку

root: system@example.com, adm@mydomain.com

получаем перенаправление почты на соответствующие адреса. После изменения файла алиасов необходимо запустить newaliases для принятия изменений.

~/.forward

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

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

Реальный адрес через обратный прокси nginx

Nginx в последнее время повсеместно используется как обратный веб-прокси. Среди параметров, которые он передаёт бэкенду есть и реальный ip-адрес пользователя, который нередко используется в приложении. Кроме приложения тот же адрес отображается в логах и для целей отладки целесообразно в них писать также действительный адрес. Задача передачи этого параметра (и некоторых других — протокола, хоста) со стороны обратного прокси обычно решается добавлением заголовков:

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

Файл с этими заголовками в виде сниппета есть даже в поставке nginx «из коробки», поэтому со его стороны всё решается предельно просто: инклюдом этого сниппета в конфигурации виртуальных хостов.

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

    RemoteIPHeader X-Real-IP
    RemoteIPInternalProxy 127.0.0.1

И после этого всё работает. В лог-файлах для корректного отображения адреса также стоит заменить «%h» -> «%a», что есть не лучшее, но рабочее решение.

В nginx-бэкенде чтобы не менять стандартный log_format в окружение server виртуального хоста добавляется

    set_real_ip_from  192.168.1.4;
    real_ip_header    X-Forwarded-For;

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

Port forward to another server

При переезде сайтов или другого постоянно используемого извне ресурса возникает потребность его доступности как со старого, так и с нового местоположения, пока по сети распространяются новые записи DNS. Сделать это без нарушения целостности данных можно с помощью перенаправления порта. Например, если на NEW_IP_ADDR поднят https-сервер, все актуальные данные уже на нём, то на время переключения DNS редиректить со старого адреса на новый можно так:

iptables -P FORWARD ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -F
iptables -X
iptables -F -t nat
iptables -X -t nat

iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination NEW_IP_ADDR:443
iptables -t nat -A POSTROUTING -j MASQUERADE

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