iptables and network namespaces
- Поднимаем виртуалку, в которой будем творить все наши непотребства, с помощью Vagrant.
- Добавляем в
Vagrantfile
следующее содержимое:
VAGRANT_API_VERSION = '2' Vagrant.configure(VAGRANT_API_VERSION) do |conf| conf.vm.box = 'ubuntu/bionic64' end
- запускаем
vagrant up
- Добавляем в
- Подключаемся к виртуалке:
vagrant ssh
- Логинимся под рута в виртуалке:
sudo su -
iptables -L
--- посмотрим текущие настройки файервола- Дропаем output tcp-трафик с 8080-го порта:
iptables -A OUTPUT -p tcp --sport 8080 -j DROP
- Убеждаемся с помощью netcat, что через 8080-й порт траффик действительно не идет
- Поднимаем сервер:
netcat -lk 0.0.0.0 8080
- Пытаемся подключиться с таймаутом:
netcat -w=1 localhost 800
- Поднимаем сервер:
- Удаляем это правило:
iptables -D OUTPUT 1
- (если будет хотя бы 3 студента с ноутбуками) Попробовать заблокировать двух из трёх студентов по подсети, чтобы только один смог подключиться ко мне по tcp
iptables -A INPUT -s subnet/mask -j DROP
- если мы после этого хотим добавить одного из забаненных в whitelist, нужно добавлять правило через
-I
, чтобы оно оказалось раньше BLOCK-а:iptables -I INPUT -s student-ip -j ACCEPT
- Посмотрим список сетевых интерфейсов
ip link
- Создадим два network namespace-а:
ip netns add ns-foo ; ip netns add ns-bar
ip netns list
--- проверим, что они корректно создались
- Убедимся, что в них никаких интерфейсов кроме loopback-а нету
ip netns exec ns-foo ip link
--- запуститьip link
в неймспейсеns-foo
ip -n ns-foo link
--- то же самое
- Добавим виртуальный сетевой пайп
veth
() и соединим им неймспейсы:ip link add name veth-foo type veth peer name veth-bar
--- создаем veth tunnelip link set veth-foo netns ns-foo
--- убираемveth-foo
в неймспейсns-foo
ip link set veth-bar netns ns-bar
--- убираемveth-bar
в неймспейсns-bar
ip -n ns-foo address
--- видим, что интерфейс есть, но он в состоянии DOWN и без IP-адресаip -n ns-foo address add 192.168.16.14/24 dev veth-foo
--- конфигурируем IP-адресveth-foo
ip -n ns-bar address add 192.168.16.88/24 dev veth-bar
--- конфигурируем IP-адресveth-bar
ip -n ns-foo link set veth-foo up
--- включаемveth-foo
ip -n ns-bar link set veth-bar up
--- включаемveth-bar
ip netns exec ns-foo ping 192.168.16.88
--- убеждаемся, что соединение между неймспейсами естьip netns exec ns-foo route
--- видим, чтоveth-foo
подтянулся в качестве дефолтного роута на сеть 192.168.16.0/24
- Подключим хост к неймспейсам через виртуальный бридж:
ip -n ns-foo link del veth-foo
--- удалим наш veth-тунель (второй конец удалится автоматически)ip link add foobar-net-0 type bridge ; ip link set foobar-net-0 up
--- создаем виртуальный бридж- Подключаем оба неймспейса к бриджу через
veth
:
for ns in `echo -e 'foo\nbar'` ; do ip link add name veth-$ns type veth peer name veth-$ns-bridge ip link set veth-$ns netns ns-$ns ip link set veth-$ns-bridge master foobar-net-0 ip -n ns-$ns link set veth-$ns up ip link set veth-$ns-bridge up done
- Присваиваем ip-адреса сетевым интерфейсам:
ip -n ns-foo address add 192.168.16.14/24 dev veth-foo ip -n ns-bar address add 192.168.16.88/24 dev veth-bar ip address add 192.168.16.1/24 dev foobar-net-0
- Проверяем, что теперь с локалхоста можно достучаться внутрь сети:
ping 192.168.16.88
- Сделаем доступ изнутри неймспейсов во внешнюю сеть.
- Настроим в неймспейсе default gateway route через бридж:
ip -n ns-foo route add default via 192.168.16.1
- Настраиваем NAT на хосте, чтобы транслировать трафик изнутри нейсмспейса в сеть
# включаем ip forwarding sysctl -w net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s 192.162.16.1/24 -o eth0 -j MASQUERADE
Пробрасываем порт 8080 изнутри неймспейса в хостовый порт 8888
iptables -t nat -I OUTPUT -p tcp --dport 8888 -o lo -j DNAT --to 192.168.16.14:8080