Назад к блогу

Защита L2 сервера от DDoS атак и ботов

Защита сервера — критически важный аспект успешного проекта Lineage 2. DDoS атаки, боты и читеры могут уничтожить даже самый качественный сервер за считанные дни. В этой статье рассмотрим многоуровневую систему защиты, которая надежно оградит ваш проект от большинства угроз.

Защита на уровне сети

Первая линия обороны — правильная настройка сетевого уровня. Большинство атак можно остановить еще до того, как они достигнут игрового сервера.

Настройка Firewall (iptables)

Базовая защита через iptables — must have для любого L2 сервера:

#!/bin/bash
# Основные правила защиты L2 сервера

# Очистка существующих правил
iptables -F
iptables -X

# Политики по умолчанию
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Разрешаем localhost
iptables -A INPUT -i lo -j ACCEPT

# Разрешаем установленные соединения
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Защита от SYN flood
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT

# Защита от ping flood
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT

# L2 порты (login + game server)
iptables -A INPUT -p tcp --dport 2106 -j ACCEPT
iptables -A INPUT -p tcp --dport 7777 -j ACCEPT

# SSH (измените порт!)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# MySQL только с локалхоста
iptables -A INPUT -p tcp --dport 3306 -s 127.0.0.1 -j ACCEPT

# Защита от port scanning
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# Сохранение правил
iptables-save > /etc/iptables/rules.v4
Важно: Перед применением правил убедитесь, что у вас есть альтернативный доступ к серверу! Неправильная настройка может заблокировать вас навсегда.

Fail2ban — автоматический бан атакующих

Fail2ban автоматически блокирует IP с подозрительной активностью:

# Установка
apt-get install fail2ban

# Конфигурация для L2
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = 22

[l2-login]
enabled = true
port = 2106
filter = l2-login
logpath = /path/to/l2server/log/login.log
maxretry = 3

[l2-game]
enabled = true
port = 7777
filter = l2-game
logpath = /path/to/l2server/log/game.log
maxretry = 5
EOF

# Перезапуск
systemctl restart fail2ban

Guard системы для L2

Специализированные Guard системы — необходимость для серьезных проектов. Они проверяют целостность клиента и блокируют читы на уровне клиент-сервер взаимодействия.

Популярные Guard решения

1. Super-Guard

  • ✅ Защита от большинства известных ботов
  • ✅ Проверка целостности клиента
  • ✅ Защита от packet injection
  • ✅ Регулярные обновления под новые читы
  • ❌ Платная лицензия (стоит своих денег)

2. Active Anticheat

  • ✅ HWID бан
  • ✅ Защита от L2Walker, Adrenaline
  • ✅ Мониторинг процессов в реальном времени
  • ✅ Хорошая техподдержка

3. Smart Guard

  • ✅ Легкая интеграция
  • ✅ Низкая нагрузка на клиент
  • ⚠️ Требует модификации клиента
Совет: Не полагайтесь только на Guard. Используйте многоуровневую защиту: Guard + серверный античит + мониторинг логов + GM контроль.

Интеграция Guard

Типичная интеграция Guard в L2J:

// Config.properties
# Guard settings
EnableGuard = True
GuardCheckInterval = 30000
GuardKickDelay = 5000
GuardBanOnFail = True

// В коде сервера
public class GuardManager {
    public void checkPlayer(L2PcInstance player) {
        if (!Config.ENABLE_GUARD) return;
        
        // Отправка guard пакета
        player.sendPacket(new GuardCheckPacket());
        
        // Ожидание ответа
        scheduleCheck(player);
    }
    
    private void scheduleCheck(L2PcInstance player) {
        ThreadPoolManager.schedule(() -> {
            if (!player.isGuardVerified()) {
                handleGuardFail(player);
            }
        }, Config.GUARD_KICK_DELAY);
    }
    
    private void handleGuardFail(L2PcInstance player) {
        if (Config.GUARD_BAN_ON_FAIL) {
            BanManager.addBan(player.getClient().getHWID(), 
                "Guard verification failed");
        }
        player.logout(true);
    }
}

Серверный античит

Guard защищает клиент, но серверная логика тоже критична. Многие читы работают на стороне сервера без модификации клиента.

Проверка скорости движения

public class MovementValidator {
    private static final int MAX_SPEED = 300;
    private static final int CHECK_INTERVAL = 1000;
    
    public boolean validateMovement(L2PcInstance player, 
                                    Location from, Location to) {
        double distance = from.distance(to);
        long timeDiff = System.currentTimeMillis() - 
                       player.getLastMoveTime();
        
        if (timeDiff < 100) return false; // Слишком частые пакеты
        
        double speed = (distance / timeDiff) * 1000;
        int maxSpeed = player.getRunSpeed() + 50; // Погрешность
        
        if (speed > maxSpeed) {
            player.addWarning("Speed hack suspected: " + speed);
            
            if (player.getWarnings() > 3) {
                player.setIsParalyzed(true);
                announceToGMs(player, "Speed hack detected!");
                return false;
            }
        }
        
        player.setLastMoveTime(System.currentTimeMillis());
        return true;
    }
}

Проверка действий (Action Validator)

public class ActionValidator {
    // Проверка времени каста
    public boolean validateCastTime(L2PcInstance player, 
                                    L2Skill skill) {
        long expectedCastTime = skill.getHitTime();
        long actualCastTime = System.currentTimeMillis() - 
                             player.getCastStartTime();
        
        // Разрешаем погрешность 500ms
        if (actualCastTime < (expectedCastTime - 500)) {
            player.addWarning("Fast cast detected");
            return false;
        }
        return true;
    }
    
    // Проверка количества действий в секунду
    public boolean checkActionFlood(L2PcInstance player) {
        int actionsPerSecond = player.getActionsInLastSecond();
        
        if (actionsPerSecond > 10) {
            player.sendMessage("You're acting too fast!");
            return false;
        }
        return true;
    }
    
    // Проверка дистанции атаки
    public boolean validateAttackRange(L2PcInstance player, 
                                       L2Character target) {
        int maxRange = player.getPhysicalAttackRange() + 50;
        double distance = player.distance(target);
        
        if (distance > maxRange) {
            player.addWarning("Attack range exceeded");
            return false;
        }
        return true;
    }
}

Защита от packet flood

Пакетный флуд может положить сервер быстрее, чем DDoS. Защищайтесь правильно:

public class PacketFloodProtector {
    private static final int MAX_PACKETS_PER_SECOND = 100;
    private final Map counters = 
        new ConcurrentHashMap<>();
    
    public boolean checkFlood(L2GameClient client, 
                              L2GameClientPacket packet) {
        String key = client.getAccountName();
        PacketCounter counter = counters.computeIfAbsent(key, 
            k -> new PacketCounter());
        
        counter.increment();
        
        if (counter.getCount() > MAX_PACKETS_PER_SECOND) {
            LOG.warning("Packet flood from: " + key);
            
            // Жесткий лимит
            if (counter.getCount() > MAX_PACKETS_PER_SECOND * 2) {
                client.close(new LeaveWorld());
                BanManager.addBan(client.getHWID(), 
                    "Packet flood attack");
                return false;
            }
            
            // Мягкий лимит - просто дропаем пакет
            return false;
        }
        
        return true;
    }
    
    // Сброс счетчиков каждую секунду
    public void resetCounters() {
        counters.values().forEach(PacketCounter::reset);
    }
}

Мониторинг и логирование

Невозможно защитить то, что не видишь. Настройте правильный мониторинг:

Что логировать

# security.log формат
[2026-01-15 14:23:15] [WARN] Player "Cheater123" speed hack detected (speed: 450)
[2026-01-15 14:23:16] [BAN] Player "Cheater123" auto-banned (reason: Speed hack)
[2026-01-15 14:25:00] [ALERT] DDoS suspected: 1000 connections from 45.67.89.0/24
[2026-01-15 14:30:12] [INFO] Guard check failed: Player "Bot001" (HWID: xxx)

Автоматические алерты

public class SecurityMonitor {
    private static final int ALERT_THRESHOLD = 10;
    
    public void checkForThreats() {
        // Проверка подозрительной активности
        int suspiciousPlayers = getSuspiciousPlayersCount();
        
        if (suspiciousPlayers > ALERT_THRESHOLD) {
            alertAdmins("High suspicious activity detected: " + 
                       suspiciousPlayers + " players");
            
            // Отправка в Telegram/Discord
            sendWebhook("⚠️ Security Alert", 
                       "Suspicious activity spike detected!");
        }
    }
    
    private void sendWebhook(String title, String message) {
        // Discord Webhook
        String url = Config.DISCORD_WEBHOOK_URL;
        JSONObject json = new JSONObject()
            .put("content", "**" + title + "**\n" + message);
        
        // Отправка (используйте HTTP client)
        HttpUtils.post(url, json.toString());
    }
}

HWID бан — эффективное оружие

Простые IP баны легко обходятся. HWID (Hardware ID) бан гораздо эффективнее:

public class HWIDBanManager {
    public void banPlayer(L2PcInstance player, String reason) {
        String hwid = player.getClient().getHWID();
        
        if (hwid != null && !hwid.isEmpty()) {
            // Бан в базе
            Connection con = L2Database.getConnection();
            PreparedStatement ps = con.prepareStatement(
                "INSERT INTO hwid_bans (hwid, reason, date) VALUES (?, ?, NOW())");
            ps.setString(1, hwid);
            ps.setString(2, reason);
            ps.execute();
            
            // Кик всех с этим HWID
            for (L2PcInstance p : L2World.getAllPlayers()) {
                if (hwid.equals(p.getClient().getHWID())) {
                    p.logout(true);
                }
            }
            
            LOG.info("HWID banned: " + hwid + " (reason: " + reason + ")");
        }
    }
    
    public boolean isHWIDBanned(String hwid) {
        // Проверка при логине
        try (Connection con = L2Database.getConnection()) {
            PreparedStatement ps = con.prepareStatement(
                "SELECT 1 FROM hwid_bans WHERE hwid = ?");
            ps.setString(1, hwid);
            ResultSet rs = ps.executeQuery();
            return rs.next();
        }
    }
}
Внимание: HWID можно подделать опытным читером. Используйте в связке с другими методами защиты.

Чек-лист безопасности

Проверьте перед запуском:

  • ✅ Firewall настроен и активен
  • ✅ Fail2ban установлен и работает
  • ✅ Guard система интегрирована
  • ✅ Серверный античит активирован
  • ✅ Packet flood protection включена
  • ✅ HWID бан система работает
  • ✅ Логирование безопасности настроено
  • ✅ Алерты в Telegram/Discord работают
  • ✅ SSH на нестандартном порту
  • ✅ MySQL доступна только с localhost
  • ✅ Регулярные бэкапы базы данных
  • ✅ DDoS protection на уровне хостера

Заключение

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

Три уровня защиты:

  1. Сеть — firewall, fail2ban, DDoS protection
  2. Клиент — Guard система, проверка целостности
  3. Сервер — античит, валидация действий, мониторинг

Только комплексный подход гарантирует надежную защиту вашего проекта.

Нужна помощь с защитой сервера? Мы предоставляем услуги по интеграции Guard систем и настройке защиты. Свяжитесь с нами для консультации.