Internet sharing (Русский)

From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи Internet sharing. Дата последней синхронизации: 11 декабря 2022. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Эта статья описывает, как раздать подключение к интернету от одного компьютера одному или нескольким другим компьютерам.

Системные требования

Компьютер, выполняющий роль сервера, должен иметь дополнительное сетевое устройство. На нём должно работать соединение канального уровня с компьютером, который будет получать интернет:

  • Чтобы иметь возможность поделиться интернетом с несколькими компьютерами, можно использовать коммутатор.
  • Можно раздавать интернет через беспроводную сеть; подробности в статье Программная точка доступа.
  • Если доступ предоставляется только одному компьютеру, достаточно перекрёстного кабеля. Если одна из сетевых карт поддерживает MDI-X, перекрёстный кабель не нужен и можно использовать обычный Ethernet-кабель. Чтобы разобраться в этом, можно выполнить команду ethtool интерфейс | grep MDI от имени root.

Настройка

В этом разделе предполагается, что сетевой интерфейс, подсоединяемый к клиентскому компьютеру (компьютерам), называется net0, а сетевой интерфейс, подключенный к интернету называется internet0.

Совет: Вы можете назвать ваши интерфейсы так же, используя udev (Русский)#Установка постоянных имен устройств.

Вся настройка выполняется на компьютере, выполняющем роль сервера, за исключением последнего шага в разделе #Назначение ip адресов клиентским компьютерам.

Статический IP адрес

Назначьте статический IPv4 адрес интерфейсу, подключенному к другим компьютерам. Первые 3 байта этого адреса не могут быть такими же как у другого интерфейса.

# ip link set up dev net0
# ip addr add 192.168.123.100/24 dev net0 # произвольный адрес

Чтобы статический ip был назначен при загрузке, можно использовать какой-нибудь сетевой менеджер.

Разрешите пересылку пакетов

Проверьте текущие настройки перенаправления пакетов:

# sysctl -a | grep forward

Вы заметите, что эта опция существует для управления переадресацией по умолчанию, на интерфейсе, а также отдельные опции для IPv4/IPv6 на интерфейсе.

Введите следующую команду для временного разрешения пересылки пакетов во время выполнения:

# sysctl net.ipv4.ip_forward=1
Совет: Чтобы включить пересылку пакетов только на определённом интерфейсе, можно вместо этой команды использовать sysctl net.ipv4.conf.интерфейс.forwarding=1.
Важно: Если в системе используется systemd-networkd для управления сетевыми интерфейсами, настройка отдельных интерфейсов по IPv4 невозможна, так логика systemd будет использовать глобальную конфигурацию IPv4 на всех интерфейсах. Рекомендуемым обходным решением является использование межсетевого экрана для запрета пересылки на отдельных интерфейсах. Смотрите systemd.network(5) для более подробной информации. Семантика IPForward=kernel, введённая в старой версии systemd 220/221 для следования настройкам ядра, больше не применяется.[1] [2]

Чтобы разрешение на пересылку для всех интерфейсов осталось после перезагрузки, отредактируйте /etc/sysctl.d/30-ipforward.conf:

/etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1

После этого рекомендуется дважды проверить, что после перезагрузки пересылка работает как положено.

Включите NAT

С помощью iptables

Установите пакет iptables. Используйте iptables, чтобы включить NAT:

# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE
# iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# iptables -A FORWARD -i net0 -o internet0 -j ACCEPT
Примечание: Разумеется, это тоже будет работать с мобильным широкополосном соединением (обычно называемом ppp0 на раздающем компьютере).

Используйте -I DOCKER-USER вместо -A FORWARD, если у вас установлен docker. [3]

# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE
# iptables -I DOCKER-USER 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# iptables -I DOCKER-USER 2 -i net0 -o internet0 -j ACCEPT

При подключении через PPPoE уменьшите mss до pmtu, чтобы предотвратить фрагментацию:

# iptables -t mangle -A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

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

С помощью nftables

Установите пакет nftables. Для включения NAT с помощью nftables создайте цепочку postrouting в новой/существующей таблице:

# nft add table inet nat
# nft add chain inet nat postrouting '{ type nat hook postrouting priority 100 ; }'

После этого включите маскарадинг адресов из интерфейса net0 для интерфейса internet0:

# nft add rule inet nat postrouting oifname internet0 masquerade

Возможно, вы захотите добавить ещё несколько ограничений межсетевого экрана на пересылку (при условии, что таблица фильтров уже существует и настроена как описано в разделе nftables (Русский)#Сервер):

# nft add chain inet filter forward '{ type filter hook forward priority 0; policy drop; }'
# nft add rule inet filter forward ct state related,established accept
# nft add rule inet filter forward iifname net0 oifname internet0 accept

Дополнительную информацию о NAT в nftables можно найти в nftables Wiki. Чтобы сделать изменения постоянными, следуйте инструкциям в статье nftables (Русский).

С помощью firewalld

Установите пакет firewalld. firewalld — это демон межсетевого экрана, который полагается на nftables и iptables. Сначала измените зоны сетевых интерфейсов firewalld:

# firewall-cmd --zone=external --change-interface=internet0 --permanent
# firewall-cmd --zone=internal --change-interface=net0 --permanent

Затем добавьте новую политику для пропуска трафика между внутренней и внешней зоной:

# firewall-cmd --permanent --new-policy int2ext
# firewall-cmd --permanent --policy int2ext --add-ingress-zone internal
# firewall-cmd --permanent --policy int2ext --add-egress-zone external
# firewall-cmd --permanent --policy int2ext --set-target ACCEPT
# firewall-cmd --reload
Совет: Вы можете использовать более строгие правила политики, чем просто ACCEPT, как показано в разделе Firewall Rules в документации firewalld.[4]

Например, чтобы разрешить доступ в интернет только узлам 192.168.2.0/24, выполните:

firewall-cmd --permanent --policy int2ext --add-rich-rule='rule family=ipv4 source address=192.168.2.0/24 accept' Не забудьте потом перегрузить правила:

firewall-cmd --reload

Назначение ip адресов клиентским компьютерам

Если вы планируете регулярно подключать какие-то компьютеры для использования интернета через ваш компьютер, хорошей идеей будет установка dhcp сервера. В качестве DHCP-сервера можно использовать, например, dhcpd (Русский) или dnsmasq. Затем установите DHCP-клиент (например, dhcpcd) на каждый клиентский компьютер.

На стороне сервера должен быть разрешён приём пакетов на UDP-порт 67. Также нужно разрешить входящие соединения с UDP/TCP портом 53 для DNS запросов. Пример для iptables:

# iptables -I INPUT -p udp --dport 67 -i net0 -j ACCEPT
# iptables -I INPUT -p udp --dport 53 -s 192.168.123.0/24 -j ACCEPT
# iptables -I INPUT -p tcp --dport 53 -s 192.168.123.0/24 -j ACCEPT

Если вы не планируете такое подключение на регулярной основе, вы можете задать ip адреса каждому клиенту вручную.

Назначение ip адресов вручную

Вместо использования DHCP можно вручную задать статический IP-адрес и маршрут по умолчанию через 192.168.123.100. Существует множество инструментов для соответствующей настройки сети. Одним из ярких примеров такого инструмента является ip(8), смотрите раздел Настройка сети#Управление сетевым подключением. Или можно использовать файл .network, смотрите раздел systemd-networkd (Русский)#Проводной интерфейс со статическим IP-адресом для настройки статического IP.

Укажите DNS сервер на каждом клиентском компьютере. Смотрите resolv.conf для дополнительной информации.

Теперь клиентский компьютер должен иметь доступ в Internet.

Решение проблем

Если вы можете подключить два компьютера, но не можете пересылать данные (например, если клиентский делает DHCP запрос к раздающему компьютеру, раздающий компьютер получает запрос и предлагает IP клиенту, но клиент не принимает его, а вместо этого происходит тайм аут), проверьте, что вы не имеете других интерферирующих правил iptables.

Клиенты не могут получить доступ к интернету или не могут подключиться

Симптомы могут быть такие: клиенты получают сообщение host is down, когда пингуют хост, получают no route to host, когда пингуют устройства вне локальной сети (которые должны быть перенаправлены через NAT), DHCP-запросы не проходят через мост, ...

Известно, что такие проблемы может вызывать Docker. Простое отключение юнитов docker.service и docker.socket решает проблему.

docker github issue.

Смотрите также