У меня проблема с маршрутизацией в CentOS 6.2 (ядро 2.6.32-220)
Вот настройка: один хост находится в моей локальной сети. Он общается с двумя почти идентичными хостами в удаленном месте. Два удаленных хоста находятся во всех тех же сетях, выступая в качестве резервных копий друг для друга.
Я установил два туннеля GRE от локального хоста, по одному на каждый удаленный хост:
ip tunnel add name tunnel1 mode gre local 10.2.1.2 remote 10.2.1.1
ip link set dev tunnel1 up
ip route add 172.16.1.0/24 dev tunnel1 metric 101
ip tunnel add name tunnel2 mode gre local 10.2.1.4 remote 10.2.1.3
ip link set dev tunnel2 up
ip route add 172.16.1.0/24 dev tunnel2 metric 102
Исходящие пакеты маршрутизируются правильно, без проблем. Входящие пакеты странные. Похоже, что какой бы туннель ни имел маршрут с более высокой метрикой (туннель 2 в приведенном выше примере), входящие пакеты будут игнорироваться. Они поступают нормально, и их можно увидеть на локальном компьютере с помощью 'tcpdump -i tunnel2', но они не маршрутизируются должным образом в локальные сети. Их просто сбросили. Я могу переключить две метрики, и туннель 1 отбросит все входящие пакеты. Туннель с более низкой метрикой маршрута будет правильно маршрутизировать пакеты, как входящие, так и исходящие.
Это «работает так, как задумано»? Конечно, я бы хотел, чтобы все пакеты в обоих туннелях пересылались должным образом. Это возможно?
Быстрое обновление: один человек предложил (я не уверен, почему) добавить «ключевые» параметры к командам «ip tunnel». Я пробовал это, как с разными ключами для каждого туннеля, так и с одинаковыми ключами для обоих туннелей, но ни одно испытание не дало результата.
Благодаря списку рассылки netdev у меня есть ответ. Есть функция, о которой я никогда не слышал, она называется «фильтрация обратного пути». Когда эта функция маршрутизации включена, эта функция маршрутизации ядра будет автоматически отбрасывать входящие пакеты, если они прибывают на интерфейс, отличный от интерфейса, который будет использоваться для исходящих пакетов на адрес источника. Он задуман как функция безопасности и используется по умолчанию в большинстве случаев, особенно когда у вас нет тщательной настройки iptables.
CentOS (и предположительно RHEL) по умолчанию включает фильтрацию обратного пути в /etc/sysctl.conf (net.ipv4.conf.default.rp_filter = 1). Я добавил в свой сценарий установки следующие команды:
echo 0 > /proc/sys/net/ipv4/conf/tunnel1/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/tunnel2/rp_filter
Это отключает фильтрацию обратного пути для обоих псевдоинтерфейсов, и теперь все работает.
Обратите внимание, что добавление в sysctl.conf для моих конкретных интерфейсов не сработало бы для меня, поскольку эти интерфейсы создаются «на лету», а sysctl.conf читается только во время загрузки. Конечно, я мог бы изменить значение по умолчанию в sysctl.conf, но я не хотел отключать эту функцию для других моих интерфейсов.