В настоящее время я настроил IPTables на своем сервере для пересылки определенных портов на определенном интерфейсе (venet0: 1) на второй сервер с другим IP. Мой файл конфигурации выглядит так:
# Generated by iptables-save v1.4.12 on Sat Jun 8 08:36:54 2013
*mangle
:PREROUTING ACCEPT [480:39372]
:INPUT ACCEPT [480:39372]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [339:44328]
:POSTROUTING ACCEPT [339:44328]
COMMIT
# Completed on Sat Jun 8 08:36:54 2013
# Generated by iptables-save v1.4.12 on Sat Jun 8 08:36:54 2013
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 51315 -j DNAT --to-destination 76.xxx.xxx.xxx
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 27015:27020 -j DNAT --to-destination 76.xxx.xxx.xxx
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 25565:25570 -j DNAT --to-destination 76.xxx.xxx.xxx
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 7777 -j DNAT --to-destination 76.xxx.xxx.xxx
COMMIT
# Completed on Sat Jun 8 08:36:54 2013
# Generated by iptables-save v1.4.12 on Sat Jun 8 08:36:54 2013
*filter
:INPUT ACCEPT [86:6572]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [66:6912]
-A INPUT -i venet0:1 -j LOG
-A INPUT -i venet0:1 -p tcp -m tcp --dport 51315 -j ACCEPT
-A INPUT -i venet0:1 -p tcp -m tcp --dport 27015:27020 -j ACCEPT
-A INPUT -i venet0:1 -p tcp -m tcp --dport 25565:25570 -j ACCEPT
-A INPUT -i venet0:1 -p tcp -m tcp --dport 7777 -j ACCEPT
COMMIT
# Completed on Sat Jun 8 08:36:54 2013
(IP-адреса скрыты)
Я убедился, что пересылка IPv4 включена, но когда я lsmod
, вообще ничего не появляется.
Я также пробовал использовать modprobe
чтобы добавить модули ядра iptables, но ничего не найдено.
Может быть, модули IPTables просто не установлены, и мне нужно перекомпилировать ядро для их установки?
Когда я пытаюсь подключиться к этим портам, в подключении отказывается, как будто iptables даже не работает.
Я запускаю Ubuntu 12.04 LTS на OpenVZ VPS (имя хоста на самом деле не hostname
).
Linux hostname 2.6.32-042stab076.7 #1 SMP Thu Apr 25 13:35:47 MSK 2013 x86_64 x86_64 x86_64 GNU/Linux
РЕДАКТИРОВАТЬ: ОК, по предложению одного из ответов я изменил venet0:1
к venet0
. Поведение осталось прежним. Tcpdump порта показывает следующее:
23:15:34.940437 IP 76.yyy.yyy.yyy.53802 > 192.xxx.xxx.xxx.51315: Flags [S], seq 3804882566, win 65535, options [mss 1460,nop,wscale 0,nop,nop,sackOK], length 0
23:15:34.940485 IP 76.yyy.yyy.yyy.53802 > 76.xxx.xxx.xxx.51315: Flags [S], seq 3804882566, win 65535, options [mss 1460,nop,wscale 0,nop,nop,sackOK], length 0
В приведенном выше примере 76.yyy.yyy.yyy - это компьютер, который я использую для проверки соединения, 192.xxx.xxx.xxx - это IP-адрес сервера, а 76.xxx.xxx.xxx - это адрес сервера. он должен пересылать. Кажется, что он каким-то образом пересылает трафик, за исключением того, что пакеты имеют нулевую длину и никогда не получают ответа. Я также запустил tcpdump на принимающей машине, и ничего не обнаружилось.
Я убедился, что пересылка IPv4 включена, однако, когда я выполняю lsmod, вообще ничего не появляется.
lsmod
показывать только загруженные модули. Это не имеет ничего общего с iptables
. iptables
автоматически загружает необходимые модули во время вставки правила, и в случае сбоя выдает красивое сообщение об ошибке. Если ваши правила загружены успешно, iptables
работает, и все модули отсутствуют.
Кроме того, вполне нормально иметь lsmod
ничего не показывает: это означает, что функциональность встроена в ядро. так что выход lsmod
здесь совершенно неактуально.
Когда я пытаюсь подключиться к этим портам, в подключении отказывается, как будто iptables даже не работает.
-A PREROUTING -i venet0: 1 -p tcp -m state --state NEW, RELATED, ESTABLISHED -m tcp --dport 51315 -j DNAT --to-destination 76.xxx.xxx.xxx
Проблема здесь скорее всего venet0:1
, которого не существует. iptables
имеет это ограничение, что он принимает любой имя интерфейса, даже несуществующие, или строки, которые даже не выглядят как имя интерфейса (вы можете даже указать IP-адреса, просто для удовольствия, это не сработает). Если нет интерфейса, соответствующего данному имени, правило просто не будет соответствовать. Это полезно, когда ваши сетевые интерфейсы еще не готовы или если ваши сетевые интерфейсы имеют «горячую» замену, но в большинстве случаев не удается проверить, действительно ли существует имя интерфейса. так легко сделать опечатку.
вместо этого используйте:
-A PREROUTING -i venet0 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 51315 -j DNAT --to-destination 76.xxx.xxx.xxx
Теперь вы, вероятно, ответите "но venet0:1
существует, ifconfig
показывает это! ».
Кроме ifconfig
неправильно. Причина ? Linux ifconfig
старый, устаревший, устаревший и отстой. Использовать ip addr
вместо. То же самое для route
, netstat
и brctl
и, возможно, другие. ip
замените их все.
ip addr
не подделывайте и не скрывайте информацию из ядра. Вы видите реальное состояние сетевого стека. Теперь вы видите, что таких venet0:1
интерфейс. Вместо, venet0
имеет несколько IP-адресов. Это то, что поддерживается с момента выхода Linux 2.2.
Но ifconfig
(или фактически BSD API, который он использует для связи с ядром) не поддерживает наличие у интерфейса нескольких IP-адресов. Вместо этого у вас есть старый трюк BSD под названием «псевдонимы интерфейса», где вы можете использовать ifconfig venet0:1
настроить дополнительный IP-адрес для venet0
, и он будет отображаться как venet0:1
интерфейс. Кроме venet0:1
это не интерфейс. Даже не близко.
Фактически, ip addr
покажу вам, что venet0:1
- это метка для IP-адреса, при этом страница руководства сообщает вам:
In order to preserve compatibility with Linux-2.0 net aliases, this string
must coincide with the name of the device or must be prefixed with the
device name followed by colon.
И iptables
страница руководства, используемая для того, чтобы запретить вам использовать псевдонимы интерфейса или что-либо, содержащее двоеточие в нем, но эта строка должна была исчезнуть.
nat
столВы можете прочитать это в страница руководства iptables:
К этой таблице обращаются, когда встречается пакет, который создает новое соединение.
Таким образом, вам не нужно там проверять состояние вашего подключения, поскольку эта таблица проверяется только на NEW
соединения.
OpenVZ это технология «виртуализации», основанная на пространства имен.
По сути, ваша виртуальная машина - это простая папка, в которой создано и содержится системное дерево Linux, чтобы создать иллюзию того, что вы находитесь в действительно независимой системе. Оригинальность этого метода виртуализации в том, что все контейнеры работают один и только один экземпляр ядра Linux, ведущий.
Теперь у вас есть проблема, потому что, поскольку вы не запускаете собственный экземпляр ядра, у вас нет полного контроля, и это многое объясняет.
lsmod
пусто, потому что по соображениям безопасности они не сообщат вам, какие модули работают в системе, и, конечно же, они не позволят вам изменить конфигурацию системы, добавляя новые модули. Представьте, что каждый клиент изменяет одно и то же ядро, на котором работают другие клиенты.
Хотя вы можете разрешить использование iptables для контейнеров, nat
возможно, не было включено.