Почему nftables блокирует IP-адрес сервера базы данных?

Я хочу ограничить количество подключений к сайту с одного IP-адреса до 20 в секунду. Если количество запросов превышает это значение, я планирую заблокировать IP, а блокировку снять через 5 минут. Я реализую это следующим образом: 
<pre><code>nft add table ip filter
nft add chain ip filter input { type filter hook input priority 0 \; }
nft add set ip filter denylist { type ipv4_addr \; flags dynamic, timeout \; timeout 5m \; }
nft add rule ip filter input ip protocol tcp ct state new, untracked limit rate over 20/second add @denylist { ip saddr }
nft add rule ip filter input ip saddr @denylist drop</code></pre>
Тем не менее, приложение на этом сервере, использующее IP 1.2.3.4.5 для отправки запросов в базу данных, вызывает блокировку сервера базы данных. Почему это происходит?
  • 15 декабря 2024 г. 17:43
Ответы на вопрос 1
Проблема, с которой вы сталкиваетесь, заключается в том, что ваши правила `nftables` блокируют запросы по IP-адресу, который используется как источником для подключения вашего приложения к базе данных. Давайте разберёмся подробнее.

1. **Правила фильтрации**: Ваша конструкция правил делает следующее:
   - Вы создаёте таблицу и цепочку для фильтрации входящего трафика.
   - Вы добавляете набор (set) `denylist`, в который помещаете IP-адреса, превышающие лимит подключений.
   - Первое правило добавляет IP-адреса в `denylist`, если они превышают 20 подключений в секунду.
   - Второе правило блокирует (drop) все IP-адреса, которые находятся в `denylist`.

2. **Подключения к базе данных**: Если ваше приложение, использующее IP-адрес 1.2.3.4.5, отправляет много запросов в секунду (больше 20), то этот IP-адрес будет добавлен в `denylist`. Это означает, что в итоге все новые подключения от этого IP-адреса будут заблокированы, включая те, которые направляются к серверу базы данных.

3. **Проблема с приложением**: Если ваше приложение постоянно переполняет лимит по обращениям (количество подключений больше 20 в секунду), то его IP-адрес будет помещён в черный список, что ведёт к тому, что оно не сможет подключаться к базе данных.

### Возможные решения:

1. **Исключение IP-адреса базы данных**: Если вы хотите, чтобы ваше приложение всегда могло подключаться к базе данных, вы можете добавить отдельное правило, которое будет разрешать подключения от IP-адреса базы данных, если он использует определённый порт (например, 3306 для MySQL или 5432 для PostgreSQL). Например:
   
   ```bash
   nft add rule ip filter input ip saddr <IP_базы_данных> tcp dport <порт_базы_данных> accept
   ```

2. **Изменение лимита**: Если у вас есть возможность регулировать количество подключений к базе данных с вашего приложения, попробуйте оптимизировать его так, чтобы количество запросов в секунду не превышало 20, что также поможет избежать блокировок.

3. **Использование различных IP-адресов**: Если возможно, настройте ваше приложение так, чтобы оно использовало разные IP-адреса для запросов к базе данных, что поможет распределить нагрузку.

4. **Анализ логов**: Проверьте логи вашего приложения и `nftables`, чтобы идентифицировать, какие именно запросы и в какой момент превышают лимит.

5. **Увеличение разрешённого лимита**: Возможно, вам стоит пересмотреть порог ограничения на подключение, если ваше приложение справляется с высокой нагрузкой.

Эти меры помогут вам предотвратить блокировку IP-адреса, с которого ваше приложение подключается к базе данных.
Похожие вопросы