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

Мануал Создаем несколько зеркал к 1 порту.

  • Автор темы Автор темы Maksim
  • Дата начала Дата начала

Maksim

Вершитель
Проверенный
Опора сообщества
Арбитр
Куратор Данных
Стратег Данных
Медаль Благодарности
Мастер Архивов
Хранитель Пера
Оратор
Авторитет форума
Знаток Lineage2
Уважаемый собеседник
Неукротимое пламя
Старожил I степени
Сообщения
1 611
Розыгрыши
1
Решения
7
Репутация
1 086
Реакции
1 602
Баллы
1 923

Pikachu

Баллов: 10
Спасибо
Да, это точно. Почти весь траффик отфильтровывается на зеркальном сервере, но главному серверу тоже нужно дофильтровывать траффик. И наверное, вести реальную статистику трафика (если вас это интересует). Лучше сделать так, чтобы пакеты приходили с реальным ИП адресом, без этих костылей.
Мне интересно какие решения используються. Я здесь читал что некоторые используют NGINX как простую прокси, ну и которую можно также настроить для передачи реального IP соединения (прокси протокол). У меня также свое решение в виде шифрованной прокси (для ХФ и Интерлюда), которая тоже может передавать реальный IP адрес даже через многие слоя (например если используется ципочка из прокси a не одно прямоe зеркалo). Но я так понимаю что и есть другие варианты?
 
Через GRE Tunnel например. Это как-то сложно для тех, кто не имеет понятия как устанавливаются туннели (мне тоже было очень сложно и сталкивался сo многими проблемами). Я попробую сделать скрипт и поделюсь им здесь.
 
У меня GRE + IPsec уже как пару лет РКН блокирует. Возможно будет полезной инфа дальше локалки может и не заработать. Самое забавное блокирует не тотально сегодня работает, а через пару дней уже нет.
 
У меня GRE + IPsec уже как пару лет РКН блокирует. Возможно будет полезной инфа дальше локалки может и не заработать. Самое забавное блокирует не тотально сегодня работает, а через пару дней уже нет.
На заметку из решений которые не блокируются РКН - кроме GRE есть еще VXLAN. Основная идея в том, чтобы НЕ шифровать трафик в туннеле (трафик и так шифруется протоколом л2), соответственно если туннель НЕ шифрованный - РКН не будет обращать на него внимание, т.к. может парить с нем попытки доступа на запрещенные ресурсы.
 
Вот вам скрипты для установления GRE туннеля. Первый предназначен для геймсервера, второй - для зеркала.

То, что надо заменить:
GS_PRV_IP - замените на ИП адрес геймсервера
PS_PRV_IP - замените на ИП адрес зеркала
GS_PORT - замените на порт геймсервера
TUN_IP_MASK - уникальный ИП адрес туннеля, который вы задаёте. Если у вас есть несколько зеркал, замените на ИП адрес в последовательности, например: 172.16.10, 172.16.11, 172.16.12 и т.д.
TUN_NAME - уникальное имя зеркала, например gre-proxy-us, gre-proxy-eu, gre-proxy-ru и т.д.
TUN_ROUTE_NAME - уникальное имя таблицы маршрутизации. Пусть оно будет похоже на уникальное имя зеркала
IF_NAME - имя сетевого интерфейса, предоставляющего публичный ИП адрес (PS_PRV_IP), проверьте его через команду ip a

Также, нужно подтвердить, что у зеркала включено net.ipv4.ip_forward=1 в /etc/sysctl.conf. Проверяем через команду sysctl -n net.ipv4.ip_forward, если результат 0, то оно выключено и надо включить через команды echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf и sysctl -p.

Если всё хорошо и скрипты сработали, тогда проверяем связь:
Пишем командыping 172.16.10.1 и ping 172.16.10.2 (или TUN_IP_MASK, которое вы задали) в зеркало и геймсервера. Если есть ответ, то туннель работает.

Затем геймсервер привязывается к локальному ИП адресу туннеля (172.16.10.1), но игрокам показывает ИП зеркала. Например, моя конфигурация выглядит следующим образом:
XML:
<gameserver id="3" bindAddress="172.16.10.1" externalAddress="98.125.65.186" bindPort="7777">

Таким образом весь трафик зеркала<->геймсервера проходит через туннель (172.16.10.2 и 172.16.10.1 соответственно), и все пакеты сохраняют реальный ИП адрес игрока. Короче, зеркало превращается в обычный роутер, который у вас в доме.

Bash:
#!/bin/bash

GS_PRV_IP="202.187.6.133" # IP address of the gameserver machine.
PS_PRV_IP="98.125.65.186" # IP address of the proxy machine.
TUN_IP_MASK="172.16.10" # Unique IP address (except the last part) set by you, which will be the IP address of the local network we are creating.
TUN_LOCAL_IP="${TUN_IP_MASK}.1" # Do not change. IP address of the gameserver machine within the tunnel network.
TUN_REMOTE_IP="${TUN_IP_MASK}.2" # Do not change. IP address of the proxy machine within the tunnel network.
TUN_NAME="gre-proxy-us" # Interface name of the tunnel.
TUN_ROUTE_NAME="proxy-us" # name of the routing table.
TUN_ROUTE_PRIO="10" # priority of the routing

echo ""
echo "================================================================================"
echo "This script must be run on the gameserver machine."
echo "================================================================================"
echo ""
echo "Check inside this script's commented sections. There are some prerequisites that must be met. Also run this script as root or sudo."
echo "Gameserver (this machine) private IP for tunneling is set to: $GS_PRV_IP"
echo "Proxy private IP for tunneling is set to: $PS_PRV_IP"
echo "Tunnel local IP (this machine) is set to: $TUN_LOCAL_IP"
echo "Tunnel remote IP (proxy machine) is set to: $TUN_REMOTE_IP"
echo "Tunnel name is set to: $TUN_NAME"

while true
do
    read -r -p 'Do you want to continue? ' choice
    case "$choice" in
      n|N) exit 0;;
      y|Y) break ;;
      *) echo 'Response not valid. Please enter y or n';;
    esac
done

echo ""
echo "Creating the tunnel..."
echo "Creating tunnel interface $TUN_NAME tunneling $GS_PRV_IP -> $PS_PRV_IP"
ip tunnel add $TUN_NAME mode gre remote $PS_PRV_IP local $GS_PRV_IP ttl 255
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Creating tunnel IP $TUN_LOCAL_IP -> $TUN_REMOTE_IP"
ip addr add $TUN_LOCAL_IP peer $TUN_REMOTE_IP dev $TUN_NAME
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Setting tunnel interface up."
ip link set $TUN_NAME up
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Adding the routing table to /etc/iproute2/rt_tables"
echo "${TUN_ROUTE_PRIO} ${TUN_ROUTE_NAME}" >> /etc/iproute2/rt_tables
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Enabling the use of the routing table."
ip route add default via $TUN_REMOTE_IP dev $TUN_NAME src $TUN_LOCAL_IP table $TUN_ROUTE_NAME
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Adding routing rules."
# We need to append "protocol kernel" to the ip rule, so systemd-networkd doesn't decide to automatically
# delete our rule and mess-up the routing :@:@:@:@:@:@:@:@:@
# this screwed us so bad!!!!
# If rule is broken and there is rp_filter=1, the packets coming from the tunnel will be marked as "martian" packets.
ip rule add from $TUN_LOCAL_IP table $TUN_ROUTE_NAME prio $TUN_ROUTE_PRIO proto kernel
if [ $? -ne 0 ]; then
   exit $?
fi

echo ""
# Add those to the networkd configuration, so it doesn't delete our rules!!!
echo "Make the following changes at \"/etc/systemd/networkd.conf\", so systemd doesn't randomly change your rules..."
echo "ManageForeignRoutingPolicyRules=no"
echo "ManageForeignRoutes=no"
echo "service systemd-networkd reload"
echo ""
echo ""
echo "All done."
echo "Time for you to test if the connection is active and working."

Bash:
#!/bin/bash
# Make sure ipv4 ip forwarding is enabled there:
#       echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
# Then reload the config:
#       sysctl -p
#
# Also make sure no such tunnel name exists.
# You can delete existing tunnels by calling:
#       ip link set $TUN_NAME down
#       ip tunnel del $TUN_NAME
#
# Other helpful changes to /etc/sysctl.conf are:
#       net.ipv4.tcp_syncookies=1
#       net.ipv4.conf.default.rp_filter=1
#       net.ipv4.conf.all.rp_filter=1
#
# These variables below must be changed by you:
GS_PORT="7777"
PS_PRV_IP="98.125.65.186" # IP address of proxy machine.
GS_PRV_IP="202.187.6.133" # IP address of gameserver machine.
TUN_IP_MASK="172.16.10" # Unique IP address (except the last part) set by you, which will be the IP address of the local network we are creating.
TUN_IP_REMOTE="${TUN_IP_MASK}.1" # Do not change. IP address of the gameserver machine within the tunnel network.
TUN_IP_LOCAL="${TUN_IP_MASK}.2" # Do not change. IP address of the proxy machine within the tunnel network.
TUN_NAME="gre-main-gs" # Interface name of the tunnel.
IF_NAME="ens3" # Interface name of the network card from which the traffic comes. Usually it is the interface name, which provides the PS_PRV_IP, check via "ip a" command.

echo ""
echo "================================================================================"
echo "This script must be run on the proxy machine."
echo "================================================================================"
echo ""
echo "Check inside this script's commented sections. There are some prerequisites that must be met. Also run this script as root or sudo."
echo "Gameserver port is set to: $GS_PORT"
echo "Gameserver private IP for tunneling is set to: $GS_PRV_IP"
echo "Proxy (this proxy) private IP for tunneling is set to: $PS_PRV_IP"
echo "Tunnel remote IP (main machine) is set to: $TUN_IP_REMOTE"
echo "Tunnel local IP (this proxy) is set to: $TUN_IP_LOCAL"
echo "Tunnel name is set to: $TUN_NAME"
echo "Interface name (public one from where people connect to this proxy, check |ip link show| or |ip addr show|) is set to: $IF_NAME"

while true
do
    read -r -p 'Do you want to continue? ' choice
    case "$choice" in
      n|N) exit 0;;
      y|Y) break ;;
      *) echo 'Response not valid. Please enter y or n';;
    esac
done

# Create the gre tunnel:
echo "Checking if ip_forward is enabled"
if [ $(sysctl -n net.ipv4.ip_forward) -eq 0 ]; then
   while true
   do
       read -r -p 'IP forwarding is disabled. Would you like to enable it? ' choice
       case "$choice" in
         n|N) exit 0;;
         y|Y) break ;;
         *) echo 'Response not valid. Please enter y or n';;
       esac
   done

   echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
   if [ $? -ne 0 ]; then
      echo "Failed to enable ip_forward. You need to manually open '/etc/sysctl.conf' and place 'net.ipv4.ip_forward=1' at the end of the file. Then reload the changes by executing 'sysctl -p'"
      exit $?
   fi

   sysctl -p
   if [ $? -ne 0 ]; then
      echo "Failed to execute: sysctl -p"
      exit $?
   fi
fi

# Create the gre tunnel:
echo ""
echo "Creating the tunnel..."
echo "Creating tunnel interface $TUN_NAME tunneling $PS_PRV_IP -> $GS_PRV_IP"
ip tunnel add $TUN_NAME mode gre local $PS_PRV_IP remote $GS_PRV_IP ttl 255
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Creating tunnel IP $TUN_IP_LOCAL -> $TUN_IP_REMOTE"
ip addr add $TUN_IP_LOCAL peer $TUN_IP_REMOTE dev $TUN_NAME
if [ $? -ne 0 ]; then
   exit $?
fi

echo "Setting tunnel interface up."
ip link set $TUN_NAME up
if [ $? -ne 0 ]; then
   exit $?
fi

# Add the firewall rules. Make sure we setup the routing rule.
# We use -I (insert) mode instead of -A (append) mode for GRE protocol because of some weird firewall configurations we might encounter that prevent us from connecting to gre tunnel.
echo ""
echo "Adding firewall rules..."
echo "Setting the routing rule for port $GS_PORT to be routed to $TUN_IP_REMOTE"
iptables -A PREROUTING -t nat -i $IF_NAME -p tcp -m tcp --dport $GS_PORT -j DNAT --to-destination ${TUN_IP_REMOTE}:${GS_PORT}
if [ $? -ne 0 ]; then
   exit $?
fi

# Make sure GRE tunnel is not blocked by firewall
echo "Opening gre protocol for IP $GS_PRV_IP"
iptables -I INPUT -s ${GS_PRV_IP}/32 -p gre -j ACCEPT
if [ $? -ne 0 ]; then
   exit $?
fi

echo ""
echo "All done."
echo "Check your ip links (type: ip link show) to verify the tunnel has been created."
echo "Check your tunnel ips (type: ip addr show) to verify the correct tunnel IPs have been set."
echo "Check your firewall rules to make sure they are not conflicting with each other (gre protocol is allowed for ip $GS_PRV_IP and port $GS_PORT is being routed to $TUN_IP_REMOTE)"
echo ""
echo "Next, test your traffic through the GRE tunnel:"
echo "       tcpdump -i $IF_NAME"
echo "This will show you if this proxy is configured properly to accept traffic through the GRE tunnel from the remote server."
echo "You will need to type the same command on the remote server (but change the interface name to correspond to the name there, because they might not be the same) to check if traffic is coming and going in both ways."
echo "To generate traffic, the easiest way is to try and enter a ssh session through the tunnel ip. Which is $TUN_IP_REMOTE when testing from this machine to remote machine and $TUN_IP_LOCAL when testing from remote machine to this machine."
echo "If ssh ports are opened for those IPs, you should be able to connect to a ssh session from both sides."
echo ""
echo "Finally test that the proxy is working:"
echo "Execute this at the gameserver machine to listen for incoming traffic on the gameserver port:"
echo "       netcat -l $TUN_IP_REMOTE $GS_PORT"
echo "Then go to a machine outside of this network (machine that is neither the proxy or the gameserver one) and try to connect to the proxy's public IP which should be routing traffic."
echo "       telnet PROXY.PUBLIC.IP.HERE $GS_PORT"
echo "This should establish a connection that is being proxied through this proxy machine towards the gameserver. Whatever you type in the telnet should appear on the gameserver machine and whatever you type on the netcat should appear on the outside machine."
 
Последнее редактирование:
Maksim добавил(а) новый ресурс:

Создаем несколько зеркал к 1 порту. - Краткая инструкция и с новым годом.



Узнать больше об этом ресурсе...
я очень давно так делал в итоге были лаги на бурстах пакетов в масс пвп и прочих моментах при скоплении игроков
в итоге лучше все же использовать haproxy с ним у меня подобных проблем никогда не было, за одно можно будет и реальный ип конекта передавать и различные правила пер конект или пер ип настроить
 
я очень давно так делал в итоге были лаги на бурстах пакетов в масс пвп и прочих моментах при скоплении игроков
в итоге лучше все же использовать haproxy с ним у меня подобных проблем никогда не было, за одно можно будет и реальный ип конекта передавать и различные правила пер конект или пер ип настроить
очень странно. nat работает на уровне модуля ядра, а haproxy в userspace, соот-но nat должен наоборот значительно быстрее всё это отрабатывать
 
Теоретически это правильный делать через балансировщик, а основной сервис разворачивать локально и подцеплять через обратный прокси, как бекенд. Iptables лучше не использовать, т.к. не для этих задач он. Лучше haproxy ну или на крайняк nginx
 
Вот вам небольшой фильтр для зеркала. Сначала необходимо загрузить ipset.rules, а затем iptables.rule. Если правила ipset отсутствуют, то iptables.rules не загрузится.

Для допольнительной защиты через "gs_whitelist", проверьте скрипт здесь: https://mmo-dev.info/threads/Настройка-iptables.34674/post-270654

Файл iptables.rules (загружаете через iptables-restore < iptables.rules)
Замените ens3 на имя главного сетевого интерфейса (проверьте через ip a).
172.16.10.1 на ИП геймсервера в тунеле
7777 на порт геймсервера
Bash:
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !!! Keep in mind that reloading the firewall will not reload
# !!! the hashlimit settings. You need to change their name
# !!! otherwise it will re-use the old hashlimit.
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -m set --match-set whitelists src -j ACCEPT
-A PREROUTING -m set --match-set blacklists src -j DROP
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -i ens3 -p tcp -m tcp --dport 7777 -j DNAT --to-destination 172.16.10.1:7777
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:GS_FWD - [0:0]
-N BLACKLIST_AND_DROP
-A BLACKLIST_AND_DROP -j SET --add-set temp_blacklist src

# !!! For debugging purposes only. It adds a lot of overhead and will not hold through a ddos.
# -A BLACKLIST_AND_DROP -j LOG --log-prefix "FILTER:BLACKLIST_AND_DROP:" --log-level 4

-A BLACKLIST_AND_DROP -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m set --match-set whitelists src -j ACCEPT
-A FORWARD -i ens3 -p tcp -m tcp --dport 7777 -j GS_FWD
-A FORWARD -m conntrack --ctstate ESTABLISHED -j ACCEPT

# !!! Uncomment if you want to enable protection for packet spam to gameserver. It adds overhead, so it might be better to keep this disabled.
# -A GS_FWD -m hashlimit --hashlimit-above 100/sec --hashlimit-burst 200 --hashlimit-mode srcip --hashlimit-name gs_pps_limit --hashlimit-htable-gcinterval 60000 --hashlimit-htable-size 65535 --hashlimit-htable-max 1048576 -j BLACKLIST_AND_DROP

-A GS_FWD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# !!! Uncomment only if you have a way to validate IPs logging in. You must have a script running on your loginserver, which executes a shell command
# !!! that adds the IP address of the player logging in to the "gs_whitelist" ipset of this proxy machine.
# !!! Only one of the both rules should be uncommented.
# !!! The first rule allows only IPs from "gs_whitelist", while the second rule allows few unauthorized connections as well.
# !!! The first rule is way more secure, but the second rule allows for more accessibility, if you experience issues.
# -A GS_FWD -m set ! --match-set gs_whitelist src -m comment --comment "Allow only valid connections." -j DROP
# -A GS_FWD -m set ! --match-set gs_whitelist src -m hashlimit --hashlimit-above 3/min --hashlimit-burst 15 --hashlimit-name gameserver_new_conn -m comment --comment "Allow all valid and only up to 3 new non-valid connection per minute" -j DROP

# A general filter for IPs spamming too many connections to the gameserver.
# If an IP makes more than 10 connections above the 3/minute rate, then his IP gets temporarily blacklisted.
# You may make this rule stricter (hashlimit-burst 5 for example) in case of ddos,
# or looser (hashlimit-above 6/minute) for example if valid people get blacklisted often.
-A GS_FWD -m hashlimit --hashlimit-above 3/minute --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-name gs_conn_limit --hashlimit-htable-gcinterval 60000 --hashlimit-htable-size 65535 --hashlimit-htable-max 1048576 -m comment --comment "Temporarily ban valid IPs if they spam too many connections to gameserver." -j BLACKLIST_AND_DROP
-A GS_FWD -j ACCEPT
COMMIT

ipset.rules (загружаете через ipset restore < ipset.rules). Если модуль отсутствует, установите его через apt install ipset
Не забудьте заменить ИП адресов из списка на свои:
172.16.10.0 на ваше ИП тунеля
98.125.65.186 на ИП зеркала
202.187.6.133 на ИП геймсервера
144.182.33.51 на ваш ИП через который подключаетесь к зеркалу (иначе доступ будет запрещён).
Код:
#-------------------------------------------------------------------------------------------------------------------------------------------
# For some reason, the temp_blacklist gets overwhelmed during DDOS and cannot add IPs quickly enough
# This is why it's a good practice to move ips from temp_blacklist to blacklist and then
# do "ipset flush temp_blacklist" so it can add new entries quickly enough to capture more IPs.
# Use this command to do that:
#    sudo ipset save temp_blacklist | awk '{ print "add blacklist " $3}' >> ddos_ipsclear.rules && grep -v "hash:ip" ddos_ipsclear.rules |sort |uniq > ddos_ipsclear_uniq.rules && sudo ipset restore -! < ddos_ipsclear_uniq.rules && sudo ipset list blacklist | wc -l
#
#-------------------------------------------------------------------------------------------------------------------------------------------
create temp_blacklist hash:ip family inet hashsize 262144 maxelem 524288 bucketsize 2 timeout 1800
create blacklist hash:net family inet hashsize 262144 maxelem 524288
create gs_whitelist hash:ip family inet hashsize 1024 maxelem 1024 timeout 30
create temp_whitelist hash:ip family inet hashsize 1024 maxelem 1024 timeout 86400 comment
create whitelist hash:net family inet hashsize 1024 maxelem 1024 comment
create blacklists list:set size 8
create whitelists list:set size 8
add blacklists blacklist
add blacklists temp_blacklist
add whitelists whitelist
add whitelists temp_whitelist
add whitelist 172.16.10.0/24 comment "Allow local tunnels."
add whitelist 98.125.65.186 comment "This machine's IP"
add whitelist 202.187.6.133 comment "Gameserver machine's IP"
add whitelist 144.182.33.51 comment "My private IP"
add whitelist 182.43.165.11 comment "My other private IP"
 
Назад
Сверху Снизу