Проброс (forwarding) портов на FreeBSD

Вы используете AdBlock. Этот сайт существует за счёт доходов от рекламы. Мы будем благодарны если вы отключите AdBlock на страницах нашего сайта.

()

Проброс портов (он же "port forwarding" и "traffic redirection") - достаточно популярная технология, позволяющая сделать доступными сервисы, "спрятанные" в локальной сети. Доступ осуществляется при помощи перенаправления трафика этих сервисов с внешнего адреса маршрутизатора в локальную сеть, к серверу, который и будет отвечать на запросы.

Кроме того, при помощи проброса портов можно сделать доступным сервер не имеющий реального IP-адреса, подключив его внешнему VPN-серверу и настроив на нём проброс портов. Далее будет показано как настроить проброс портов на OpenVPN-сервере под управлением FreeBSD.

За основу возьмём описанный ранее OpenVPN-сервер. На нём необходимо пробросить порты tcp/80, tcp/443 и udp/53 на компьютер, подключенный к серверу с логином "webserver". Примерная схема показана на рисунке:

Port forwarding

Для начала нужно связать IP-адреса и пользователей (чтобы пользователи всегда получали один и тот же адрес). Для этого нужно в директории, указанной в опции "client-config-dir" OpenVPN-сервера создать для каждого логина по файлу, описывающему настройки для этого пользователя. В качестве имён файлов используются логины пользователей (Так как указана опция "username-as-common-name").

Для примера создадим файл для пользователя "webserver" (в данном случае его имя будет "/usr/local/etc/openvpn/ccd/webserver"), следующего содержания:

ifconfig-push 172.16.251.134 172.16.251.133

Здесь "172.16.251.134" - IP-адрес клиента, а "172.16.251.133" - адрес, который у клиента будет маршрутом по умолчанию.

Общая методика расчёта этих адресов такая: указанная у OpenVPN в параметре "server" подсеть разбивается на подсети с маской 255.255.255.252 и в кажой полученной подсети:

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

Пользуясь данной методикой надо написать конфигурацию для кажого логина. Теоретически можно этого не делать, но тогда клиенты клиенты, не имеющие постоянного адреса, будут получать его динамически и случайно могут получить чужой (OpenVPN это никак не контролирует).

Закончив конфигурацию OpenVPN на всякий случай стоит перезапустить OpenVPN-сервер:

/usr/local/etc/rc.d/openvpn restart

Приступаем к настройке проброса портов. Открываем файл "/etc/pf.rules" и приводим к виду:

set limit { states 20000, frags 5000 }
set timeout { adaptive.start 6000, adaptive.end 12000 }
set skip on { lo0 }


if_ext = "vtnet0"
if_int = "tun0"
net_int = "172.16.251.128/27"
# На этот IP будем пробрасывать порты
forward_to = "172.16.251.134"
# Порты TCP для проброса
forward_ports_tcp = "{ 80, 443 }"
# Порты UDP для проброса
forward_ports_udp = "{ 53 }"

set block-policy drop
set state-policy if-bound

scrub in


# NAT
nat pass on $if_ext from $net_int -> ($if_ext) static-port

# Собственно проброс портов
rdr on $if_ext inet proto tcp from any to $if_ext port $forward_ports_tcp -> $forward_to
rdr on $if_ext inet proto udp from any to $if_ext port $forward_ports_udp -> $forward_to

# Разрешаем весь трафик на loopback-интерфейсе
pass quick on lo0 all


# Разрешаем серверу его собственный исходящий трафик
pass out quick on $if_ext inet proto tcp from ($if_ext) to any flags S/SA keep state
pass out quick on $if_ext inet proto { udp, icmp } from ($if_ext) to any keep state

# Разрешаем доступ к серверу по SSH
pass in quick on $if_ext inet proto tcp from any to ($if_ext) port 22 flags S/SA keep state

# Разрешаем доступ к нашему OpenVPN-серверу
pass in quick on $if_ext inet proto udp from any to ($if_ext) port 443

# Разрешаем ICMP
pass in quick on $if_ext inet proto icmp from any to ($if_ext)

# Разрешаем всё клиентам нашего сервреа
pass in quick on $if_int from $net_int to any keep state

# Разрешаем обращения с внешних адресов к нашему внутреннему серверу
# Входящие пакеты на внешнем интерфейсе
pass in quick on $if_ext proto tcp from any to $forward_to port $forward_ports_tcp
pass in quick on $if_ext proto udp from any to $forward_to port $forward_ports_udp
# Исходящие пакеты на внутреннем интерфейсе
pass out quick on $if_int proto tcp from any to $forward_to port $forward_ports_tcp
pass out quick on $if_int proto udp from any to $forward_to port $forward_ports_udp


# Блокируем весь остальной трафик
block drop all

Логика здесь такая:

  1. Правила, начинающиеся с "rdr" модифицируют входящие пакеты, меняя в них адрес получателя.
  2. Правила вида "pass in quick on $if_ext proto tcp from any to $forward_to..." разрешают таким модифицированным пакетам "входить" во внешний интерфейс.
  3. Правила "pass out quick on $if_int proto tcp from any to $forward_to..." разрешают таким модифицированным пакетам "выходить" из внутреннего интерфейса в сторону клиента.

Применяем правила:

pfctl -f /etc/pf.rules

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

pfctl -s nat|grep rdr

Проверить что всё работает можно просто обратившиесь браузером к IP-адресу вашего OpenVPN-сервера. Если всё работает то должен открыться сайт, расположенный на вашем внутреннем веб-сервере. В случае проблем первым делом надо проверить подключен ли пользователь "webserver" к вашему серверу:)

На этом всё. Приятной работы!

Ключевые слова: freebsd, openvpn, проброс портов, port forwarding, pf.

Подписаться на обновления: RSS-лента Канал в TamTam Telegram канал

Комментарии:

Новый комментарий

Жирный текстКурсивный текстПодчёркнутый текстЗачёркнутый текстПрограммный кодСсылкаИзображение




© 2006-2025 Вадим Калинников aka MooSE
Политика конфиденциальности