URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 103105
[ Назад ]

Исходное сообщение
"Раздел полезных советов: Установка параметров шлюза на базе ..."

Отправлено auto_tips , 16-Июн-15 01:00 
++ Введение

На сервере FreeBSD 10.1 установлены два интернет канала. Первый вполне нормальный Ethernet, выделенный ip адрес.
Второй - LTE модем, адрес соответственно динамический.
Весь трафик squid должен уходить на второй канал.
Для этого используется опция tcp_outgoing в squid.conf
В правилах ipfw добавлены два правила для обеспечения forward на новый шлюз

   ipfw add 10 fwd <адрес шлюза на втором канале> all from <динамический адрес второго канала> to not 192.168.1.0/24 out
   ipfw add 11 pass all from any to <динамический адрес второго канала> via <интерфейс LTE модема> in

Механизм ясен. Осталось сделать следующее:

1. При изменении динамического адреса надо подставлять новые значения в ipfw и в squid

2. Сделать это при старте сервера

По тексту интерфейс ue0 - интерфейс LTE модема.

++ Получение нового динамического адреса

После инициализации модема и запуска dhclient мы получим динамический IP адрес. dhclient формирует leases в своем файле.

Пример файла:

    lease {
      interface "ue0";
      fixed-address 100.67.50.124;
      option subnet-mask 255.255.255.248;
      option routers 100.67.50.121;
      option domain-name-servers 83.149.32.225,83.149.32.224;
      option dhcp-lease-time 518400;
      option dhcp-message-type 5;
      option dhcp-server-identifier 100.67.50.121;
      option dhcp-renewal-time 259200;
      option dhcp-rebinding-time 453600;
      renew 1 2015/6/15 08:59:05;
      rebind 3 2015/6/17 14:59:05;
      expire 4 2015/6/18 08:59:05;
    }
    lease {
      interface "ue0";
      fixed-address 100.67.3.43;
      option subnet-mask 255.255.255.248;
      option routers 100.67.3.41;
      option domain-name-servers 83.149.32.225,83.149.32.224;
      option dhcp-lease-time 518400;
      option dhcp-message-type 5;
      option dhcp-server-identifier 100.67.3.41;
      option dhcp-renewal-time 259200;
      option dhcp-rebinding-time 453600;
      renew 6 2015/6/13 16:12:27;
      rebind 1 2015/6/15 22:12:27;
      expire 2 2015/6/16 16:12:27;
    }

Lease в текущий момент будет последним. Нас интересует две строки. fixed-address - это сам динамический адрес. option routers - это адрес шлюза на этом интерфейсе.

Я получаю эти поля через awk, только потому, что lease несколько и нам нужен последний. Через awk это удобно сделать.

Скрипт для получения ip
megafon_get_ip.awk:

    BEGIN {nline=1
    }
    
    {
       tag1[nline]=$1
       tag2[nline]=$2
       nline=nline+1
    }
    
    END {
        for (u=1;u<nline;u++)
          {
            if (tag1[u]=="fixed-address")
            {
    # Делаем замену последнего символа, что бы не мешал.
                    gsub(";","",tag2[u]);
                    ip = tag2[u];
            }
          }
        print ip;
        }

Скрипт для получения routers

megafon_get_router.awk:

    BEGIN {nline=1
    }
    
    {
       tag2[nline]=$2
       tag3[nline]=$3
       nline=nline+1
    }
    
    END {
        for (u=1;u<nline;u++)
          {
            if (tag2[u]=="routers")
            {
    # Делаем замену последнего символа, что бы не мешал.
                    gsub(";","",tag3[u]);
                    router = tag3[u];
            }
          }
    
       print router;
    }

++ Обновление таблиц ipfw

Считывание нового динамического адреса и адреса шлюза в ipfw сделано через cat

Выдержка из rc.firewall:

    ...
    eth_megafon="ue0"
    ip_megafon=`cat /etc/megafon_ip`
    router_megafon=`cat /etc/megafon_router`
    ${fwcmd} add 10 fwd $router_megafon all from $ip_megafon to not 192.168.0.0/16 out
    ${fwcmd} add 11 pass all from any to $ip_megafon via $eth_megafon in
    ...

Как видно, текущие адреса хранятся в /etc/megafon_ip и /etc/megafon_router

++ Обновление squid.conf

К сожалению, опция tcp_outgoing_address требует указания адреса. То есть фокус как в rc.firewall не пройдет.
Значит надо будет делать замену.

Создаем файл squid.conf.etalon:
    ...

    tcp_outgoing_address #ip_megafon#

    ...

И остается применить

   sed 's/#ip_megafon#/'< новый динамический адрес >'/g' /usr/local/etc/squid/squid.conf.etalon > /usr/local/etc/squid/squid.conf

++ Основной скрипт

Итак, получать новые адреса научились. Обновлять в ipfw, менять squid.conf тоже.

Полученные новые адреса пишем во временные файлы, потом сравниваем новый динамический адрес с прежним.
Прежний (текущий) адрес храним в файл /etc/megafon. Если адреса не совпадают, обновляем файл с адресом и запускаем механизм обновления

megafon_get_ip:

    #Получаем новый ip
    awk -f /usr/local/scripts/megafon_get_ip.awk /var/db/dhclient.leases.ue0 > /tmp/megafon_ip
    
    #Получаем новый router. Хотя можно и позже, но для удобства понимания можно и тут
    awk -f /usr/local/scripts/megafon_get_router.awk /var/db/dhclient.leases.ue0 > /tmp/megafon_router
    
    #Сравниваем его с существующим
    ip_new=`cat /tmp/megafon_ip`
    ip_now=`cat /etc/megafon_ip`
    
    if [ $ip_new != $ip_now ]; then
            # Обновляем файлы. Нужно обновлять и таблицы ipfw
            cp /tmp/megafon_ip /etc/megafon_ip
            cp /tmp/megafon_router /etc/megafon_router
    
            #Обновляем ipfw. Эта конструкция не отрубает соединение при обновлении правил ipfw
        sh /etc/rc.firewall > /dev/null 2>&1
    
           #Формируем новый конфиг squid. К сожалению, tcp_outgoing не умеет брать адрес из файла.
            sed 's/#ip_megafon#/'$ip_new'/g' /usr/local/etc/squid/squid.conf.etalon > /usr/local/etc/squid/squid.conf
    
            #Рестарт squid.
            /usr/local/sbin/squid -k reconfigure
    fi

++ Запуск основного скрипта при старте сервера

Для получения динамического адреса самым простым виделось поставить в rc.conf строку ifconfig_ue0="DHCP"

Но модем от Мегафона, его надо инициализировать перед запросом адреса. Заодно обеспечим вызов основного скрипта.
Создал /usr/local/etc/rc.d/megafon

megafon:

    #!/bin/sh
    #
    # PROVIDE: megafon
    # REQUIRE: dhclient
    # KEYWORD: shutdown
    
    . /etc/rc.subr
    
    name=megafon
    
    load_rc_config ${name}
    
    command=/usr/local/etc/megafon
    command_args=""
    
    run_rc_command "$1"

В rc.conf добавляем:

    ...
    megafon="YES"
    ...

Сам стартовый скрипт

/usr/local/etc/megafon:

    #Инициализация модема
    echo 'AT^NDISDUP=1,1,"internet"' > /dev/cuaU1
    #Стартуем клиента
    /sbin/dhclient -b ue0

    #Через 10 секунд надо вызвать обновление таблиц и всего остального. Приводит к 10 секундной задержки старта сервера.
    sleep 10
    #Вызов основного скрипта
    /usr/local/scripts/megafon_get_ip

++ Периодическое обновление

Механизма вызова сторонних скриптов при обновлении динамического адреса не нашел. Если поставить основной скрипт в cron с периодом запуска 1 минута, то при обновлении адреса время потери составит связи не больше 1 минуты.


URL:
Обсуждается: http://www.opennet.me/tips/info/2909.shtml


Содержание

Сообщения в этом обсуждении
"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено Crazy Alex , 16-Июн-15 01:00 
А вот такой штуки у вас там нет, что ли, что ректально всё так? http://linux.die.net/man/8/dhclient-script

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено als , 16-Июн-15 06:13 
Спасибо за наводку.
Попробую dhclient-script
Судя по описанию, он позволит сократить вызов cron
Со squid.conf все равно получается некрасиво.

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено Crazy Alex , 16-Июн-15 16:54 
Он параметром новый IP получает, если что. Так что парсить ничего не нужно.

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено Аноним , 19-Июн-15 03:05 
> Он параметром новый IP получает, если что. Так что парсить ничего не нужно.

Это слишком просто. Как это - не надо выносить коня из горящей избы? День прожит зря!!!


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено _KUL , 16-Июн-15 15:28 
В линуксе я бы сделал маскарадинг для фаервола, а для сквида создал бы виртуальный tap интерфейс, слал бы туда трафик, и создал бы вторую таблицу маршрутизации iproute2 с дефолтным гейтвеем на интерфейс динамика.

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено анонимммм , 16-Июн-15 16:24 
use cisco ?

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено Аноним , 17-Июн-15 23:10 
Нет!

"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено universite , 16-Июн-15 20:18 
Слишком сложно.
1) Используете ipfw NAT на интерфейсе ue0
2) При подключении по dhcp переписываем default (в /etc/dhclient.conf)
3) не трогаем tcp_outgoing_address в aquid
4) Профит!

Еще вариант через setfib и ipfw fwd
получить ip адрес интерфейса:

ifconfig ue0 | awk '/-->/ {print $2}'

Вместо демона megafon - man devd


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено Аноним , 16-Июн-15 21:01 
Что люди только не делают, лишь бы не использовать  pf.

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено getfr , 14-Авг-15 05:56 
я то же самое подумал



"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено ALex_hha , 17-Июн-15 16:34 
Ох блин как много действий

Поднимаем alias (10.0.0.1) на интерфейсе с динамическим ip, прописываем его ip как tcp_outgoing_address в squid.

Маркируем все пакеты с alias ip при помощи:

# iptables -t mangle -A OUTPUT -s 10.0.0.1 -j MARK --set-mark 0x1

маскарадим

# iptables -t nat -A POSTROUTING -o ppp1 -j MASQUERADE

дальше направляем в нужную нам таблицу

# ip rule add fwmark 0x1 table channel2
# ip rule add from 10.0.0.1 table channel2

profit


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено shurik , 19-Июн-15 11:22 
Используйте несколько таблиц маршрутизации:

# echo net.fibs=2 >> /boot/loader.conf
# echo squid_enable=\"YES\" >> /etc/rc.conf
# echo squid_fib=\"1\" >> /etc/rc.conf
# shutdown -r now
# setfib 1 dhclient ue0


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено als , 19-Июн-15 22:30 
Коллеги, спасибо за советы.
Ясно дело, изначально заметка не так красива и ясна, как многие из советов.
Спасибо за отклики, спасибо за рекомендации.
iptables не используется, за сим и мне, лично мне, не пойдет. Но это еще не повод не начать его использовать :)
Спасибо за совет awk к ifconfig, не пришло в голову. Красиво и просто получить адрес. Хотя, тот же awk через dhcpclient получает адрес :) Но сложнее.
По поводу алиаса на ue0, попробую. Пока не скажу :)

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено universite , 20-Июн-15 02:58 

> Хотя, тот же awk через dhcpclient получает адрес :) Но сложнее.

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


data=`cat dhcpd.leases | awk 'tolower($1) ~ /(fixed-address|option routers)/ && \
                        $2 { key=($1=="fixed-address" : tolower($1)); arr[key]=$2 } \
                            END { for (key in arr) print key arr[key] }'`
        set -- ${data}
        case ${1} in
                address:*)      address=${1#fixed-address:}  ;;
                router:*)       router=${1#routers:}        ;;
        esac
        case ${2} in
                address:*)      address=${2#fixed-address:}  ;;
                router:*)       router=${2#routers:}        ;;
        esac

Код скорее всего содержит огрехи, но у меня нет перед глазами живой dhcpd.leases перед глазами.


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено als , 20-Июн-15 15:03 
воспользовался dhclient-script

Добавляем /etc/dhclient-enter-hooks :

if [ $reason == "PREINIT" ]; then
        echo 'AT^NDISDUP=1,1,"internet"' > /dev/cuaU1
fi


Добавляем /etc/dhclient-exit-hooks :
if [ $reason == "BOUND" ]; then
        if [ $new_ip_address != $old_ip_address ]; then
                echo $new_ip_address > /etc/megafon_ip
                echo $new_routers > /etc/megafon_router

                #Обновляем ipfw
                /usr/local/sbin/sh_firewall

                #Формируем новый конфиг squid. К сожалению, tcp_outgoing не умеет брать адрес из файла.
                sed 's/#ip_megafon#/'$new_ip_address'/g' /usr/local/etc/squid/squid.conf.etalon > /usr/local/etc/squid/squid.conf

                #Рестарт squid.
                /usr/local/sbin/squid -k reconfigure
        fi
fi

Уходит вызов скрипта в cron.

Спасибо за советы.


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено маша , 06-Июл-15 22:25 
дешевле и надежней поставить роутер tplink воткнув в него модем.
зачем прокся ? а затем что бы ничего не создавать, а что-нибудь контролировать.
и интернет что бы не нормальный был а тормозной 3G

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено pavlinux , 25-Июл-15 03:47 
Машко, прокси ещё кэширущий бывает, а ещо авторизация, а ещо редиректы,....  

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено XoRe , 27-Июл-15 17:48 
> Машко, прокси ещё кэширущий бывает, а ещо авторизация, а ещо редиректы,....

А ещо запреты роскомнадзора


"Установка параметров шлюза на базе FreeBSD по динамическому адресу"
Отправлено пиу , 09-Июл-15 00:03 
Используйте PF
($ext_if) будет получать ip динамического д линка автоматически

"Установка параметров шлюза на базе FreeBSD по динамическому ..."
Отправлено Аноним , 04-Окт-15 00:44 
> Используйте PF
> ($ext_if) будет получать ip динамического д линка автоматически

Это бесподезно, люди хотят использовать единственно правильный инструмент.