Проброс портов в ОС FreeBSD. Оговоримся сразу, всё что здесь написано вполне работоспособно, работает не на одной системе. Проброс портов - штука довольно простая, как в теории, так и в практике. Итак, давайте посмотрим, о чем тут можно подумать. Пробрасывать порты стоит в том случае, если необходимый сервис находится в локальной сети за шлюзом с Фрей, а воспользоваться им нужно снаружи. Это может быть как веб-сайт, либо удаленный рабочий стол, так и какой-нибудь специфический софт. Вот что удавалось сделать мне: 1. Удаленный рабочий стол \ RDP 2. Доступ к серверу интернет-клиентов для клиентов. 3. Веб-сайт 4. РАдмин. Для удобства восприятия обозначим нашу схему как: (клиент)------>(шлюз)------>(сервер) Сначала давайте удостоверимся что сервис на целевой машине (сервер), на который мы будем прокидывать порт действительно работает и к нему можно подключиться. Пусть к примеру это будет radmin. Для этого воспользуемся телнетом. Например так: Code telnet server.local 4899 Если порт слушает - результат увидим, если нет, то будет рефуз. Я поясню, почему надо в этом удостовериться. Дело в том, что как-то раз я очень долго пытался подключиться на машину на сервис, который слушался совсем на другом порту. Что и говорить, трудно подключиться на закрытый порт, блин. Поэтому семь раз отпей, как говорится :). Итак, удостоверившись, что сервис слушает, важно проверить следующий момент - дефолтным шлюзом у сервера должен быть наш шлюз, на котором мы будем пробрасывать порты. Соответственно, это обеспечит обратный маршрут, а иначе, никто не увидит результата. Я использую на серверах ОС FreeBSD и пакетный фильтр PF. Думаю, что запуск ПФ с большой вероятностью удастся большинству из начинающих сисадминов, поэтому раскрывать настройку ПФ не вижу смысла. Перейдем уже к матчасти. Правила должны располагаться в следующим порядке: NAT RDR FILTER Соответственно ваши строчки с пробросом портов должны быть после ната и перед фильтрацией. Итак, я приведу кусок кода, достаточный для того, чтобы прокинуть радминовский порт на целевой сервер. С комментариями смотрите ниже: Code #### VAR ext_if = "rl1" int_if = "rl0" lan_net = "192.168.1.0/24" server = "192.168.1.3" radmin = "{78.111.87.247}"
rdr on $ext_if proto tcp from $radmin to $ext_if port 1400-> $server port 4899
#### ALLOW RADMIN pass in on $ext_if inet proto tcp from $radmin to $ext_if port 1400 pass in on $ext_if inet proto tcp from $radmin to $server port 4899 pass out on $int_if inet proto tcp from $radmin to $server port 4899 Итак, вначале я обозначил переменные, $ext_if - внешний интерфейс, $int_if - внутренний интерфейс, $lan_net - локальная сеть, $server - ип-адрес целевой машины, $radmin - внешний ип-адрес, с которого будем подключаться. Использование переменных позволит легко изменять конфигурацию фаервола, не копаясь долго в правилах и не выискивая адреса. Следующая строчка: rdr on $ext_if proto tcp from $radmin to $ext_if port 1400-> $server port 4899 она и будет отвечать за проброс порта. rdr - ключевое слово редиректа on $ext_if - показываем где именно будет происходить редирект proto tcp - тип протокола from $radmin - от кого будет редиректиться траффик указанного выше типа to $ext_if - при подключении на какой интерфейс будет работать правило (как правило это всё однотипно, а различаются только порты) port 1400 - на какой порт будем подключаться, чтобы попасть на целевой порт -> - стрелочка показывает куда редиректить $server port 4899 - цель редиректа. То есть здесь указываем целевой сервер и порт Не забудем, что для проброса портов также необходимо прописать некоторые правила фильтрации траффика в фаерволе. Если схематично представить схему прохождения траффика от внешней машины до целевого порта на сервере, то должно быть ясно, что необходимо разрешить следующие вещи: 1. Разрешить входящие подключения с внешней машины на внешний интерфейс на подключаемый порт (здесь я взял в качестве примера 1400, но в принципе, можно взять любой понравившийся не занятый порт, тот же 4899 2. Разрешить входящие подключения на внешнем интерфейсе с внешней машины на внутренний целевой сервер на порт радмина 4899. 3. Разрешить исходящие подключения на внутреннем интерфейсе с внешней машины на целевой сервер и порт радмина. Таким образом видим, что в этом случае траффик проходит следующие направления: 1. входящий траффик на внешний интерфейс к внешнему интерфейсу подключаемому порту 2. входящий траффик на внешнем интерфейсе к целевому сервису и целевому порту 3. исходящий траффик на внутреннем интерфейсе к целевому сервису и порту После прописывания этих нехитрых строчек, настроив в Радмин Вьюер ип и порт для подключения, можно попробовать подключиться. Должно получиться. Если не заработало, то смотрим раздел "Возможные проблемы" при пробросе портов. Возможные проблемы при пробросе портов. Бывает, что не подключается и всё тут. Вроде бы все сделал правильно, но нифига не работает. Тогда давайте плясать от противного. Откроем фаервол полностью, это конечно плохо, но сразу поможет определить в чем именно загвоздка. То есть я привел фаервол к такому виду: Code # cat /etc/pf.conf.open ext_if = "rl1" int_if = "rl0" lan_net = "192.168.1.0/24" server = "192.168.1.3" radmin = "{78.111.87.247}"
nat on $ext_if inet from $lan_net to any -> $ext_if rdr on $ext_if proto tcp from any to $ext_if port 1400 -> $server port 4899 pass all # Эта конфигурация фаервола позволяет натить траффик из локальной сети, редиректить один порт на целевую машину и пропускать весь траффик, не блокируя ничего. Теперь попробуем подключиться. Большинство проблем исчезнет на этом этапе. Если не помогло - читаем далее. Возможно, что безопасность сервиса на целевой машине не позволяет подключаться клиентам не из локальной сети. То есть, с улицы не удастся подключиться, к примеру, на веб-сервер, который показывает страницу только локальной сетке. Проблему нужно поискать в настройке целевого сервиса. Возможно, часть проблем уйдет на этом этапе. Далее, если ничего не помогает, то юзаем старый добрый tcpdump на каждом узле нашей цепочки. Например, таким образом: # tcpdump -i sk0 dst port 1400 Ман по команде подскажет что за ключи здесь используются. Конечно, времени ни у кого нет, но все же попробуем посмотреть что они означают. Проблема безопасности. Проблема безопасности при пробросе портов состоит в том, что не вы один можете воспользоваться этим сервисом. Ладно ещё, если это для паблика, а если это радмин на свою админскую тачку ? Так вот, не забываем после того как поработали, как минимум, закомментировать правило с редиректом. Даже если у вас выделенный ип, не стоит пренебрегать элементарными правилами безопасности. Если это РДП - заблокируйте экран заранее, если это радмин, составьте пароль, отличающийся от "11111111" или "12345678" :)))). Подведем итог. Итак, вспомним последовательность. 1. Подготовка. Обрисуйте четкое представление откуда, кто, куда, на какие ип-адреса и порты подключается. 2. Проверка доступности целевого сервиса. Проверьте возможно ли подключиться к целевому сервису со шлюза. На этом же этапе стоит проверить и настройки безопасности целевого сервера, позволит ли она подключиться к сервису извне. 3. Добавьте строки в фаервол. 4. Перезапустите фаервол. 5. Попробуйте подключиться. 6. При неудаче - первое, что нужно сделать, это проверить синтаксис. Ведь эта операционная система довольно умная, и не позволит сделать то, что не написано админом. Итак внимательно проверим синтаксис. Если он в порядке, попробуйте использовать утилиту tcpdump. При наличии строчке в фаерволе "block log all" и поддержки псевдоустройства pflog0 в ядре можно использовать tcpdump -eni pflog0. Если он молчит, то дампим весь траффик на искомых портах: tcpdump -i sk0 dst port 1400. В итоге обязательно должно получиться. ЗЫЖ: Кстати, rdr правила применяются также при использовании т.н. прозрачного проксирования. Если Squid работает в режиме прозрачного прокси, то в фаерволе должна быть следующая строчка: rdr on $int_if inet proto tcp from any to any port www -> 127.0.0.1 port 3128 Что она означает уже сможете расшифровать сами. Удачи в пробрасывании портов, друзья мои.
Ссылка на форуме для обсуждения статьи: http://rm-rf.ucoz.ru/forum/23-5-1
|