## Часть 1. Настройка межсетвеого экрана в Linux-системах
### Цель работы
Получить практические навыки настройки межсетевого экрана (фаервола), а также настройки переадресации сетевых соединений и трансляции адресов (NAT).
### 1. Теоретическая часть
**Брандмауэр** - это система или группа систем, реализующих правила управления доступом между двумя сетями. Фактические средства, с помощью которых это достигается, весьма различны, но в принципе брандмауэр можно рассматривать как пару механизмов: один для блокирования передачи информации, а другой, - для пропуска информации. Некоторые брандмауэры уделяют больше внимания блокировке передачи информации, другие - ее пропуску. Важно понимать, что конфигурация брандмауэра, как механизма обеспечения выполнения определенных правил, определяет правила для всех систем, которые он защищает.
### 1.1 Работа *IPTABLES*. Основные понятия
При описании выполняемых команд приняты следующие обозначения:
- `#` - если перед командой стоит данный знак, это означает, что команда должна выполняться от имени пользователя root (суперпользователь)
- `$` - если перед командой стоит данный знак, это означает, что команда должна выполняться от имени обычного пользователя.
Обработка пакетов осуществляется согласно определенным правилам. Каждое правило - это строка, содержащая в себе критерии определяющие, подпадает ли пакет под заданное правило, и действие, которое необходимо выполнить в случае выполнения критерия. В общем виде правила задаются в командной строке так:
Если в правило не включается спецификатор [-t table], то по умолчанию предполагается использование таблицы filter, если же предполагается использование другой таблицы, то это требуется указать явно. Спецификатор таблицы так же можно указывать в любом месте строки правила, однако более или менее стандартом считается указание таблицы в начале правила. Можно использовать следующие таблицы:
- Таблица **nat** используется главным образом для преобразования сетевых адресов (*Network Address Translation*). Через эту таблицу проходит только первый пакет из потока. Преобразования адресов автоматически применяется ко всем последующим пакетам;
- Таблица **mangle** используется для внесения изменений в заголовки пакетов. Примером может служить изменение поля `TTL`, `TOS` или `MARK`;
- Таблица **filter** используется главным образом для фильтрации пакетов. Для примера, здесь мы можем выполнить `DROP`, `LOG`, `ACCEPT` или `REJECT` без каких либо ограничений, которые имеются в других таблицах;
Далее, непосредственно за именем таблицы, должна стоять команда. Если спецификатора таблицы нет, то команда всегда должна стоять первой. Команда определяет действие **iptables**, например: вставить правило, или добавить правило в конец цепочки, или удалить правило и т.п. Ниже перечислены команды **iptables**:
- `-A`, `--append` - добавление нового правила в конец заданной цепочки;
- `-D`, `--delete` - удаление правила из цепочки. Команда имеет два формата записи, первый - когда задается критерий сравнения с опцией -D, второй - порядковый номер правила;
- `-R`, `--replace` - замена одного правила другим;
- `-I`, `--insert` - вставка нового правила в цепочку. Число, следующее за именем цепочки, задает номер для вставляемого правила;
- `-L`, `--list` - вывод списка правил в заданной цепочке. Если имя цепочки не указывается, то выводится список правил для всех цепочек;
- `-F`, `--flush` - сброс (удаление) всех правил из заданной цепочки (таблицы). Если имя цепочки и таблицы не указывается, то удаляются все правила, во всех цепочках;
- `-Z`, `--zero` - обнуление всех счетчиков в заданной цепочке. Если имя цепочки не указывается, то подразумеваются все цепочки;
- `-N`, `--new-chain` - создание новой цепочки с заданным именем в заданной таблице;
- `-X`, `--delete-chain` - удаление заданной цепочки из заданной таблицы. Удаляемая цепочка не должна иметь правил, а также ссылок на нее из других цепочек. Если имя цепочки не указано, то будут удалены все цепочки заданной таблицы кроме встроенных;
- `-P`, `--policy` - определение политики «по-умолчанию» для заданной цепочки. Политика «по-умолчанию» определяет действие, применяемое к пакетам, не попавшим под действие ни одного из правил в цепочке;
Раздел **match** задает критерии проверки, по которым определяется подпадает ли пакет под действие этого правила или нет. Здесь мы можем указать самые разные критерии - IP-адрес источника пакета или сети, IP-адрес места назначения, порт, протокол, сетевой интерфейс и т.д. Рассмотрим общие критерии. Общие критерии допустимо употреблять в любых правилах, они не зависят от типа протокола и не требуют подгрузки модулей расширения.
- `-p`, `--protocol` - тип протокола. Примерами протоколов могут быть `TCP`, `UDP` и `ICMP` (список протоколов можно посмотреть в файле */etc/protocols*), а также ключевое слово `ALL`;
- `-s`, `-src`, `--source` - IP-адрес(а) источника пакета. Может указываться как единственный IP-адрес, так и в виде address/mask, например как `192.168.0.0/255.255.255.0`,или `192.168.0.0/24`. Символ `!`, установленный перед адресом, означает логическое отрицание;
- `-d`, `-dst`, `--destination` - IP-адрес(а) получателя. Имеет синтаксис схожий с критерием `-source`;
- `-i`, `--in-interface` - интерфейс, с которого получен пакет. При отсутствии этого критерия предполагается любой интерфейс;
- `-o`, `--out-interface` - имя выходного интерфейса. Критерий допускается использовать только в цепочках OUTPUT, FORWARD и POSTROUTING, в противном случае будет генерироваться сообщение об ошибке;
- `-f`, `--fragment` - правило распространяется на все фрагменты фрагментированного пакета, кроме первого;
- `-m limit` - устанавливает предельное число пакетов в единицу времени, которое способно пропустить правило;
- `--dport`, `¬-destination-port` - порт или диапазон портов, на который адресован пакет;
Значение **target** указывает, какое действие должно быть выполнено при условии выполнения критериев в правиле. Здесь можно заставить ядро передать пакет в другую цепочку правил, «сбросить» пакет и забыть про него, выдать на источник сообщение об ошибке и т.п. Ниже приведен список действий:
- `ACCEPT` - пакет прекращает движение по цепочке (и всем вызвавшим цепочкам, если текущая цепочка была вложенной) и считается принятым;
- `DNAT` - используется для преобразования адреса места назначения в IP заголовке пакета.Если пакет подпадает под критерий правила, выполняющего `DNAT`, то этот пакет, и все последующие пакеты из этого же потока, будут подвергнуты преобразованию адреса назначения и переданы на требуемое устройство, хост или сеть;
- `DROP` - действие «сбрасывает» пакет. "Сброшенные" пакеты прекращают свое движение полностью;
- `LOG` служит для журналирования отдельных пакетов и событий. В журнал могут заноситься заголовки IP пакетов и другая интересующая информация;
- `MARK` используется для установки меток на определенные пакеты. Действие может выполняться в пределах таблицы **mangle**;
- `QUEUE` - ставит пакет в очередь на обработку пользовательскому процессу. Оно может быть использовано для нужд учета, проксирования или дополнительной фильтрации пакетов;
- `REDIRECT` - выполняет перенаправление пакетов и потоков на другой порт той же ЭВМ;
- `REJECT` - используется, как правило, в тех же самых ситуациях, что и `DROP`, но в отличие от нее, команда 'REJECT` выдает сообщение об ошибке на хост, передавший пакет;
- `RETURN` - прекращает движение пакета по текущей цепочке правил и производит возврат в вызывающую цепочку, если текущая цепочка была вложенной, или, если текущая цепочка лежит на самом верхнем уровне (например, `INPUT`), то к пакету будет применена политика *«по-умолчанию»*;
- `SNAT` - используется для преобразования сетевых адресов, т.е. изменение исходящего IP адреса в IP заголовке пакета;
- `TOS` используется для установки битов в поле *Type of Service* IP заголовка. Поле `TOS` содержит 8 бит, которые используются для маршрутизации пакетов;
- `TTL` используется для изменения содержимого поля *Time To Live* в IP заголовке;
- `ULOG` предоставляет возможность журналирования пакетов в пользовательское пространство. Оно заменяет традиционное действие `LOG`, базирующееся на системном журнале.
### 2. Практическая часть
**Описание задачи**: требуется защитить web-сервер. Необходимо разрешить доступ к портам 80 и 22 и сделать перенаправление вызова с порта 8080 на 80. При попытке обратится к портам сервера, не описанным в операционной системе (ОС) как сервис, следует отказывать в обслуживании. При попытке обратится к портам, описанным в системе как сервисы, следует отказывать в обслуживании и заносить данные об этом в журнал. Для выполнения задания необходима следующая последовательность действий.
### 2.1 Определение политики по умолчанию
Определение политики по умолчанию для цепочек с учетом того, что все порты системы для должны быть закрыты для внешнего пользователя. Поскольку осуществляется фильтрация пакетов, их обработка будет производится в таблице **filter**. Используем ключ `–P` чтобы задать политику по умолчанию. Зададим правило для входящих пакетов (цепочка `INPUT`). Действие для обработки политики по умолчанию `LOG` (журналирование запроса). Поскольку политика по умолчанию определяется для всех портов, критерии проверки опускаются.
```ssh
# iptables -P INPUT ACCEPT
# iptables -A INPUT -j LOG
```
Определим также политику «по-умолчанию» для исходящих пакетов с разрешением всем исходящим IP-пакетам беспрепятственно проходить фильтрацию. Для определения заданной политики по умолчанию необходимо выполнить в консоли
```ssh
# iptables –P OUTPUT ACCEPT
```
### 2.2 Добавление правил для портов 22 и 80
Осуществляется командой, в которой для заданных критериев применено действие ACCEPT, то есть пакет будет пропущен брэндмауэром.
```ssh
# iptables –A INPUT –p tcp ––dport 22 –j ACCEPT
# iptables –A INPUT –p tcp ––dport 80 –j ACCEPT
```
### 2.3 Добавление правила для порта 8080. Переадресация с порта 8080 на порт 80
Поскольку происходит преобразование адреса назначения, используем таблицу **nat**. Критерии для применения этого правила: `–p tcp ––dport 8080`. Изменение получателя осуществляется в цепочке `PREROUTING`. Правило для переадресации – `REDIRECT`, которое имеет дополнительный ключ для определения порта переадресации `––to-ports`. Зададим перенаправление на порт `80`. Таким образом для определения последнего правила, необходимо ввести в командной строке:
После выполнения команд правила для цепочек сформированы и необходимо осуществить проверку правильности их занесения и работы. Просмотреть созданные правила для всех цепочек можно после выполнения команды:
```ssh
# iptables –S
# iptables –t nat -S
```
Пример первой выполненной команды:
```ssh
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -j LOG
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
-A TCP -p tcp -m tcp --dport 80 -j ACCEPT
```
Проверка правильности настройки защиты web-сервера на основе **iptables** осуществляется проведением проверки доступных для подключения портов на сервере. Для получения открытых для подключения портов следует воспользоваться сканером портов **nmap** и выполнить следующую инструкция в командной строке.
Проверьте, что на компьютере установлен nmap, выполнив команду:
```ssh
$ nmap
```
Если система выдала ошибку, что такой программы нет, необходимо установить nmap:
```ssh
# apt-get update
# apt-get install nmap
```
Запуск команды сканирования портов:
```ssh
$ nmap localhost
```
Вывод команды покажет какие порты на данный момент открыты в системе. Пример:
```ssh
Starting Nmap 7.01 ( https://nmap.org ) at 2017-10-10 04:54 PDT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000065s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh
```
Для сброса настроек iptables в изначальное состояние:
```ssh
# iptables –F
# iptables –t nat -F
```
### 3. Задание
Необходимо сделать перенаправление вызова с соответствующих портов.
Для начала потребуется установить дополнительные пакеты
```ssh
apt-get update
apt install -y screen python3-pip
pip install simple-http-server
```
Утилита `screen` позволяет создавать независимые окна терминала:
- `screen -S name` - создание окна терминала с идентификатором `name` и переход в него;
- `screen -r name` - переход в окно терминала `name`;
Комбинация клавиш `Ctrl+A+D` выйти в главное окно терминала.
Для проверки доступа по указанному порту, в новом окне терминала выполните следующую команду (вместо слова `port` укажите номер порта, согласно варианту):
```ssh
$ screen -S server
$ python –m http.server port
```
После запуска команды, в браузере необходимо проверить доступность вашего сервера, для этого наберите строку ip_adress:port (к примеру 127.0.0.1:8081 для первого варианта). Или обратиться можно на внешний интерфейс, его можно узнать, выполнив команду
$ ifconfig
В браузере вы увидите страничку с файловой системой:
Это означает, что порт открыт и вы можете получить доступ к запущенному Web-server. После запуска запустите команду nmap и посмотрите, какие порты открыты сейчас.
После внесения правила перенаправления, проверьте доступность вашего сервера в браузере, перейдя по адресу: ip_adress:redirect_port (к примеру, 127.0.0.1:81 для второго варианта.)
Повторно запустите команду nmap и проверьте вывод.
Варианты:
№ Бригады Порт доступа Порт с которого перенаправляются запросы Порт на которые перенаправляются запросы
Бригада 1 8081 8081 80
Бригада 2 8079 8079 81
Бригада 3 8078 8078 82
Бригада 4 8077 8077 83
Бригада 5 8076 8076 84
Бригада 6 8075 8075 85
Бригада 7 8074 8074 86
Бригада 8 8073 8073 87
Бригада 9 8072 8072 88
Бригада 10 8071 8071 89
Лабораторная работа разделена на две части:
1. [Подсистема разграничения доступа в ОС Linux](assets/lab1-1.pdf)