• Новые темы в этом разделе публикуются автоматически при добавлении файла в менеджер ресурсов.
    Ручное создание новых тем невозможно.
Иконка ресурса

Мануал Настройка IPtables

Нет прав для скачивания
  • Автор темы Автор темы tapok
  • Дата начала Дата начала

tapok

Выдающийся
Местный
Сообщения
51
Розыгрыши
0
Репутация
68
Реакции
212
Баллы
1 338
tapok добавил(а) новый ресурс:

Настройка IPtables - IPtables


Узнать больше об этом ресурсе...
 
Спасибо!
Хотел бы поинтересоваться почему используется так много mangle а не raw?
И кажется что лучше блокировать приватные подсети указав интерфейс на который трафик с них пытается попасть, иначе можно полностью отрезать доступ к серверу, или я ошибаюсь?
 
Хотел бы поинтересоваться почему используется так много mangle а не raw?
В RAW нельзя использовать -m conntrack --ctstate
Нельзя проверять TCP флаги с состоянием соединения
В RAW можно было перенести например некоторые правила
Код:
ptables -t raw -A PREROUTING -s 224.0.0.0/3 -j DROP  # Спуфинг
iptables -t raw -A PREROUTING -s 10.0.0.0/8 -j DROP
Но проверки TCP флагов с conntrack остаются в MANGLE:
Код:
iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
тут спасибо, обновил скрипт
 
tapok обновил(а) ресурс Настройка IPtables новой записью:

Логика блокировки приватных сетей


Узнать больше об этом обновлении...
 
tapok обновил(а) ресурс Настройка IPtables новой записью:

Теперь скрипт безопасен при обрыве SSH сессии


Узнать больше об этом обновлении...
 
Вот вам способ инициировать шелл команду при логине на сервер.
Суть в том, что можно блокировать все пакеты к 7777 порту (геймсерверу), если логин не пройдён (проверяем наличие IP в gs_whitelist ipset). Так мы снижаем нагрузку при ДДОС, атакующим позволено только атаковать логинсервер, а там мы можем установить более жёсткие ограничения. А если логин находится на другом компе, то таким образом мы можем полностью изолировать ГС с минимальной нагрузкой на IPTables (например используя шел команду
Код:
ssh debian@172.16.10.2 'sudo ipset -! add gs_whitelist $IP'
для дистанционного добавления ИП в gs_whitelist)

Diff:
Subject: [PATCH] Adding shell script execution on login
===================================================================
diff --git a/dist/config/authserver.properties b/dist/config/authserver.properties
--- a/dist/config/authserver.properties    (revision dd4612b907357287d32b8ad77e657eba86253f2e)
+++ b/dist/config/authserver.properties    (revision e2f6658a4434af74825cd3d27a0deea5b4813c7c)
@@ -95,6 +95,31 @@
 
 # Minimum: 1800, or you get banned
 TorRefreshRate = 5400
+
+# Execute a shell script when an account logs in into the loginserver.
+ExecuteShellScriptOnLogin = False
+
+# The shell script to be executed. Can be a .sh script path as well.
+# $IP is replaced with the IP address of the client.
+# $ACCOUNT is replaced with the account name of the user.
+ShellScriptOnLogin = sudo ipset -! add gs_whitelist $IP
+
+# The timeout in milliseconds, for the shell script to execute.
+# If the shell script does not execute in the given time, it will fail.
+ShellScriptOnLoginTimeout = 5000
+
+# Enable if you want to forcibly destroy the shell script after its execution or fail.
+# It is recommended to normally close the process, but if you experience issues with the process not exiting,
+# you can temporarily enable this, while you are working on solving the issue.
+ShellScriptDestroyForcibly = False
+
+# Log shell script output to the console for debugging purposes.
+ShellScriptLogging = False
+
+# If the shell script execution fails (err code different than 0 is received),
+# send "There is a system error. Please log in again later" error and close the client.
+PreventLoginOnShellScriptFail = False
+
Index: src/main/java/org/mmocore/authserver/Config.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/org/mmocore/authserver/Config.java b/src/main/java/org/mmocore/authserver/Config.java
--- a/src/main/java/org/mmocore/authserver/Config.java    (revision dd4612b907357287d32b8ad77e657eba86253f2e)
+++ b/src/main/java/org/mmocore/authserver/Config.java    (revision e2f6658a4434af74825cd3d27a0deea5b4813c7c)
@@ -76,6 +76,13 @@
     public static boolean TOR_BANNED;
     public static String TOR_BAN_LIST;
     public static long TOR_REFRESH_RATE;
+   
+    public static boolean EXECUTE_SHELL_SCRIPT_ON_LOGIN;
+    public static String SHELL_SCRIPT_ON_LOGIN;
+    public static long SHELL_SCRIPT_ON_LOGIN_TIMEOUT;
+    public static boolean SHELL_SCRIPT_DESTROY_FORCIBLY;
+    public static boolean SHELL_SCRIPT_LOGGING;
+    public static boolean PREVENT_LOGIN_ON_SHELL_SCRIPT_FAIL;
 
     private static ScrambledKeyPair[] _keyPairs;
     private static byte[][] _blowfishKeys;
@@ -261,6 +268,13 @@
         TOR_BANNED = serverSettings.getProperty("TorBanned", false);
         TOR_BAN_LIST = serverSettings.getProperty("TorBanList", "https://www.dan.me.uk/torlist/?exit");
         TOR_REFRESH_RATE = Math.min(1800, serverSettings.getProperty("TorRefreshRate", 1800)) * 1000L; // 1800s minimum
+       
+        EXECUTE_SHELL_SCRIPT_ON_LOGIN = serverSettings.getProperty("ExecuteShellScriptOnLogin", false);
+        SHELL_SCRIPT_ON_LOGIN = serverSettings.getProperty("ShellScriptOnLogin", "sudo ipset -! add gs_whitelist $IP");
+        SHELL_SCRIPT_ON_LOGIN_TIMEOUT = serverSettings.getProperty("ShellScriptOnLoginTimeout", 5000);
+        SHELL_SCRIPT_DESTROY_FORCIBLY = serverSettings.getProperty("ShellScriptDestroyForcibly", false);
+        SHELL_SCRIPT_LOGGING = serverSettings.getProperty("ShellScriptLogging", false);
+        PREVENT_LOGIN_ON_SHELL_SCRIPT_FAIL = serverSettings.getProperty("PreventLoginOnShellScriptFail", false);
 
         GAME_SERVER_PING_DELAY = serverSettings.getProperty("GameServerPingDelay", 30) * 1000L;
         GAME_SERVER_PING_RETRY = serverSettings.getProperty("GameServerPingRetry", 4);
Index: src/main/java/org/mmocore/authserver/network/l2/c2s/RequestAuthLogin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/org/mmocore/authserver/network/l2/c2s/RequestAuthLogin.java b/src/main/java/org/mmocore/authserver/network/l2/c2s/RequestAuthLogin.java
--- a/src/main/java/org/mmocore/authserver/network/l2/c2s/RequestAuthLogin.java    (revision dd4612b907357287d32b8ad77e657eba86253f2e)
+++ b/src/main/java/org/mmocore/authserver/network/l2/c2s/RequestAuthLogin.java    (revision e2f6658a4434af74825cd3d27a0deea5b4813c7c)
@@ -18,7 +18,11 @@
 import org.slf4j.LoggerFactory;
 
 import javax.crypto.Cipher;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.time.LocalDateTime;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Format: b[128]ddddddhc b[128]: the rsa encrypted block with the login an password
@@ -156,6 +160,68 @@
             client.close(LoginFailReason.REASON_ATTEMPTED_RESTRICTED_IP);
             return;
         }
+       
+        if (Config.EXECUTE_SHELL_SCRIPT_ON_LOGIN)
+        {
+            int errCode;
+            try
+            {
+                final Process exec = Runtime.getRuntime().exec(Config.SHELL_SCRIPT_ON_LOGIN.replace("$IP", String.valueOf(client.getIpAddress())).replace("$ACCOUNT", String.valueOf(account.getLogin())));
+                if (!exec.waitFor(Config.SHELL_SCRIPT_ON_LOGIN_TIMEOUT, TimeUnit.MILLISECONDS))
+                {
+                    errCode = -1;
+                }
+               
+                BufferedReader stdInput = null;
+                BufferedReader stdErr = null;
+                if (Config.SHELL_SCRIPT_LOGGING)
+                {
+                    stdInput = new BufferedReader(new InputStreamReader(exec.getInputStream()));
+                    stdErr = new BufferedReader(new InputStreamReader(exec.getErrorStream()));
+                }
+               
+                if (exec.isAlive())
+                {
+                    if (Config.SHELL_SCRIPT_DESTROY_FORCIBLY)
+                    {
+                        exec.destroyForcibly();
+                    }
+                    else
+                    {
+                        exec.destroy();
+                    }
+                }
+               
+                if (Config.SHELL_SCRIPT_LOGGING)
+                {
+                    _log.info("Shell script logging: Started");
+                    if (stdInput != null)
+                    {
+                        stdInput.lines().forEach(line -> _log.info("Shell in: {}", line));
+                        stdInput.close();
+                    }
+                   
+                    if (stdErr != null)
+                    {
+                        stdErr.lines().forEach(line -> _log.info("Shell err: {}", line));
+                        stdErr.close();
+                    }
+                }
+               
+                errCode = exec.exitValue();
+            }
+            catch (NullPointerException | IOException | InterruptedException e)
+            {
+                _log.error("Failed to execute shell script on login for account: " + account + " with client: " + client, e);
+                errCode = -1;
+            }
+           
+            if (Config.PREVENT_LOGIN_ON_SHELL_SCRIPT_FAIL && errCode != 0)
+            {
+                client.close(LoginFailReason.REASON_SYSTEM_ERROR);
+                return;
+            }
+        }
 
         for (GameServer gs : GameServerManager.getInstance().getGameServers())
             if (gs.getProtocol() >= 2 && gs.isAuthed())
 
Также, мы можем блокировать все длинные пакеты к 2106 (логинсерверу). Он не использует длинные пакеты, а часто при ДДОС атакуют через такие длинные пакеты.

Код:
-A LS -m length --length 250:65535 -m set ! --match-set temp_blacklist src -m comment --comment "Block packets greater than this size as LS doesn\'t work with larger packets." -j BLACKLIST_AND_DROP
 
Итак, раз вам интересно.

Надо отметить, что обработка сетевых пакетов является однопоточной. Используется только 1 процессорный поток на сетевой канал.
От получения пакета, до его обработки в IPTables, всё в одном потоке. Новые пакеты ждут пока поток не завершит всю обработку предыдущего пакета.
Из-за этого, чем больше правил в IPTables (точнее, чем они тежелее), тем меньше пакет можно принимать.
Сетевых каналов не так много (часто 1-4, в зависимости от сетевых интерфейсах). Так что, нет значения, что у вас 32 процессорных потока, почти все они не будут использоваться.
Это значит, что вся сетевая нагрузка будет сконцентрирована в этих потоках (можно поискать какие потоки используются для обработки сети через команду "cat /proc/interrupts")
Я долго искал решение этой проблемы, потому что мои ВПС машины использовали только один поток и при ддос остальные потоки ничего не делали. Наконец-то нашёл штуковину под названием RPS.

RPS Configuration (управление получаемых пакетов)

RPS позволяет перераспределить обработку сетевых пакетов между доступными процессорами,
увеличивая пропускную способность и снижая нагрузку на один CPU.
Это достигается путем привязки конкретного IRQ (прерывания) к определенному ядру процессора.
За счет этого удается более эффективно использовать ресурсы системы и распределить нагрузку равномерно.


Опция находится на:
Bash:
/sys/class/net/<interface>/queues/rx-<n>/rps_cpus

Например, если ваш сетевой интерфейс называется "ens3" и поддерживает 2 канала:
Bash:
/sys/class/net/ens3/queues/rx-0/rps_cpus
/sys/class/net/ens3/queues/rx-1/rps_cpus

Проверьте текущее значение (если отключено, то будет "0"):
Bash:
cat /sys/class/net/ens3/queues/rx-0/rps_cpus

Как включить? (нужен root доступ):
2-поточный процессор:
Bash:
echo "3" > /sys/class/net/ens3/queues/rx-0/rps_cpus
4-поточный процессор:
Bash:
echo "f" > /sys/class/net/ens3/queues/rx-0/rps_cpus
8-поточный процессор:
Bash:
echo "ff" > /sys/class/net/ens3/queues/rx-0/rps_cpus
16-поточный процессор:
Bash:
echo "ffff" > /sys/class/net/ens3/queues/rx-0/rps_cpus
16-поточный процессор:
Bash:
echo "ffffffff" > /sys/class/net/ens3/queues/rx-0/rps_cpus

Короче, это шестнадцатеричное значение битового набора, каждый бит - вкл./выкл. соответствующий поток.
Код:
"1" -> "1", "11" -> "3", "1111" -> "F", "11111111" -> "FF", "01" -> "2", "0111" -> "E"

Если у вас есть более 1 сетевого канала, то сделайте то же самое и для остальных.
Если не хотите включать какой-то процессорный поток в обработку пакетов, то пересчитайте значение битового набора
и поставьте его шестнадцатеричное значение.
 
Данный сайт использует cookie. Вы должны принять их для продолжения использования. Узнать больше…