Выход из локальной сети в Интернет через FreeBSD и двух провайдеров


Рассмотрим ситуацию, когда некоторым пользователям локальной сети необходим выход в Интернет через одного провайдера, а другим через другого. Такая ситуация может возникнуть по разным причинам, например, начальству хочется, чтобы у них все "летало", а другие могут посидеть и на медленном канале. Допустим, что у нас имеется три интерфейса: vr0 (192.168.0.1) - локальная сеть 192.168.0.0./24, vr1 (1.2.3.4) - сеть первого провайдера 1.2.3.4/24 со шлюзом 1.2.3.1, vr2 (2.3.4.5) - сеть второго провайдера 2.3.4.5/24 со шлюзом 2.3.4.1. Рабочие станции с адресами 192.168.0.10 и 192.168.0.20 должны ходить в Интернет через первого провайдера, все остальные через второго. Для того, чтобы разрулить данную ситуацию, необходимо вначале пересобрать ядро, включив в него следующие строки:
options IPFIREWALL
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=100
options IPDIVERT

Так как каждый провайдер выдает только один реальный IP-адрес, то будем использовать natd на обоих внешних интерфейсах. Для этого необходимо создать конфигурационный файл /etc/natd.conf:
unregistered_only
use_sockets
same_ports

instance default
interface vr2
port 1000

instance ISP1
interface vr1
port 2000

globalport 3000

Для разруливания пакетов будем использовать ipfw. Для этого создадим дополнительный раздел в файле /etc/rc.firewall следующего содержания:
[Rr][Oo][Uu][Tt][Ee][Rr])

oif1="$firewall_router_oif1"
onet1="$firewall_router_onet1"
oip1="$firewall_router_oip1"

oif2="$firewall_router_oif2"
onet2="$firewall_router_onet2"
oip2="$firewall_router_oip2"
gwip2="$firewall_router_gwip2"

iif="$firewall_router_iif"
inet="$firewall_router_inet"
iip="$firewall_router_iip"

${fwcmd} table 10 add 192.168.0.10
${fwcmd} table 10 add 192.168.0.20

${fwcmd} add pass all from any to any via ${iif}

${fwcmd} add skipto 1000 all from any to any in via ${oif1}
${fwcmd} add skipto 2000 all from any to any out via ${oif1}
${fwcmd} add skipto 3000 all from any to any in via ${oif2}
${fwcmd} add skipto 4000 all from any to any out via ${oif2}

${fwcmd} add 1000 divert 1000 all from any to any
${fwcmd} add skipto 6000 all from any to any

${fwcmd} add 2000 divert 3000 all from any to any
${fwcmd} add skipto 6000 all from ${oip1} to any
${fwcmd} add skipto 5000 all from ${oip2} to any
${fwcmd} add skipto 4000 all from "table(10)" to any
${fwcmd} add divert 1000 all from any to any
${fwcmd} add skipto 6000 all from any to any

${fwcmd} add 3000 divert 2000 all from any to any
${fwcmd} add skipto 6000 all from any to any

${fwcmd} add 4000 divert 2000 all from any to any
${fwcmd} add 5000 fwd ${gwip2} all from ${oip2} to not ${onet2}

${fwcmd} add 6000 pass all from any to any

${fwcmd} add deny all from any to any

;;

Вместо правила 6000 можно прописать свои более жесткие правила. В заключении добавляем несколько строк в /etc/rc.conf:
ifconfig_vr0="inet 192.168.0.1 netmask 255.255.255.0"
ifconfig_vr1="inet 1.2.3.4 netmask 255.255.255.0"
ifconfig_vr2="inet 2.3.4.5 netmask 255.255.255.0"
defaultrouter="2.3.4.1"

gateway_enable="YES"

natd_enable="YES"
natd_flags="-f /etc/natd.conf"

firewall_enable="YES"
firewall_quiet="YES"
firewall_logging="YES"
firewall_type="ROUTER"
firewall_router_oif1="vr2"
firewall_router_onet1="2.3.4.5/24"
firewall_router_oip1="2.3.4.5"
firewall_router_oif2="vr1"
firewall_router_onet2="1.2.3.4/24"
firewall_router_oip2="1.2.3.4"
firewall_router_gwip2="1.2.3.1"
firewall_router_iif="vr0"
firewall_router_inet="192.168.0.0/24"
firewall_router_iip="192.168.0.1"

Теперь все пользователи локальной сети по умолчанию будут выходить в Интернет через второго провайдера. А пользователи 192.168.0.10 и 192.168.0.20 через первого.

Обновлено: 12.03.2015