Docker и Nginx - ВСЁ!
Больше невозможно по нормальному собрать некоторые сервисы и получить подтверждение Let's Encrypt ssl сертификата!
Больше невозможно по нормальному собрать некоторые сервисы и получить подтверждение Let's Encrypt ssl сертификата!
Похоже, лично мое клатбисче используемых проектов* в этом году пополнится Ingress NGINX – проект все, Ingress NGINX Retirement: What You Need to Know. Предлагается переход на Gateway API, сколько всего придется переделать, переписать и переставить – пока даже не представляю.
Интересно даже не это, а то, сколько заброшенных или забрасываемых проектов выявляется каждый год. И замены им нет, и не будет.
И даже не это интересно, как то, что разработчики Ingress NGINX два года пытались найти кого-то, кто бы помог в разработке опенсорса. Но нет, использовать можно, сказать бесплатным разработчикам ВЕЗИ МЕНЯ ТВАРЬ «давайте чините» можно, самим делать – нет.
На первом месте в моем личном каталоге «проблем от заброшенных компонентов» – Apache Log4j. 4 года назад (9 декабря 2021 года) в проекте, который теоретически должен был быть 100 раз просмотрен и проверен, потому что использовался везде, нашли огроменную дыру, Log4Shell (CVE-2021-44228). Куда смотрело все сообщество?
На втором месте – огроменная дыра в Linux под названием EternalRed (она же SambaCry), она же CVE-2017-7494. Дыра существовала с 2010 года, обнаружена была только в 2017, и то, не «обнаружена», а была проэксплуатирована с огромными последствиями. Куда смотрело все сообщество?
На третьем – свежая огромная дыра, размером с дверь ангара, в grafana - CVE-2025-41115. 10 из 10. Куда смотрело все сообщество?
Если говорить только о заброшенных проектах, то я до сих пор скучаю по заброшенному 10 лет назад RatticWeb. Не видел ничего лучше с тех пор. Мне особо не нужно, мне и Hashicorp Vault хватает, коллеги хвалят teampass, но все равно не то.
Что тут сказать?
Меняется вся модель opensource. «Давно», даже «очень давно», во времена победившей сексуальной революции и зарождения опенсорса, продукты были куда проще, а времени куда больше, так что продукты как-то писались и эксплуатировались.
Сейчас? Недавно у коллег (не в РФ) случились эффективные менеджеры, которые волевым способом продавили переход на новый, свежий Ceph.
Проработал Ceph полтора месяца и свалился, с потерей данных.
Смешно во всем этом даже не то, что Ceph свалился, и не то, что Ceph до сих пор тормозное и дорогое (отдельные сервера, отдельные сети, отдельные люди) решение, а то, что одной из причин стало
Support for GlusterFS is dropped
As GlusterFS is no longer maintained upstream, Proxmox VE 9 drops support for GlusterFS storages. Setups using GlusterFS storage either need to move all GlusterFS to a different storage, or manually mount the GlusterFS instance and use it as a Directory storage.
Drop support for GlusterFS starting with PVE 9, as it is unmaintained.
Proxmox Roadmap - Proxmox VE 9.0
Так и живем.
* отсылка к pet sematary, правильное написание Pet Cemetery, книга и кино.
Для модераторов. В статье нет рекламы.
Кажется, у нас появился настоящий "фанат", причём настолько страстный, что решил обрушить наш сайт массированной DDoS-атакой. Сначала мы даже улыбнулись — ну, внимание приятно. Но серверу было не до шуток.
Несмотря на то, что у нас стоял сервис от DDOS (не буду писать, а то подумают реклама), включение режима JS Challenge не помогло — часть запросов всё равно проходила, и сервер ложился от нагрузки. Пришлось действовать решительно.
Мы быстро собрали из логов черный список из 1400 IP-адресов, но эффект оказался кратковременным — IP менялись, а нагрузка продолжалась.
Так и родилась идея: использовать fail2ban для автоматической защиты на уровне сервера. И, скажем прямо, это было отличное решение.
Устанавливаем через APT:
sudo apt install fail2ban
Нам повезло: злоумышленник атаковал один конкретный адрес —
https://site/login/
https://site/register/
https://site/wp-login.php
и прочие варианты по шаблону
Это дало преимущество: множество повторяющихся POST-запросов с одного IP — именно то, что умеет отсекать fail2ban.
Создаём фильтр:
/etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^ - - [.] "POST /login/ HTTP/." (200|403|404)
📌 Что делает фильтр?
Он отслеживает POST-запросы к /login/, которые получают коды ответа:
200 — успешный доступ (например, фальшивая регистрация)
403 — доступ запрещён
404 — страницы не существует (спамеры промахнулись)
Открываем файл:
/etc/fail2ban/jail.local
и добавляем:
[wordpress-register]
enabled = true
filter = wordpress
logpath = /var/log/nginx/domains/site.log
maxretry = 5
findtime = 60
bantime = 36000000
action = iptables[name=wordpress-register, port="http,https", protocol=tcp]
📌 Объяснение параметров:
enabled = true — включаем правило
filter = wordpress — имя фильтра без .conf
logpath — путь к nginx-логу
maxretry = 5 — допустимое количество попыток до бана
findtime = 60 — за какой период искать попытки (в секундах)
bantime = 36000000 — сколько длится бан. Это ~68 лет 😄
action — блокировка через iptables на порт 80 и 443 (HTTPS)
Перед применением можно протестировать фильтр:
fail2ban-regex /var/log/nginx/domains/site.log /etc/fail2ban/filter.d/wordpress.conf
Применяем конфигурацию:
sudo fail2ban-client reload
sudo systemctl restart fail2ban (Перезапускать службу не всегда желательно, так как он забывает все заблокированные IP адреса, а это плохо при массированной атаке, поэтому рекомендую использовать только fail2ban-client reload, где обновляются правила)
Проверка статуса:
fail2ban-client status wordpress-register
Пример:
Status for the jail: wordpress-register
|- Filter
| |- Currently failed: 138
| |- Total failed: 6038
| - File list: /var/log/nginx/domains/site.log - Actions
|- Currently banned: 821
|- Total banned: 821
`- Banned IP list: 1.20.227.66 101.126.80.238 ...
Если видите IP — значит, fail2ban работает.
Дополнительно можете проверить цепочку в iptables:
sudo iptables -L f2b-wordpress-register -n
После этого наш фанат решил проявить смекалку и нам пришлось создать еще несколько правил.
Открываем файл:
/etc/fail2ban/jail.local
и добавляем:
[wordpress-ddos]
enabled = true
filter = wordpress-ddos
logpath = /var/log/nginx/domains/site.log
maxretry = 5
findtime = 60
bantime = 36000
backend = auto
action = iptables[name=wordpress-ddos, port="http,https", protocol=tcp]
[hestia-ddos]
enabled = true
filter = hestia-ddos
logpath = /var/log/hestia/nginx-access.log
maxretry = 90
findtime = 60
bantime = 360
action = iptables[name=hestia-ddos, port=8027, protocol=tcp]
[site-ddos-param]
enabled = true
filter = site-ddos-param
logpath = /var/log/nginx/domains/site.log
findtime = 60
maxretry = 2
bantime = 360000
action = iptables[name=site-ddos-param, port="http,https", protocol=tcp]
[nginx-ddos-errorlog]
enabled = true
filter = nginx-ddos-errorlog
logpath = /var/log/nginx/domains/site.error.log
findtime = 60
maxretry = 3
bantime = 86400
action = iptables[name=nginx-ddos-errorlog, port="http,https", protocol=tcp]
[nginx-referrer-selfip]
enabled = true
filter = nginx-referrer-selfip
logpath = /var/log/nginx/domains/site.log
findtime = 60
maxretry = 1
bantime = 2592000 # 30 дней
action = iptables[name=referrer-selfip, port="http,https", protocol=tcp]
Все правила писали через регулярные выражения
/etc/fail2ban/filter.d/hestia-ddos.conf
[Definition]
failregex = ^ - - [.] "." [2-5][0-9]{2} .*
/etc/fail2ban/filter.d/site-ddos-param.conf
[Definition]
failregex = ^ - - [.] "GET /?\d{5,} HTTP/." [2-5][0-9]{2} .*
/etc/fail2ban/filter.d/nginx-ddos-errorlog.conf
[Definition]
failregex = ^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} [error].access forbidden by rule, client: , server: ., request: "GET /?\d{6,} HTTP/1.1"
/etc/fail2ban/filter.d/nginx-referrer-selfip.conf
[Definition]
failregex = ^ - - [.] "GET ." \d+ \d+ "https?://.100.90.80.70."
🚀 Договариваемся с nginx
Так же часть запросов ?78698675876 грузили сервер, т.е. Fail2ban пропускал запросы к серверу из-за того, что трафика было много, но мы это решили делать пересылку на 403 запрос, что бы экономить ресурсы сервера
Открываем файл:
/etc/nginx/conf.d/domains/site.ssl.conf
и добавляем:
Между блоком
server {
...
#Slait
# Блокировать запросы с реферером, содержащим наш IP
if ($http_referer ~* "100\.90\.80\.70") {
return 403;
}
# Блокировать GET-запросы типа /?123456 (только цифры в query string)
if ($request_uri ~* "^/\?\d{9,}$") {
return 403;
}
#Slait...
}
Применяем конфигурацию:
sudo systemctl restart nginx
Fail2ban помог нам перехватить атаку в реальном времени, за считанные минуты блокируя сотни IP-адресов. Простая настройка и мощный результат — рекомендуем!
Nginx — пока еще один из самых популярных веб-серверов, и ключевой компонент современной корпоративной архитектуры. В этой статье мы рассмотрим базовые параметры конфигурации (доступные "из коробки"), которые упрощают мониторинг, улучшают производительность и усиливают безопасность — в конечном итоге повышая устойчивость вашей инфраструктуры.
JSON — лучший выбор формата для логов Nginx по двум основным причинам. Во-первых, он гораздо более читаем для человека. Во-вторых, передача логов в такие системы, как OpenSearch, для последующего мониторинга или в рамках SIEM-решений становится сильно проще.
Вот простой пример из nginx.conf:
log_format json-logger escape=json '{
"type": "access-log",
"time": "$time_iso8601",
"remote-ip": "$remote_addr",
"x-forward-for": "$proxy_add_x_forwarded_for",
"request-id": "$request_id",
"request-length": "$request_length",
"response-bytes": "$bytes_sent",
"response-body-size": "$body_bytes_sent",
"status": "$status",
"vhost": "$host",
"protocol": "$server_protocol",
"path": "$uri",
"query": "$args",
"duration": "$request_time",
"backend-duration": "$upstream_response_time",
"backend-status": "$upstream_status",
"method": "$request_method",
"referer": "$http_referer",
"user-agent": "$http_user_agent",
"active-connections": "$connections_active"
}';
access_log /var/log/nginx/access.log json-logger;
Это приведёт к следующему выводу в файле access.log:
{
"type": "access-log",
"time": "2025-02-25T16:02:54+00:00",
"remote-ip": "130.61.78.239",
"x-forward-for": "130.61.78.239",
"request-id": "38750f2a1a51b196fa0a76025b0d1be9",
"request-length": "258",
"response-bytes": "353",
"response-body-size": "167",
"status": "404",
"vhost": "3.69.78.187",
"protocol": "HTTP/1.1",
"path": "/lib/phpunit/Util/PHP/eval-stdin.php",
"query": "",
"duration": "0.016",
"backend-duration": "0.016",
"backend-status": "404",
"method": "GET",
"referer": "",
"user-agent": "Custom-AsyncHttpClient",
"active-connections": "1"
}
Большие размеры тела запроса, длительные тайм-ауты и чрезмерно увеличенные настройки KeepAlive могут негативно повлиять на производительность. Чтобы повысить эффективность, лучше устанавливать эти параметры на минимально возможные значения — при этом, само собой, соблюдая требования вашего приложения.
Пример из nginx.conf:
client_max_body_size 10M;
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 5s 5s;
Описание параметров:
client_max_body_size
Определяет максимальный размер тела HTTP-запроса, который клиент может отправить. Если лимит превышен, Nginx возвращает ошибку 413 Request Entity Too Large.
client_body_timeout
Задает максимальное время ожидания полного тела запроса. Если за это время тело не получено, соединение будет закрыто.
client_header_timeout
Устанавливает максимальное время ожидания полного заголовка HTTP-запроса от клиента. Если лимит превышен — соединение также закрывается.
keepalive_timeout
Определяет, как долго будет оставаться открытым соединение Keep-Alive после последнего запроса.
Первый параметр (например, 5s) задаёт тайм-аут на стороне сервера. Второй (опциональный) параметр передаётся клиенту как предложение о том, как долго он может держать соединение открытым.
На случай если клиент пытается перегрузить веб-сервер частыми запросами, Nginx предоставляет возможность настроить "зоны ограничения запросов" (limit request zones) — для контроля трафика по различным параметрам.
Пример настройки (реверс-прокси с зоной ограничения запросов):
limit_req_zone $binary_remote_addr zone=limitreqsbyaddr:20m rate=15r/s;
limit_req_status 429;
upstream app.localhost {
server localhost:8080;
}
server {
listen 443 ssl;
server_name app.devlab.intern;
location / {
limit_req zone=limitreqsbyaddr burst=10;
proxy_pass http://app.localhost;
}
}
Пояснение параметров:
$binary_remote_addr
Используется для настройки зоны ограничения по IP-адресу клиента. Адрес сохраняется в бинарной форме (это снижает потребление памяти).
zone=limitreqsbyaddr:20m
Создаёт общую (shared) область памяти объёмом 20 МБ с именем limitreqsbyaddr. В этой зоне хранятся данные о лимитах для разных IP-адресов.
rate=15r/s
Ограничивает количество запросов до 15 запросов в секунду на IP. Превышение лимита приводит к отклонению избыточных запросов.
limit_req_status 429;
При превышении лимита Nginx возвращает статус 429 Too Many Requests, что означает: "Слишком много запросов за короткое время".
Эта конфигурация помогает защитить сервисы от перегрузки и злоупотреблений.
На мой взгляд, ограничение допустимых HTTP-методов только теми, которые действительно необходимы или поддерживаются приложением (например, REST API), — это чистый и логичный способ синхронизации настроек веб-сервера с логикой приложения. Это помогает не только предотвратить неправильное использование API или вызов нежелательных методов, но и блокирует потенциально опасные запросы вроде TRACE. Кроме того, это снижает ненужную нагрузку на сервер, устраняя неподдерживаемые или неуместные запросы.
Пример: разрешён только метод GET (HEAD разрешается по умолчанию):
# HEAD is implicit
limit_except GET {
deny all;
}
Пример: разрешить все методы, кроме TRACE и PATCH:
if ($request_method ~ ^(PATCH|TRACE)$) {
return 405;
}
Если на сервер поступают запросы от ботов или плохо сконфигурированных сканеров (часто с «говорящими» user-agent'ами), можно внести путаницу и затруднить их работу, возвращая нестандартный статус HTTP от самого Nginx.
Для этого создаём файл bot.protection.conf в директории /etc/nginx/snippets со следующим содержимым:
map $http_user_agent $blacklist_user_agents {
~*wpscan 1;
~*dirbuster 1;
~*gobuster 1;
}
Вы можете дополнять список по мере необходимости.
Внутри конфигурации виртуального хоста (VHost) подключите файл следующим образом:
include /etc/nginx/snippets/bot.protection.conf;
if ($blacklist_user_agents) {
return 444;
}
HTTP 444 также можно «весело» использовать для предотвращения угадывания служебных файлов, таких как .env:
# <your-domain>/.bash_history for example ends with HTTP 444.
location ~ /\. {
return 444;
}
Что означает HTTP 444?
HTTP 444 — это нестандартизированный статус-код, используемый в NGINX, который заставляет сервер мгновенно закрыть соединение без отправки заголовков ответа клиенту. Чаще всего используется для отклонения вредоносных или некорректно оформленных запросов. Интересный побочный эффект: некоторые сканеры не умеют корректно обрабатывать такие ответы, что добавляет дополнительный уровень защиты.
TCP Fast Open — это важное улучшение в Nginx, которое позволяет более эффективно устанавливать TCP-соединения. Эта функция даёт возможность начать передачу данных уже во время начального рукопожатия, что заметно ускоряет процесс установления соединения. Особенно полезна она в условиях высокой сетевой задержки, так как помогает сократить латентность и повысить производительность.
Проверка поддержки TCP Fast Open в ядре Linux
Выполните следующую команду:
cat /proc/sys/net/ipv4/tcp_fastopen
Если в ответе вернётся 1, функция уже включена. Если нет — включите её командой:
echo 1 > /proc/sys/net/ipv4/tcp_fastopen
Использование в конфигурации Nginx
Добавьте параметр fastopen в директивы listen:
listen [::]:443 ssl http2 fastopen=500;
listen 443 ssl http2 fastopen=500;
Число 500 — это количество подключений, которые могут использовать TCP Fast Open одновременно (значение можно адаптировать под вашу нагрузку).
GZip — это метод сжатия данных, позволяющий уменьшить размер файлов. При этом исходные данные можно полностью восстановить путём распаковки («разархивирования») сжатого файла.
Для веб-приложений и сайтов GZip особенно важен, поскольку HTTP-протокол поддерживает передачу данных в сжатом виде до того, как они попадут в сеть.
Почему GZip важен:
Снижение трафика: при включённом GZip размер передаваемых файлов уменьшается, что приводит к меньшему потреблению пропускной способности.
Экономия на хостинге: меньше трафика — ниже затраты на обслуживание.
Ускорение загрузки для пользователей: посетители получают более лёгкие файлы, что сокращает время загрузки страниц.
Пример конфигурации:
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
Эта настройка включает GZip и указывает типы содержимого, которые следует сжимать (текст, CSS, JavaScript, XML, JSON и др.).
В современном веб пространстве скорость и производительность сайтов имеют решающее значение. Пользователи ожидают быстрой загрузки страниц, а поисковые системы учитывают время отклика при ранжировании. Поэтому выбор веб-сервера имеет критически важное значение. Давайте разберемся почему LiteSpeed часто превосходит Apache и Nginx.
1. Высокая производительность и скорость.
Представьте себе веб-сервер, который способен жонглировать тысячями запросов, не проливая ни капли пота. Это LiteSpeed! Благодаря своей событейно-ориентированной архитектуре, он работает так же быстро, как кофе по утрам!)
В то время как Apache все еще пытается проснуться со своей процессной архитектурой, LiteSpeed уже пробежал марафон.
2. Встроенное кэширование с LSCache
Вот кто не любит, когда все работает быстрее? LSWS приходит с подарком - встроенным кэшэм. Это как личный шеф-повар, который зарнее готовит ваши любимые блюда)
Ваш сайт будет подавать страницы так быстро, что пользователи предположат, что вы предсказываете их желания))) И конечно он дружит с такими CMS как Wordpress, Joomla и прочие..
3. Поддержка современных протоколов
LiteSpeed - всегда вкурсе последних трендов.
Имеется поддежка HTTP/3 и QUIC, что делает передачу данных быстрее скорости света. Это особенно круто для мобильных пользователей и тех, кто сидит на интернете с улиточной скоростью - теперь все будет летать!)
4. Эффективное использование ресурсов
Цены на железо достигают колосальных цен, а зачем тратить больше, когда можно тратить меньше?
LiteSpeed экономит оперативную память и процессорное время так, словно сам за них платит)
Большее кол-во пользователей может быть обслуженно на том же железе, позволяя вам сэкономить на инфраструктуре, потратьте эти деньги на родных и близких ;)
5. Совместимость с Apache
Боитесь перермен? Я тоже. Как хорошо, что LiteSpeed полностью совместим с конфигурационными файлами Apache. Переходите на РЕАЛЬНО хороший вебсервер без головной и жопной боли из за переписывания всех настроек с нуля.
6. Бесплатная версия OpenLiteSpeed.
Не уверенны? Хотите попробовать, а трайл версии мало? OpenLiteSpeed идеальный вариант для временного решение, ведь по функционалу, он не сильно то и урезан, грубо говоря чуть более старая версия нынешнего LiteSpeed.
Заключение
К чему эта статья? Создатели веб-серверов, хватит уже жить в эпохе динозваров! Нам, пользователям, нужна скорость и удобство. Зачем нам Apache и Nginx, когда есть нечтно новее, с GUI и высокой производительностью?
Не время ли оставить старые добрые и "ламповые" сервера для музеев технологий? Зачем нам разгонять интернет на паровой машине, когда давно придумали реактивные двигатели.
И, честно говоря, кто станет использовать веб-сервера, требующие знания древних заклинаний для настройки? Может, некоторым хостингам кажется, что это весело? Ну что ж, пусть продолжают жить в мире дискет и модемов)) (Привет синийхост точка ком)
Давайте двигаться вперед и использовать современные технологии, которые делают жизнь проще, а сайты быстрее)
Мы все заслуживаем скорость света в интернете, а не прогулки с черепахой, мы же платим за это деньги!
Доброго времени суток. Столкнулся с трудноуловимым и малопонятным багом в Редмайне.
В общем, имеется сервер с Редмайном. Доступ есть и из локальной сети, и извне. Для доступа извне, на веб-сервере (другая машина) в nginx настроено проксирование.
Так вот, теперь, при доступе из локали, например по ip-адресу в адресной строке, всё работает нормально. Но если заходить извне, по доменному имени, то проявляется следующий баг:
Добавляем к задаче комментарий (допустим, "ТЕСТ"). Сохраняем его. Редактируем этот комментарий (ТЕСТ2). Сохраняем. И при повтором редактировании, комментарий отображается как самый первый (ТЕСТ). Пробовал искать информацию по такому глюку - не нашёл, потому что сложноописумый.
Подозреваю что дело в проксировании (так как в локали глюк не проявляется), но правило там стандартное:
server {
server_name redmine.example.com www.redmine.example.com;
location / {
proxy_pass http://192.168.1.253;
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;
client_max_body_size 0;
client_body_buffer_size 128k;
}
}
Доступ по протоколу HTTP, как изнутри, так и снаружи.
Может тут кто с таким сталкивался, или знает в какую сторону копать?
Какой пет-проект выбрать (придумать) для начинающих программистов – это актуальная тема. Где еще можно воплотить теорию, которую ты учил месяцами, и узнать, «тварь ли ты дрожащая», или что-то уже можешь и умеешь.
На самом деле желание сделать что-то свое возникает не только в IT, но эта область требует минимальных финансовых вложений, поэтому пробовать и ошибаться не так страшно и накладно. К сожалению, выбор приходит с опытом, поэтому юные джуны мучаются вопросом, что еще сделать, кроме «todo list». Но когда у тебя есть опыт и в «оффлайне», то найти, куда приложить новые IT-знания, становится значительно проще. Один из моих пет-проектов, воплотив который, за короткий срок я изучил и использовал много новых для себя технологий: Vue, Docker, Nginx, JWT-аутентификацию, ИИ-модели, Mongo, Git, Node.
В телеге оставил ссылку на репозиторий проекта и более развернутое видео, на сервере его уже не попробовать. Вполне рабочее и полезное приложение по концепции "вторая память", код в репозитории открывает огромные возможности для рефакторинга, но думаю слова: "всё х..ня, давай по-новой" - наиболее точно описывают его.