-`filter` - основная таблица для фильтрации пакетов, используется по умолчанию;
-`nat` - управление преобразованием сетевых адресов;
-`mangle` - модификация и замена содержимого сетевых пакетов вне контекста NAT и фильтрации пакетов;
-`raw` - предназначена для работы с сырыми пакетами, пока они еще не прошли обработку
## Цепочки
Цепочки бывают базовые/встроенные и пользовательские (можно создать самому).
В новую цепочку можно направлять пакеты чтобы подвергуть их анализу правил. Например для отладки правил или настройки особого движения пакетов как это сделано в Docker
-`FORWARD` - транзитный трафик поступающий на локальную машину с целью передачи его на другую машину (трафик передаваемый в docker контейнер тоже будет считаться транзитным), при этом транзитный трафик проходит в обоих направлениях;
-`OUTPUT` - исходящий из локального хоста трафик
## Правила - условия и действия
Правило - состоит из условия/критерия (если нет значит применяется ко всему трафику) действия (может не быть) и счетчика (для учета пакетов попавших под правило).
-`-s` - ip адрес источника (можно с маской 10.0.0.0/24), допускается отрицание (т.е. все кроме) `-s ! 10.0.0.0/24`;
-`-d` - ip адрес получателя (аналогично `-s`);
-`-i` - интерфейс с которого пришел пакет (только для `INPUT`, `FORWARD`, `PREROUTING`), например `ens3`, допускается указать `ens+` что означает все имена интерфейсов начинающиеся с заданной строки, допускается отрицание `-i ! ens+`;
-`-o` - интерфейс локального хоста, из которого выходит трафик (только для `OUTPUT`, `FORWARD`, `PREROUTING`);
-`--sport` - порт с которого был отправлен TCP/UDP пакет (допускаются имена служб из `/etc/services`), поддерживаются диапазоны вида `20:80` что значит от 20 до 80 порта, так же можно опустить одно из значений `:80` (от 0 до 80) или `20:` (от 20 до 65535), отрицание поддерживается даже к диапазонам `--sport ! 20:80`;
-`--dport` - аналогично `--sport` только речь идет про порт, которому адресован пакет;
-`--icmp-type` - тип ICMP сообщения (номер или название), поддерживается отрицание. RFC 792 или `iptables --protocol icmp --help`;
-`-m mac --mac-source` - MAC адрес устройства передавшего пакет, поддерживается отрицание;
-`-m state --state` - состояние соединения:
-`INVALID` - неизвестное соединение, возможно ошибочное;
-`NEW` - новое соединение;
-`ESTABLISHED` - уже установленное соединение;
-`RELATED` - пакет принадлежит уже существующему соединению, но он отправляется по новому
-`DROP` - пакет сбрасывается и перестает движение в системе;
-`LOG` - пакет журналируется и продолжает дальнейшие движение по цепочке правил и таблицам (рассмотрим ниже)
-`REJECT` - аналогично DROP только отдает сообщение об ошибке на хост отправителя (работает на всех цепочках таблицы filter):
-`--reject-with` - тип ответа, RFC 793 или `iptables -j REJECT -h`
-`RETURN` - возврат пакета в вышестоящую цепочку для применения действия по умолчанию, при отсутствии вышестоящей цепочки применится действие по умолчанию
**Стоит иметь ввиду, что очистка правил не изменяет правило по-умолчанию, если оно установлено в DROP, после очистки всех правил можно потерять доступ к узлу.**
- Для полной очистки правил и отключения фильтрации
```bash
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
```
## Управление правилами и цепочками
Добавить правило (разрешить весь трафик с tun интерфейсов) в конец цепочки INPUT (-A, --append):
```bash
iptables -A INPUT -i tun+ -j ACCEPT
```
Вставить правило в позицию 2 цепочки INPUT (-I, --insert):
```bash
iptables -I INPUT 2 -i lo -j ACCEPT
```
Установить политику по умолчанию DROP для цепочки INPUT (-P, --policy):
```bash
iptables -P INPUT DROP
```
Создание новой цепочки правил:
```bash
iptables -N LOGGING
```
## Примеры
Предположим что для цепочки `INPUT` политика по умолчанию `DROP`, это значит что все входящие пакеты будут отброшены, но нам нужен некоторый входящий трафик.
Разрешим трафик на локальный DNS сервер, без этого могут быть долгие подключения по ssh:
Разрешим движение трафика из интерфейсов создаваемых Docker (при политиках по умолчанию `DROP`, контейнеры не смогут общаться с другими интерфейсами):
```bash
iptables -A INPUT -i br+ -j ACCEPT
```
Разрешим любой входящий трафик из `localhost` и откроем `http/https` порты (80/443), например для случая когда у нас есть веб-сервер и наши сайты должны быть доступны снаружи:
```bash
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
```
*Если не разрешить входящий трафик от `localhost` то могут быть странные задержки с ответами, а при дебаге можно увидеть отклоенные пакеты от 127.0.0.1*
Теперь локальный DNS на 53 порту доступен, docker контейнеры тоже, с localhost трафик разрешен, и для внешнего мира открыты 80 и 443 порты для наших сайтов. Но это все только для установления соединения и рукопожатия. Теперь нам нужно разрешить все установленные и связанные с ними соединения чтобы трафик действительно пошел (еще вот):
```bash
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
```
### Пример первоначальной настройки
```bash
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT