The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Построение шлюза с трансляцией адресов на двух интерфейсах во FreeBSD (nat ipfw freebsd)


<< Предыдущая ИНДЕКС Правка src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: nat, ipfw, freebsd,  (найти похожие документы)
From: Taras Savchuk <taras@elantech.ru.> Newsgroups: email Date: Mon, 03 Oct 2005 14:31:37 +0000 (UTC) Subject: Построение шлюза с трансляцией адресов на двух интерфейсах во FreeBSD FreeBSD + natd x 2 Содержание 1. Постановка задачи. 2. Конфигурация ipfw. 3. Создание\модификация rc скриптов. 4. Правка rc.conf. 5. Проверка связи, проверка функционирования скриптов. Благодарности ELANTECH - ИТ аутсорсинг, комплексная системная интеграция, абонентское обслуживание, поддержка UNIX/Linux/FreeBSD серверов, WEB дизайн, WEB разработка, разработка ПО, автоматизация. 1. Постановка задачи. Задача формулируется просто: необходимо транслировать сетевые адреса на двух разных интерфейсах, один из которых виртуальный. Цели две: * Обеспечить для локальной сети доступ к ресурсам сети провайдера. * Предоставить для пользователей локальной сети доступ к ресурсам Интернет. В нашем распоряжении машина с FreeBSD 5.4-STABLE, на которой установлены следующие интерфейсы: * sk0: 192.168.94.26/24 - смотрит в сеть провайдера (192.168.xxx.0/24). * rl0: 10.0.0.1/24 - смотрит во внутреннюю сеть (10.0.0.0/24). * ng0: 62.231.11.104 - туннель к VPN-серверу 192.168.2.1 (VPN-сервер находится в сети провайдера, туннель создается демоном mpd). Ниже изображена схема сети: 2. Конфигурация ipfw. Приведенная ниже конфигурация ipfw минимальна, так что следует при необходимости добавить дополнительные ограничения. Основная задача данной конфигурации ipfw - позволить mpd создать туннель к VPN-серверу и распределить пакеты для Интернет и пакеты для сети провайдера по разным divert-сокетам (8669 и 8668 соответственно), при этом не позволяя ничего лишнего (особенно соединений "снаружи"). Предполагается, что комментариев к тексту будет достаточно для понимания конфигурации. Итак, /etc/elantech.firewall: #!/bin/sh ### Полезные переменные ;) fwcmd="/sbin/ipfw -q" skip="skipto 30000" ### Внешний интерфейс, смотрит в сеть провайдера (ext_if) ext_if="sk0" ext_net="192.168.0.0/16" ext_ip="192.168.94.26" ### Внутренний интерфейс, смотрит в "маленькую" локалку (elantech_if) elantech_if="rl0" elantech_net="10.0.0.0/24" elantech_mask="255.255.255.0" elantech_ip="10.0.0.1" ### Internet интерфейс (VPN туннель) inet_if="ng0" inet_ip="62.231.11.104" ### VPN-сервер vpn_ip="192.168.2.1" vpn_port="1723" ###---------------------------------------------------------------------------- ### Сбрасываем старые правила ${fwcmd} -f flush ### Таблица доступа в интернет/к большой локалке для машин из "маленькой" сети ${fwcmd} table 13 flush ${fwcmd} table 13 add 10.0.0.13 ${fwcmd} table 13 add 10.0.0.10 ${fwcmd} table 13 add 10.0.0.1 ### Только локальный траффик через loopback ${fwcmd} add 100 pass all from any to any via lo0 ${fwcmd} add 200 deny all from any to 127.0.0.0/8 ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any ### Разрешаем GRE пакеты до и от VPN сервера, чтобы mpd мог поднять туннель ${fwcmd} add 501 allow gre from ${ext_ip} to ${vpn_ip} via ${ext_if} ${fwcmd} add 502 allow gre from ${vpn_ip} to ${ext_ip} via ${ext_if} ### Разрешаем PPTP к VPN серверу, опять же для создания туннеля ${fwcmd} add 503 allow tcp from ${ext_ip} to ${vpn_ip} dst-port ${vpn-port} via ${ext_if} setup keep-state ###---------------------------------------------------------------------------- ### NAT-им входящие из сети провайдера пакеты ${fwcmd} add 10000 divert natd all from ${ext_net} to any in via ${ext_if} ### NAT-им входящие пакеты из Internet ${fwcmd} add 10001 divert 8669 all from any to any in via ${inet_if} ###---------------------------------------------------------------------------- --------- ### Требуем от ipfw обработки динамических правил ${fwcmd} add 11000 check-state ### Доступ из локалки в сеть провайдера ${fwcmd} add 12100 ${skip} tcp from table\(13\) to ${ext_net} out via ${ext_if} setup keep-state ${fwcmd} add 12105 ${skip} udp from table\(13\) to ${ext_net} out via ${ext_if} keep-state ${fwcmd} add 12110 ${skip} icmp from table\(13\) to ${ext_net} out via ${ext_if} keep-state ### Доступ из локалки в Internet ${fwcmd} add 12115 ${skip} tcp from table\(13\) to not ${ext_net} out via ${inet_if} setup keep-state ${fwcmd} add 12120 ${skip} udp from table\(13\) to not ${ext_net} out via ${inet_if} keep-state ${fwcmd} add 12125 ${skip} icmp from table\(13\) to not ${ext_net} out via ${inet_if} keep-state ### Доступ в Internet для себя ${fwcmd} add 12115 ${skip} tcp from ${inet_ip} to not ${ext_net} out via ng0 setup keep-state ${fwcmd} add 12120 ${skip} udp from ${inet_ip} to not ${ext_net} out via ng0 keep-state ${fwcmd} add 12125 ${skip} icmp from ${inet_ip} to not ${ext_net} out via ng0 keep-state ### Доступ в сеть провайдера для себя ${fwcmd} add 12130 ${skip} tcp from ${ext_ip} to ${ext_net} out via ${ext_if} setup keep-state ${fwcmd} add 12135 ${skip} udp from ${ext_ip} to ${ext_net} out via ${ext_if} keep-state ${fwcmd} add 12140 ${skip} icmp from ${ext_ip} to ${ext_net} out via ${ext_if}keep-state ### Доступ из локалки к внутреннему интерфейсу ${fwcmd} add 12145 ${skip} tcp from table\(13\) to ${elantech_ip} in via ${elantech_if} setup keep-state ${fwcmd} add 12150 ${skip} udp from table\(13\) to ${elantech_ip} in via ${elantech_if} keep-state ${fwcmd} add 12155 ${skip} icmp from table\(13\) to ${elantech_ip} in via ${elantech_if} keep-state ### Ексклюзив для root-а ${fwcmd} add 12200 ${skip} all from me to any out via ${elantech_if} setup keep-state ###---------------------------------------------------------------------------- ### Режем остальные пакеты ${fwcmd} add 14600 deny all from any to any via ${ext_if} ${fwcmd} add 14601 deny all from any to any via ${inet_if} ${fwcmd} add 14602 deny all from any to me via ${elantech_if} ${fwcmd} add 14603 deny all from me to any via ${elantech_if} ###---------------------------------------------------------------------------- ### NAT-им пакеты в сеть провайдера ${fwcmd} add 50000 divert natd all from any to ${ext_net} out via ${ext_if} ### NAT-им пакеты в интернет ${fwcmd} add 51000 divert 8669 all from any to any out via ${inet_if} ### Сюда долетели честные пакеты - пропускаем! ${fwcmd} add 55000 allow ip from any to any ###---------------------------------------------------------------------------- 3. Создание\модификация rc скриптов. Итак, настало время подумать о запуске второго экземпляра natd. Запускать его будем аналогично основному нату, поэтому делаем... #cp /etc/rc.d/natd /etc/rc.d/natd2 ... читаем man rc, man rc.subr, HANDBOOK и правим /etc/rc.d/natd2. Вот результат (изменения выделены красным): #!/bin/sh # # $FreeBSD: src/etc/rc.d/natd,v 1.1.2.1 2004/10/10 09:50:53 mtm Exp $ # # PROVIDE: natd2 # KEYWORD: nostart nojail . /etc/rc.subr . /etc/network.subr name="natd2" rcvar=`set_rcvar` command="/sbin/natd" start_cmd="natd2_start" pidfile="/var/run/${name}.pid" natd2_start() { dhcp_list="`list_net_interfaces dhcp`" for ifn in ${dhcp_list}; do case ${natd2_interface} in ${ifn}) natd_flags="$natd2_flags -dynamic" ;; *) ;; esac done if [ -n "${natd2_interface}" ]; then if echo ${natd2_interface} | \ grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then natd2_flags="$natd2_flags -a ${natd2_interface}" else natd2_flags="$natd2_flags -n ${natd2_interface}" fi fi echo -n ' natd2' ${natd2_program:-/sbin/natd} ${natd2_flags} ${natd2_ifarg} -P ${pidfile} } load_rc_config $name run_rc_command "$1" Хорошо видно, что мы подставили цифру "2" ко многим переменным, добавили переменную pidfile, чтобы система скриптов могла корректно останавливать и запускать natd2, а также добавили опцию -P с именем pidfile к строке запуска natd2. Файл /etc/rc.d/natd тоже следует немного модифицировать: #!/bin/sh # # $FreeBSD: src/etc/rc.d/natd,v 1.1.2.1 2004/10/10 09:50:53 mtm Exp $ # # PROVIDE: natd # KEYWORD: nostart nojail . /etc/rc.subr . /etc/network.subr name="natd" rcvar=`set_rcvar` command="/sbin/${name}" start_cmd="natd_start" pidfile="/var/run/${name}.pid" natd_start() { dhcp_list="`list_net_interfaces dhcp`" for ifn in ${dhcp_list}; do case ${natd_interface} in ${ifn}) natd_flags="$natd_flags -dynamic" ;; *) ;; esac done if [ -n "${natd_interface}" ]; then if echo ${natd_interface} | \ grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then natd_flags="$natd_flags -a ${natd_interface}" else natd_flags="$natd_flags -n ${natd_interface}" fi fi echo -n ' natd' ${natd_program:-/sbin/natd} ${natd_flags} ${natd_ifarg} -P ${pidfile} } load_rc_config $name run_rc_command "$1" Чтобы при старте/перезапуске/остановке ipfw аналогичным действиям подвергался не только natd, но и natd2, правим /etc/rc.d/ipfw: #!/bin/sh # # $FreeBSD: src/etc/rc.d/ipfw,v 1.8.2.1 2004/10/10 09:50:53 mtm Exp $ # # PROVIDE: ipfw # REQUIRE: ppp-user # BEFORE: NETWORKING # KEYWORD: nojail . /etc/rc.subr . /etc/network.subr name="ipfw" rcvar="firewall_enable" start_cmd="ipfw_start" start_precmd="ipfw_precmd" stop_cmd="ipfw_stop" ipfw_precmd() { if ! ${SYSCTL} net.inet.ip.fw.enable > /dev/null 2>&1; then if ! kldload ipfw; then warn unable to load firewall module. return 1 fi fi return 0 } ipfw_start() { # set the firewall rules script if none was specified [ -z "${firewall_script}" ] && firewall_script=/etc/rc.firewall if [ -r "${firewall_script}" ]; then . "${firewall_script}" echo -n 'Firewall rules loaded, starting divert daemons:' if [ -f /etc/rc.d/natd ] ; then /etc/rc.d/natd start fi if [ -f /etc/rc.d/natd2 ] ; then /etc/rc.d/natd2 start fi elif [ "`ipfw l 65535`" = "65535 deny ip from any to any" ]; then echo 'Warning: kernel has firewall functionality, but' \ ' firewall rules are not enabled.' echo ' All ip services are disabled.' fi echo '.' # Firewall logging # if checkyesno firewall_logging; then echo 'Firewall logging enabled' sysctl net.inet.ip.fw.verbose=1 >/dev/null fi # Enable the firewall # ${SYSCTL_W} net.inet.ip.fw.enable=1 } ipfw_stop() { # Disable the firewall # ${SYSCTL_W} net.inet.ip.fw.enable=0 if [ -f /etc/rc.d/natd ] ; then /etc/rc.d/natd stop fi if [ -f /etc/rc.d/natd2 ] ; then /etc/rc.d/natd2 stop fi } load_rc_config $name run_rc_command "$1" 4. Правка rc.conf. Теперь допишем в /etc/rc.conf нужные для функционирования нашей системы параметры: hostname="oppa.elantech.ru" ### Интерфейс, который смотрит в сеть провайдера ifconfig_sk0="192.168.94.26/24" ### Интерфейс, который смотрит в нашу локалку ifconfig_rl0="10.0.0.1/24" ### Маршрутизация и файрволл gateway_enable="YES" firewall_enable="YES" ### Наш файрволльный скрипт firewall_script="/etc/firewall.elantech" ### natd natd_enable="YES" natd_interface="sk0" natd_flags="" ### natd2 (для него указываем внешний IP-адрес, а не интерфейс, ### т.к. на момент запуска natd2 интерфейс ng0 еще не создан) natd2_enable="YES" natd2_interface="62.231.11.104" natd2_flags="-p 8669" ### Статические маршруты route_fnet="192.168/16 192.168.94.1" static_routes="fnet" ### DNS named_enable="YES" ### PPTP клиент mpd_enable="YES" 5. Проверка связи, проверка функционирования скриптов. На практике убеждаемся, что ipfw, natd, natd2 и mpd корректно останавливаются, запускаются, перезапускаются, VPN туннель создается, доступ в интернет есть там, где он нужен. oppa# /etc/rc.d/ipfw stop net.inet.ip.fw.enable: 1 -> 0 Stopping natd. Waiting for PIDS: 285, 285, 285, 285, 285. Stopping natd2. Waiting for PIDS: 295, 295, 295, 295, 295. oppa# /etc/rc.d/ipfw start Firewall rules loaded, starting divert daemons: natd natd2. net.inet.ip.fw.enable: 0 -> 1 oppa# ifconfig sk0: flags=8843 mtu 1500 inet 192.168.94.26 netmask 0xffffff00 broadcast 192.168.94.255 inet6 fe80::211:d8ff:fe98:9d1a%sk0 prefixlen 64 scopeid 0x2 ether 00:11:d8:98:9d:1a media: Ethernet autoselect (100baseTX ) status: active rl0: flags=8843 mtu 1500 options=8 inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255 inet6 fe80::280:48ff:fe33:9d77%rl0 prefixlen 64 scopeid 0x3 ether 00:80:48:33:9d:77 media: Ethernet autoselect (100baseTX ) status: active plip0: flags=108810 mtu 1500 lo0: flags=8049 mtu 16384 inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x6 ng0: flags=88d1 mtu 1500 inet 62.231.11.104 --> 172.16.0.1 netmask 0xffffffff inet6 fe80::211:d8ff:fe98:9d1a%ng0 prefixlen 64 scopeid 0x7 oppa# Все работает! А у Вас? Шлите письма на taras@elantech.ru с отзывами и пожеланиями.

<< Предыдущая ИНДЕКС Правка src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, universite (ok), 23:35, 04/10/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Ниосилил!

    Непонятно через какой интерфейс поднят VPN?
    Нафига делать такие огромные стартовые скрипты?
    когда можно обойтись тремя конфигами (двух натов и firewall) и запускать с rc.conf и rc.local.


     
     
  • 2.11, lexx (??), 17:55, 29/12/2005 [^] [^^] [^^^] [ответить]  
  • +/
    interface virtualniy. on sozdaetsya progoy pod nazvaniem mpd.
     

  • 1.2, Saenara (?), 05:50, 05/10/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Непонятно, зачем делать через natd+ipfw, когда теперь есть pf?
     
     
  • 2.8, Vdim (?), 11:55, 26/10/2005 [^] [^^] [^^^] [ответить]  
  • +/
    Извиняюсь за глупый вопрос, но что такое pf ?
    И если можно узнать токак построить на базе этого интернет и локалку ?
     

  • 1.3, SomeThingWrong (?), 09:48, 05/10/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    согласен с Saenara, накой хрен юзать старые оглобли natd + ipfw, если существует pf?
     
     
  • 2.4, Envoy (??), 12:12, 05/10/2005 [^] [^^] [^^^] [ответить]  
  • +/
    Еще есть ipfilter, который не только под *BSD РАБОТАЕТ ;)
     

  • 1.5, _Ale_ (??), 13:24, 05/10/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    в который раз убеждаюсь PF - весчь! А тут такое наворочено, что не дай бог!
     
  • 1.6, Taras_ (??), 00:42, 06/10/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    pf есть, но в 6-ой ветке natd уже в ядре, а это большая перспектива.
     
  • 1.7, Feb (??), 11:55, 06/10/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Отличная статья!
     
  • 1.9, Stalker AKA Zver (?), 14:59, 23/12/2005 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А как быть в такой ситуации?

    http://www.bsdportal.ru/viewtopic.php?t=7662

     
  • 1.12, gerash (?), 21:31, 31/01/2006 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А про IPNAT все дружно забыли?
    в отличие от монстра, описанного в статье, он спокойно НАТит на два интерфейса, и не требует, в отличие от NATD, двух переключений контекста на каждый пакет. Кстати, он не требует, чтобы с ним вместе запускался ipf, и спокойно сосуществует с ipfw. А правила НАТа можно менять по ходу дела.
    Т.е. вся мазута в статье свелать бы к отработке правила

    map <extNIC> from <intranet> to any -> <extNIC-address>/32

    и добавлению при поднятии ng0 из mpd правила
    map ng0 from <intranet> to <куда там через VPN ходим> -> <ng0-address>/32

    что спокойно добавляется (и убирается при падении VPN) из скрипта в /usr/local/etc/mpd/, ну, например, ng0-up и ng0-down

     
  • 1.13, jhn (??), 15:45, 22/02/2006 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А как быть если ext_ip inet_ip задаются dhcp сервером???
     
     
  • 2.16, gerash (?), 12:58, 24/09/2006 [^] [^^] [^^^] [ответить]  
  • +/
    Скрипты ng*-up и ng*-down вызываются из mpd с параметрами - например

    exec: /usr/local/etc/mpd/ng1-up ng1 inet 192.168.2.2 192.168.2.1 MyConnection
    exec: /usr/local/etc/mpd/ng1-down ng1 inet MyConnection

    так что наличие или отсутствие DHCP не влияет.

     

  • 1.18, MetallisT (ok), 14:37, 28/09/2007 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    всё отлично работает )
     
  • 1.20, daggerok (?), 17:33, 30/07/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    >3. Созданиемодификация rc скриптов.
    >Итак, настало время подумать о запуске второго экземпляра natd.
    >Запускать его будем аналогично основному нату, поэтому делаем…
    >#cp /etc/rc.d/natd /etc/rc.d/natd2
    >… читаем man rc, man rc.subr, HANDBOOK и правим /etc/rc.d/natd2….

    далее поскипано

    зачем вы это делаете?
    есть более простой способ и правильный
    читаем man natd
    там видим пример указанный разработчиками:

    The way this works is that natd.conf builds two instances of the aliasing
    engine.

    In addition to these instances’ private divert(4) sockets, a third socket
    called the “globalport” is created; packets sent to natd via this one
    will be matched against all instances and translated if an existing entry
    is found, and unchanged if no entry is found. The following lines are
    placed into /etc/natd.conf:

    log
    deny_incoming
    verbose

    instance default
    interface sis0
    port 1000
    redirect_port tcp 10.0.0.2:122 122

    instance sis2
    interface sis2
    port 2000
    redirect_port tcp 10.0.0.2:122 122

    globalport 3000

    и ничего копировать и править не надо

     
  • 1.21, Pirate (?), 14:30, 07/07/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Настроил данный конфиг, перестали открываются сайты. Просто белый экран и лоадер "0%" и может висеть так до бесконечности. Может у кого была такая проблема, подскажите решение пожалуйста!
     

    игнорирование участников | лог модерирования

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру