The OpenNET Project / Index page

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

Установка параметров шлюза на базе FreeBSD по динамическому адресу
Введение

На сервере 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 минуты.
 
12.06.2015 , Автор: als
Ключи: freebsd, dhcp, squid, ipfw / Лицензия: CC-BY
Раздел:    Корень / Администратору / Система / FreeBSD специфика / Установка и апгрейд FreeBSD и приложений.

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, Crazy Alex (ok), 01:00, 16/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А вот такой штуки у вас там нет, что ли, что ректально всё так? http://linux.die.net/man/8/dhclient-script
     
     
  • 2.2, als (ok), 06:13, 16/06/2015 [^] [^^] [^^^] [ответить]  
  • +/
    Спасибо за наводку.
    Попробую dhclient-script
    Судя по описанию, он позволит сократить вызов cron
    Со squid.conf все равно получается некрасиво.
     
     
  • 3.5, Crazy Alex (ok), 16:54, 16/06/2015 [^] [^^] [^^^] [ответить]  
  • +/
    Он параметром новый IP получает, если что. Так что парсить ничего не нужно.
     
     
  • 4.11, Аноним (-), 03:05, 19/06/2015 [^] [^^] [^^^] [ответить]  
  • +/
    > Он параметром новый IP получает, если что. Так что парсить ничего не нужно.

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

     

  • 1.3, _KUL (ok), 15:28, 16/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    В линуксе я бы сделал маскарадинг для фаервола, а для сквида создал бы виртуальный tap интерфейс, слал бы туда трафик, и создал бы вторую таблицу маршрутизации iproute2 с дефолтным гейтвеем на интерфейс динамика.
     
     
  • 2.4, анонимммм (?), 16:24, 16/06/2015 [^] [^^] [^^^] [ответить]  
  • +/
    use cisco ?
     
     
  • 3.10, Аноним (-), 23:10, 17/06/2015 [^] [^^] [^^^] [ответить]  
  • +/
    Нет!
     

  • 1.7, universite (ok), 20:18, 16/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Слишком сложно.
    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

     
  • 1.8, Аноним (-), 21:01, 16/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    Что люди только не делают, лишь бы не использовать  pf.
     
     
  • 2.20, getfr (?), 05:56, 14/08/2015 [^] [^^] [^^^] [ответить]  
  • +/
    я то же самое подумал


     

  • 1.9, ALex_hha (ok), 16:34, 17/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Ох блин как много действий

    Поднимаем 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

     
  • 1.12, shurik (??), 11:22, 19/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Используйте несколько таблиц маршрутизации:

    # 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

     
  • 1.13, als (ok), 22:30, 19/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Коллеги, спасибо за советы.
    Ясно дело, изначально заметка не так красива и ясна, как многие из советов.
    Спасибо за отклики, спасибо за рекомендации.
    iptables не используется, за сим и мне, лично мне, не пойдет. Но это еще не повод не начать его использовать :)
    Спасибо за совет awk к ifconfig, не пришло в голову. Красиво и просто получить адрес. Хотя, тот же awk через dhcpclient получает адрес :) Но сложнее.
    По поводу алиаса на ue0, попробую. Пока не скажу :)
     
     
  • 2.14, universite (ok), 02:58, 20/06/2015 [^] [^^] [^^^] [ответить]  
  • +/

    > Хотя, тот же 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 перед глазами.

     

  • 1.15, als (ok), 15:03, 20/06/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    воспользовался 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.

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

     
  • 1.16, маша (??), 22:25, 06/07/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    дешевле и надежней поставить роутер tplink воткнув в него модем.
    зачем прокся ? а затем что бы ничего не создавать, а что-нибудь контролировать.
    и интернет что бы не нормальный был а тормозной 3G
     
     
  • 2.18, pavlinux (ok), 03:47, 25/07/2015 [^] [^^] [^^^] [ответить]  
  • +/
    Машко, прокси ещё кэширущий бывает, а ещо авторизация, а ещо редиректы,....  
     
     
  • 3.19, XoRe (ok), 17:48, 27/07/2015 [^] [^^] [^^^] [ответить]  
  • +/
    > Машко, прокси ещё кэширущий бывает, а ещо авторизация, а ещо редиректы,....

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

     

  • 1.17, пиу (?), 00:03, 09/07/2015 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Используйте PF
    ($ext_if) будет получать ip динамического д линка автоматически
     
     
  • 2.21, Аноним (-), 00:44, 04/10/2015 [^] [^^] [^^^] [ответить]  
  • +/
    > Используйте PF
    > ($ext_if) будет получать ip динамического д линка автоматически

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

     


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




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

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