Unix2018/Сетевые возможности

Материал из iRunner Wiki

Современные вычислительные системы невозможно представить без наличия сетей. Операционная система UNIX почти с самого рождения интегрировала в себя технологии локальных сетей, на её основе затем была построена сеть Internet, распространившаяся по всему миру.

Дистрибутивы Linux давно используются в качестве серверных операционных систем и заняли значительную долю этого рынка. В рамках практического занятия мы рассмотрим процесс настройки сервера в локальной сети.

Инструменты настройки сети

GUI vs command line

На десктопных дистрибутивах Ubuntu:

  • NetworkManager
  • консольные утилиты (ifconfig, ip, ifup, ...)

По умолчанию они несовместимы.

NetworkManager — демон, позволяющий нескольким пользователям редактировать настройки сети, что удобно на десктопе или ноутбуке. В некотором смысле NetworkManager является фронтендом для iproute, dhclient (клиент протокола DHCP), wpa_supplicant (утилита для настройки шифрования в беспроводных сетях) и ppp (утилита для установления соединений вида точка-точка).

Инструменты командной строки

Среди консольных инструментов наблюдается большое разнообразие.

ifconfig — общая утилита для настройки сетевых интерфейсов. Не читает никакие конфиги и делает ровно то, что попросили.

Часто пишут, что ifconfig устарел. Эта программа практически не развивается с 2001 года. Сейчас на Linux нужно использовать iproute2 (команда ip). У этой утилиты больше возможностей, хотя иногда команды получаются длиннее... Увидим далее на практике.

Устройства и интерфейсы

Сетевые устройства

Сетевые адаптеры (network interface controllers) служат для подключения компьютера к сети. Это может быть сетевая карта с разъёмом Ethernet, может быть Wi-Fi-модуль...

В Ubuntu имя сетевого адаптера можно узнать из вывода команды:

$ sudo lshw -C network

Она позволяет посмотреть подключенные сетевые устройства.

Сетевые интерфейсы

Основной сетевой подсистемы UNIX является сетевой интерфейс. Сетевой интерфейс – это абстракция, используемая для представления связи канального уровня сети с протоколом TCP/IP в UNIX.

Интерфейс имеет набор параметров, большинство которых относятся к сетевому уровню (IP-адрес, маска сети и т. п.). Важным параметром сетевого интерфейса является аппаратный адрес (в Ethernet аппаратный адрес называется MAC-адрес и состоит из шести байтов, которые принято записывать в шестнадцатеричной системе исчисления и разделять двоеточиями).

Интерфейсы не представлены в /dev/ как устройства

Классическое наименование — ethN (например, eth0, eth1).

После внедрения systemd (в Ubuntu начиная с 15.04) сетевые интерфейсы могут иметь другие имена. Сделано это для того, что бы имена сетевых устройств не менялись при подключении к машине новых адаптеров (в последнее время, некоторые USB модемы выступают в роли сетевого адаптера). Эта функциональность называется «Predictable Network Interface Names». В результате eth0 может называться например enp0s4 или eno1, или даже enx78e7d1ea46da. Именно такое имя сетевого адаптера и нужно использовать в настройке сети.

Как правило, в системе присутствует специальный интерфейс под названием lo — это **loopback**-интерфейс. Он может быть использован сетевым клиентским программным обеспечением, чтобы общаться с серверным приложением, расположенным на том же компьютере. То есть если на компьютере, на котором запущен веб-сервер, указать в веб-браузере URL http://127.0.0.1/ или http://localhost/, то он попадает на веб-сайт этого компьютера. Этот механизм полезен для тестирования.

Просмотр сетевых интерфейсов

Как получить список сетевых интерфейсов? [1]

Раньше все использовали команду ifconfig. Можно было выполнить

ifconfig -a

и получить вывод вроде такого:

$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr 8c:16:45:f5:e6:52
          inet addr:169.254.159.114  Mask:255.255.0.0
          inet6 addr: fe80::e5fd:4ee6:969b:9f72/64 Scope:Global
          RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Global
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Сейчас ifconfig признан устаревшим инструментом. В Ubuntu 18.04 он по умолчанию не устанавливается. Теперь нужно использовать команду ip:

ip link show
ip address show

Другие способы получить имена интерфейсов:

ls /sys/class/net
/proc/net/dev

Включение и отключение интерфейсов

Включить сетевой интерфейс:

$ ifconfig eth0 up
$ ip link set eth0 up

Выключить сетевой интерфейс:

$ ifconfig eth0 down
$ ip link set eth0 down

Вспомогательные программы ifup и ifdown используют конфиг из /etc/network/interfaces. В Ubuntu 18.04 они не работают.

Прикладные программы для работы с сетью

nc

Утилита Unix, позволяющая устанавливать соединения TCP и UDP, принимать оттуда данные и передавать их. Несмотря на свою полезность и простоту, данная утилита не входит ни в какой стандарт (например, POSIX).

На сервере (192.168.1.1):

nc -l 17083

На клиенте:

nc 192.168.1.1 17083

telnet

TELNET (сокр. от англ. teletype network) — сетевой протокол для реализации текстового интерфейса по сети (в современной форме — при помощи транспорта TCP). Название telnet имеет утилита, реализующая клиентскую часть протокола.

Исторически Telnet служил для удалённого доступа к интерфейсу командной строки операционных систем. В протоколе не предусмотрено использование ни шифрования, ни проверки подлинности данных. Поэтому он уязвим для любого вида атак, к которым уязвим его транспорт, то есть протокол TCP. Для функциональности удалённого доступа к системе в настоящее время применяется сетевой протокол SSH (особенно его версия 2), при создании которого упор делался именно на вопросы безопасности.

Использует по умолчанию порт 23.

Клиент Telnet иногда используется для осуществления ручного доступа (например, в целях отладки) к таким протоколам прикладного уровня, как HTTP, IRC, SMTP, POP3 и прочим текст-ориентированным протоколам на основе транспорта TCP. Однако, использование клиента telnet в качестве клиента TCP может вызывать следующие нежелательные эффекты:

  • Клиент может передать данные, которые вы не вводили (опции Telnet);
  • Клиент не будет принимать байт 0xFF;
  • Клиент будет искажать 0xFF при передаче.

Удобно проверять, есть ли доступ к порту X (не важно, что именно там за сервер работает, главное, чтобы принимал TCP-соединения).

Есть доступ:

$ telnet bsu.by 80
Trying 217.21.43.3...
Connected to bsu.by.
Escape character is '^]'.

Нет доступа:

$ telnet bsu.by 22
Trying 217.21.43.3...
telnet: Unable to connect to remote host: Connection refused

Ручное задание HTTP-запросов:

$ telnet example.com 80
Trying 93.184.216.34...
Connected to example.com.
Escape character is '^]'.
GET / HTTP/1.0
Host: example.com

HTTP/1.1 200 OK

wget

wget (GNU Wget) — свободная консольная программа для загрузки файлов по сети. Поддерживает протоколы HTTP, FTP и HTTPS, а также поддерживает работу через HTTP-прокси-сервер.

wget является неинтерактивной программой. Это означает, что после её запуска пользователь может повлиять на её работу только с помощью средств управления процессами операционной системы. Как правило, для этого используются сочетания клавиш Ctrl+C при необходимости прерывания работы программы и Ctrl+Z для помещения текущего задания в фон.

Файлы можно скачивать рекурсивно по ссылкам в HTML страницах, как с одного сайта с определённой глубиной следования по ссылкам, так и с нескольких.

wget поддерживает докачку файла в случае обрыва соединения.

curl

cURL — кроссплатформенная служебная программа командной строки, позволяющая взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL. libcurl — библиотека, которую можно использовать из C.

GET, POST

Специальные отдельные команды, имеют названия как у HTTP-методов.

Реализованы на языке perl через утилиту lwp-request. На Debian-дистрибутивах она входит в состав пакета libwww-perl.

Linux как сервер в локальной сети

ОС Linux часто используется на серверах.

  • Высокая стабильность. Система может работать годами без перезагрузок.
  • Гибкость настройки. Можно выключить всё лишнее, например GUI. Можно выбрать любую ФС в зависимости от задач.
  • Производительность. Можно перекомпилировать ядро под конкретное железо, чтобы использовать все оптимизации под имеющийся процессор. Можно тюнить параметры TCP/IP-стека...
  • Безопасность. Исходники открыты, теоретически это должно способствовать тому, что сообщество будет находить и исправлять ошибки. На практике можно вспомнить уязвимость Heartbleed (CVE-2014-0160) в библиотеке OpenSSL, которая существовала в коде с конца 2011 и была публично объявлена в апреле 2014.
  • Малое количество вирусов и прочего malware. Для серверов это не столь актуально, если администратор следит, какой софт выполняется на сервере, и не запускает неизвестное ПО.
  • Бесплатность. Становится особенно важно, если в компании много серверов. Так, цена лицензии Windows Server 2016 Standard для 16-ядерного сервера составляет $882.
  • Большое количество разнообразного серверного ПО также бесплатно. Windows-версии того же софта если и есть, то хуже оптимизированы (например nginx).
  • Популярность. На серверах большая доля, значит, много документации, инструкций, ответов на Stackoverflow, баги репортятся и исправляются...
  • Удобство удалённого администрирования через шелл.

Установить статический IP

sudo ifconfig enp0s8 192.168.1.1 netmask 255.255.255.0

Этот адрес слетит при перезагрузке... Чтобы зафиксировать, надо прописать в конфиге:

sudoedit /etc/network/interfaces
auto enp0s8
iface enp0s8 inet static
address 192.168.1.1
netmask 255.255.255.0

Теперь запустить интерфейс:

sudo ifup enp0s8

Если выдаёт что-то вроде "RTNETLINK answers: File exists", сбросить устройство:

sudo ip addr flush dev enp0s8

Настройка ssh

sudo apt-get install openssh-server

Установка nginx

sudo apt-get install nginx

Настройка DNS

[2]

Служба доменных имён (Domain Name Service, DNS) — это служба интернета, которая ставит в соответствие друг с другом IP-адреса и полные доменные имена (Fully Qualified Domain Names, FQDN). Таким образом, DNS избавляет от необходимости запоминать IP-адреса. Компьютеры, на которых запущен сервер DNS, называются серверами имён. Ubuntu включает в себя BIND (Berkley Internet Naming Daemon), наиболее распространенную программу для обслуживания серверов имён в Linux.

sudo apt-get install bind9

По умолчанию работает как кеширующий DNS-прокси.

Редактируем /etc/bind/named.conf.local:

zone "yandex.ru" {
    type master;
    file "/etc/bind/db.yandex.ru";
};
//reverse zone
zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192";
};
sudo cp /etc/bind/db.{local,yandex.ru}
$TTL	604800
@	IN	SOA	yandex.ru. root.yandex.ru. (
			      3		; Serial
			 604800		; Refresh
			  86400		; Retry
			2419200		; Expire
			 604800 )	; Negative Cache TTL
;
@	IN	NS	ns.yandex.ru.
@	IN	A	192.168.1.1
ns	IN	A	192.168.1.1
sudo cp /etc/bind/db.{127,192}
$TTL	604800
@	IN	SOA	yandex.ru. root.yandex.ru. (
			      2		; Serial
			 604800		; Refresh
			  86400		; Retry
			2419200		; Expire
			 604800 )	; Negative Cache TTL
;
@	IN	NS	ns.
1	IN	PTR	ns.yandex.ru.

DHCP

DHCP (англ. Dynamic Host Configuration Protocol — протокол динамической настройки узла) — сетевой протокол, позволяющий компьютерам автоматически получать IP-адрес и другие параметры, необходимые для работы в сети TCP/IP. Данный протокол работает по модели «клиент-сервер». Для автоматической конфигурации компьютер-клиент на этапе конфигурации сетевого устройства обращается к так называемому серверу DHCP и получает от него нужные параметры. Сетевой администратор может задать диапазон адресов, распределяемых сервером среди компьютеров. Это позволяет избежать ручной настройки компьютеров сети и уменьшает количество ошибок. Протокол DHCP используется в большинстве сетей TCP/IP.

sudo apt-get install isc-dhcp-server
sudoedit /etc/default/isc-dhcp-server
sudoedit /etc/dhcp/dhcpd.conf
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.10 192.168.1.254;
    option domain-name-servers 192.168.1.1;
    option routers 192.168.1.1;
}

Настройка шлюза

Нам нужно обеспечить доступ в интернет с компьютеров локальной сети. Пусть наш сервер будет выступать шлюзом.

Итак, есть два сетевых интерфейса:

  • enp0s3 — доступ к NAT VirtualBox и далее к интернету
  • enp0s8 — доступ к локальной сети (для простоты, пусть это сеть 192.168.1.0/24, интерфейс имеет статический IP 192.168.1.1).

Вначале нужно включить IP forwarding в ядре, то есть разрешить пересылку пакетов между сетевыми интерфейсами. По умолчанию в большинстве дистрибутивов оно выключено из соображений безопасности.

echo 1 > /proc/sys/net/ipv4/ip_forward

Если сделать так, то настройка «слетит» после перезагрузки. Для того чтобы настройка сохранялась, нужно прописать её в /etc/sysctl.conf:

net.ipv4.ip_forward=1

Затем применить изменения

sudo sysctl -p /etc/sysctl.conf

Будем использовать iptables. Это утилита командной строки, является стандартным интерфейсом управления работой межсетевого экрана (брандмауэра) netfilter для Linux. Для использования утилиты iptables требуются привилегии суперпользователя (root).

Викиучебник по iptables

Функционирование фаервола определяется набором правил, каждое из которых состоит из критерия и действия, применяемого к пакетам, подпадающим под этот критерий. Цепочка — это независимый список правил. Были введены отдельные цепочки для фильтрации входящих (INPUT), исходящих (OUTPUT) и транзитных (FORWARD) пакетов. Таблицы — независимые группы цепочек. Каждая таблица решает свою задачу — цепочки таблицы filter отвечали за фильтрацию, цепочки таблицы nat — за преобразование сетевых адресов (NAT), к задачам таблицы mangle относились прочие модификации заголовков пакетов (например, изменение TTL или TOS).

iptables при обработке отдельных пакетов использует информацию о соединениях в целом. iptables может отслеживать состояние соединения и перенаправлять, изменять или отфильтровывать пакеты, основываясь не только на данных из их заголовков (источник, получатель) или содержимом пакетов, но и на основании данных о соединении. Такая возможность фаервола называется stateful-фильтрацией. Можно сказать, что iptables анализирует не только передаваемые данные, но и контекст их передачи.

Выполним следующие команды:

iptables -F FORWARD # На всякий случай очистим цепочку FORWARD
# Разрешаем проходить пакетам по уже установленным соединениям
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Разрешаем исходящие соединения из локальной сети к интернет-хостам
iptables -A FORWARD -m conntrack --ctstate NEW -i enp0s8 -s 192.168.1.0/24 -j ACCEPT
iptables -P FORWARD DROP # Весь остальной транзитный трафик — запрещаем.
iptables -t nat -F POSTROUTING # На всякий случай очистим цепочку POSTROUTING таблицы nat
# Маскарадим весь трафик, идущий через enp0s3
iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

Вкратце рассмотрим, что они делают.

Таблица nat предназначена для операций stateful-преобразования сетевых адресов и портов обрабатываемых пакетов. Действие MASQUERADE подменяет адрес источника для исходящих пакетов адресом того интерфейса, с которого они исходят, то есть осуществляет маскарадинг. Такая операция позволяет, например, предоставлять доступ в Интернет целым локальным сетям через один шлюз.

Если один из хостов локальной сети, например, 192.168.1.2, попытается связаться с одним из интернет-хостов, например, 199.204.44.194 (kernel.org), при проходе его пакетов через шлюз их исходный адрес будет подменяться на внешний адрес шлюза. С точки зрения удаленного хоста (kernel.org) это будет выглядеть, как будто с ним связывается непосредственно сам шлюз. Когда же удаленный хост начнет ответную передачу данных, он будет адресовать их именно шлюзу. Однако, на шлюзе адрес назначения этих пакетов будет подменяться на 192.168.1.2, после чего пакеты будут передаваться настоящему получателю. Для такого обратного преобразования никаких дополнительных правил указывать не нужно — это будет делать все та же операция MASQUERADE. Простота трансляции сетевых адресов является одним из важнейших достоинств stateful-фильтрации.

Если же такой трансляции не производить, удаленный хост просто не сможет ответить на адрес 192.168.1.2, так как адресные пространства локальных сетей изолировано от адресного пространства Интернета. В мире могут существовать миллионы локальных сетей 192.168.1.0/255.255.255.0, и в каждой может быть свой хост 192.168.1.2. Эти сети могут и не быть связаны с Интернетом. Но если они с ним связаны — то только благодаря механизмам трансляции сетевых адресов.

Программирование сетевых приложений

Beej's Guide to Network Programming