Защита сервера — критически важный аспект успешного проекта 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 в 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();
}
}
}
Чек-лист безопасности
Проверьте перед запуском:
- ✅ Firewall настроен и активен
- ✅ Fail2ban установлен и работает
- ✅ Guard система интегрирована
- ✅ Серверный античит активирован
- ✅ Packet flood protection включена
- ✅ HWID бан система работает
- ✅ Логирование безопасности настроено
- ✅ Алерты в Telegram/Discord работают
- ✅ SSH на нестандартном порту
- ✅ MySQL доступна только с localhost
- ✅ Регулярные бэкапы базы данных
- ✅ DDoS protection на уровне хостера
Заключение
Защита L2 сервера — это не разовая настройка, а постоянный процесс. Новые читы и методы атак появляются регулярно. Следите за обновлениями Guard систем, анализируйте логи, оперативно реагируйте на подозрительную активность.
Три уровня защиты:
- Сеть — firewall, fail2ban, DDoS protection
- Клиент — Guard система, проверка целостности
- Сервер — античит, валидация действий, мониторинг
Только комплексный подход гарантирует надежную защиту вашего проекта.