|
Ключевые слова: freebsd, vpn, mpd, limit, traffic, pf, firewall, (найти похожие документы)
From: Vit <artemrts@ukr.net.> Newsgroups: email Date: Mon, 15 Jul 2009 14:31:37 +0000 (UTC) Subject: Раздача Интернета через VPN (mpd) с ограничением траффика по пользователям средствами PF В этой статье хочу описать как я настроил vpn-сервер для раздачи Инета на базе mpd5.3 в связке с пакетным фильтром PF с ограничением трафика. Почему именно такая конструкция? Просто мне необходимо было решение раздачи интернета пользователям с шифрованием, и плюс ограничивать и приоретизировать трафик дабы всем хватало. Можно было использовать функции mpd для "нарезки" канала, но мне не хотелось заморачиваться с радиусом и т.д. Поэтому было принято решение строить из того з чем умею работать :-). В PF будем использовать такие фичи как anchors и Packet Tagging (Policy Filtering). Разжевывать каждый параметр не буду, поэтому читающий должен иметь некий опыт работы в сетевом администрировании в общем и во FreeBSD в частности. Настройка vpn будет показана на примере виртуальной машины на базе VMWare, на которой я всю эту систему отрабатывал. Имеем: Inet <---- 10.0.10.182/16:le0 [FreeBSD VPN-server] le1:172.16.1.1/24<-------------->LAN ng0:192.168.1.1<------------>192.168.1.2 ng1:192.168.1.1<------------>192.168.2.3 ...... OS: FreeBSD 7.2-RELEASE LAN: 172.16.1.0/24 External IP:10.0.10.182/16 IP адреса, которые будут назначаться vpn-клиентам: 192.168.1.2, 192.168.1.3 1. Подготовка системы 1.1 Перед обновлением дабы удобнее было работать установим МС: pkg_add -r mc-lite Так же необходимо запустить DNS-сервер и "повесить" его на внутренний интерфейс. Объяснение как это сделать выходят за рамки статьи. 1.2. Обновляем исходники, как это сделать - читаем handbook. 1.3. Далее создаем файл /etc/src.conf и исключаем все, что не требуется для работы сервера. WITHOUT_ATM=true WITHOUT_BLUETOOTH=true WITHOUT_GAMES=true WITHOUT_I4B=true WITHOUT_INET6=true WITHOUT_INET6_SUPPORT=true WITHOUT_IPFILTER=true WITHOUT_PROFILE=true WITHOUT_USB=true WITHOUT_ZFS=true WITHOUT_IPX=true WITHOUT_IPX_SUPPORT=true WITHOUT_LPR=true WITHOUT_NCP=true WITHOUT_RCMDS=true WITHOUT_RCS=true WITHOUT_HTML=true WITHOUT_SENDMAIL=true 1.4. Далее правим /etc/make.conf Здесь я приведу только то, что изменял в этом файле, комментарии удалены. CPUTYPE?=pentium4 CFLAGS= -O2 -fno-strict-aliasing -pipe CXXFLAGS+= -fconserve-space MAKE_SHELL=sh COPTFLAGS= -O2 -pipe BOOT_COMCONSOLE_SPEED= 115200 PERL_VERSION=5.8.9 WANT_FORCE_OPTIMIZATION_DOWNGRADE=1 1.5. Для бересборки ядра редактируем GENERIC. Его я переименовал в MYGENERIC1. Понятное дело, что каждый сам должен править конфиг под свое железо, я приведу только то что необходимо для работы. Закоментируем следующие строчки: #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols #options INET6 # IPv6 communications protocols #options SCTP # Stream Control Transmission Protocol #options NFSCLIENT # Network Filesystem Client #options NFSSERVER # Network Filesystem Server #options NFSLOCKD # Network Lock Manager #options NFS_ROOT # NFS usable as /, requires NFSCLIENT И добавим: ### for mpd options NETGRAPH options NETGRAPH_BPF options NETGRAPH_IFACE options NETGRAPH_KSOCKET options NETGRAPH_MPPC_ENCRYPTION options NETGRAPH_MPPC_COMPRESSION options NETGRAPH_PPP options NETGRAPH_PPTPGRE options NETGRAPH_SOCKET options NETGRAPH_TCPMSS options NETGRAPH_VJC options NETGRAPH_ETHER options NETGRAPH_TEE options NETGRAPH_ONE2MANY options NETGRAPH_NETFLOW ### for PF device pf device pflog #device pfsync #device carp options ALTQ options ALTQ_CBQ options ALTQ_RED options ALTQ_RIO options ALTQ_HFSC options ALTQ_CDNR options ALTQ_PRIQ options ALTQ_NOPCC ### others options IPSTEALTH В базовую систему не включен код MPPC compression, поэтому нужно его добавить. Сам код и инструкция что куда копировать находятся на сайте http://www.mavhome.dp.ua/MPPC/ 1.6. Далее делаем пересборку мира и ядра. Из /usr/src/makefile: # 1. 'd /usr/src' (or to the directory containing your source tree). # 2. 'make buildworld' # 3. 'make buildkernel KERNCONF=YOUR_KERNEL_HERE' (default is GENERIC). # 4. 'make installkernel KERNCONF=YOUR_KERNEL_HERE' (default is GENERIC). # [steps 3. & 4. can be combined by using the "kernel" target] # 5. 'reboot' (in single user mode: boot -s from the loader prompt). # 6. 'mergemaster -p' # 7. 'make installworld' # 8. 'make delete-old' # 9. 'mergemaster' (you may wish to use -U or -ai). # 10. 'reboot' # 11. 'make delete-old-libs' (in case no 3rd party program uses them anymore) Лично я последний пункт не делал. Если все прошло успешно, получаем: FreeBSD gw1.local 7.2-RELEASE-p2 FreeBSD 7.2-RELEASE-p2 #3: Mon Jul 6 16:28:52 EEST 2009 root@gw1.local:/usr/obj/usr/src/sys/MYGENERIC1 i386 Более подробно про обновление системы смотрим здесь 2. Устанвливаем MPD Ставим из портов. cd /usr/ports/net/mpd5 make make install clean Нам понадобиться 2 конфига в /usr/local/etc/mpd5 следующего содержания: а) mpd.conf startup: # configure mpd users #set user foo bar admin #set user foo1 bar1 # configure the console #set console self 127.0.0.1 5005 #set console open # configure the web server #set web self 172.16.1.1 5006 #set web open # default: load pptp_server pptp_server: set ippool add pool1 192.168.1.2 192.168.1.10 # Create clonable bundle template named B create bundle template B set iface up-script /usr/local/etc/mpd5/if-up.sh set iface down-script /usr/local/etc/mpd5/if-down.sh set iface enable proxy-arp set iface idle 1800 set iface enable tcpmssfix set ipcp yes vjcomp # Specify IP address pool for dynamic assigment. set ipcp ranges 192.168.1.1/32 ippool pool1 set ipcp dns 172.16.1.1 # The five lines below enable Microsoft Point-to-Point encryption # (MPPE) using the ng_mppc(8) netgraph node type. set bundle enable compression set bundle enable crypt-reqd set ccp yes mppc set mppc yes compress e40 e56 e128 stateless # Create clonable link template named L create link template L pptp # Set bundle template to use set link action bundle B # Multilink adds some overhead, but gives full 1500 MTU. set link enable multilink set link yes acfcomp protocomp set link disable pap chap eap set link enable chap chap-msv1 chap-msv2 chap-md5 # We can use use RADIUS authentication/accounting by including # another config section with label 'radius'. # load radius set link keep-alive 10 60 # We reducing link mtu to avoid GRE packet fragmentation. set link mtu 1460 set link mru 1460 # Configure PPTP set pptp self 172.16.1.1 # Allow to accept calls set pptp disable windowing set link enable incoming б) mpd.secret test1 "test1" 192.168.1.2 test2 "test2" 192.168.1.3 в) Скрипты, которые будут запускаться при старте и шатдауне интерфейсов ng if-up.sh #!/bin/sh echo "nat on le0 tag from_$4 tagged from_$4 -> le0" | pfctl -a mpd-nat/$4 -f -; echo "pass out quick on le0 inet tagged from_$4 queue $4_up" | pfctl -a ext_if-out/$4 -f -; echo "pass in quick on $1 inet from $1:peer $4 to any tag from_$4 queue $4_down" | pfctl -a ng-in/$4 -f -; if-down.sh #!/bin/sh pfctl -a mpd-nat/$4 -F all; pfctl -a ext_if-out/$4 -F all; pfctl -a ng-in/$4 -F all; Пояснения: $1 - обозначает интерфейс (ng0, ng1, ...) $4 - IP-адрес, выдаваемый клиенту. Скрипт if-up.sh будет добавлять правило для NATa, назначать нужную нам очередь на внешнем интерфейсе и назначать тег и очередь на внутреннем. Скрипт if-down.sh удаляет все правила, кроме самих очередей. 3. Настройка PF 3.1. Добавляем запись в /etc/rc.conf pf_enable="YES" pflog_enable="YES" 3.2. Создаем файл /etc/pf.conf с таким содержанием ext_if="le0" int_if="le1" lan="172.16.1.0/24" pc1="172.16.1.2" pc2="172.16.1.3" set skip on lo set loginterface le0 set ruleset-optimization basic set block-policy return set limit { states 20000 frags 20000 } set timeout {adaptive.start 15000 adaptive.end 45000} set state-policy if-bound scrub on $ext_if all random-id min-ttl 128 reassemble tcp fragment reassemble scrub on $int_if all ### ALTQ altq on $int_if cbq bandwidth 100Mb qlimit 50 queue { def_download } queue def_download bandwidth 100% cbq(default) {192.168.1.2_down,192.168.1.3_down, ...} queue 192.168.1.2_down bandwidth 512Kb cbq(ecn) queue 192.168.1.3_down bandwidth 1024Kb cbq(ecn) ...... altq on $ext_if cbq bandwidth 10Mb qlimit 50 queue { def_upload } queue def_upload bandwidth 100% cbq(default) {192.168.1.2_up,192.168.1.3_up, ...} queue 192.168.1.2_up bandwidth 128Kb cbq(ecn) queue 192.168.1.3_up bandwidth 128Kb cbq(ecn) ...... ### NAT nat-anchor "mpd-nat/*" ### RULES block in block out antispoof quick for { lo $int_if } inet ### EXT_IF_OUT anchor "ext_if-out/*" pass out quick on $ext_if inet proto {tcp udp} from $ext_if to any port 53 ### EXT_IF_IN pass in quick on $ext_if inet proto tcp from any to $ext_if port ssh synproxy state ### INT_IF_IN anchor "ng-in/*" pass in quick on $int_if inet proto {tcp udp} from $lan to $int_if port {53 1723} ### INT_IF_OUT pass out quick on $int_if inet proto gre from $int_if to $lan ### THE END 4. И на последок немного тюнинга ### secur security.bsd.see_other_uids=0 security.bsd.see_other_gids=0 security.bsd.unprivileged_read_msgbuf=0 security.bsd.unprivileged_proc_debug=0 security.bsd.conservative_signals=0 net.inet.ip.portrange.first=1025 net.inet.ip.portrange.last=65535 net.inet.ip.ttl=128 net.inet.ip.stealth=1 net.inet.ip.forwarding=1 net.inet.ip.check_interface=1 net.inet.ip.random_id=1 net.inet.tcp.blackhole=2 net.inet.udp.blackhole=1 net.inet.icmp.maskfake=1 net.inet.ip.redirect=0 ### inet kern.ipc.maxsockbuf=1048576 #default 262144 kern.ipc.somaxconn=1024 #deault 128 net.inet.tcp.sendspace=65536 net.inet.tcp.recvspace=65536 net.inet.tcp.sendbuf_max=1048576 #default 262144 net.inet.tcp.recvbuf_max=1048576 #default 262144 net.local.stream.sendspace=65536 net.local.stream.recvspace=65536 net.inet.ip.intr_queue_maxlen=4096 net.inet.tcp.nolocaltimewait=1 Для работы системы необходимо записать Логин\Пароль и назначаемый клиенту IP-адрес в mpd.secret. В файле pf.conf сразу надо забить очереди с нужными ограничениями для даного IP-адреса. 5. Проверяем, что получилось. 5.1. Нам понадобиться утилита pftop. Устанавливаем, как всегда, из портов: cd /usr/ports/sysutils/pftop make make install clean rehash Подключимся с первого ПК (172.16.1.2) Вывод ifconfig: ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1218 inet 192.168.1.1 --> 192.168.1.2 netmask 0xffffffff Вывод команды pfctl -sq: queue root_le1 on le1 bandwidth 10Mb priority 0 cbq( wrr root ) {def_download} queue def_download on le1 bandwidth 10Mb cbq( default ) {192.168.1.2_down, 192.168.1.3_down} queue 192.168.1.2_down on le1 bandwidth 512Kb cbq( red ecn ) queue 192.168.1.3_down on le1 bandwidth 1.02Mb cbq( red ecn ) queue root_le0 on le0 bandwidth 10Mb priority 0 cbq( wrr root ) {def_upload} queue def_upload on le0 bandwidth 10Mb cbq( default ) {192.168.1.2_up, 192.168.1.3_up} queue 192.168.1.2_up on le0 bandwidth 256Kb cbq( red ecn ) queue 192.168.1.3_up on le0 bandwidth 256Kb cbq( red ecn ) Смотрим состояние очередей в pftop: Клиент закачивает. Видно, что скорость ограничивается 512Кбитами pfTop: Up Queue 1-8/8, View: queue, Cache: 10000 11:30:33 QUEUE BW SCH PR PKTS BYTES DROP_P DROP_B QLEN BORR SUSP P/S B/S root_le1 10M cbq 0 4829 3853K 0 0 0 0 0 109 63K def_download 10M cbq 31 1522 0 0 0 0 0 1.0 72 192.168.1.2_do 512K cbq 4798 3851K 44 36483 6 0 1207 108 63K <-- 192.168.1.3_do 1024K cbq 0 0 0 0 0 0 0 0 0 root_le0 10M cbq 0 2841 173K 0 0 0 0 0 63 3821 def_upload 10M cbq 86 22388 0 0 0 0 0 1.0 245 192.168.1.2_up 256K cbq 2755 151K 0 0 0 0 0 62 3575 192.168.1.3_up 256K cbq 0 0 0 0 0 0 0 0 0 Клиент закачивает, скорость ограничивается 256Кбитами. pfTop: Up Queue 1-8/8, View: queue, Cache: 10000 11:32:31 QUEUE BW SCH PR PKTS BYTES DROP_P DROP_B QLEN BORR SUSP P/S B/S root_le1 10M cbq 0 577 45074 0 0 0 0 0 29 2198 def_download 10M cbq 198 9136 0 0 0 0 0 10 497 192.168.1.2_do 512K cbq 379 35938 0 0 0 0 0 18 1700 192.168.1.3_do 1024K cbq 0 0 0 0 0 0 0 0 0 root_le0 10M cbq 0 665 561K 0 0 0 0 0 37 30K def_upload 10M cbq 37 17882 0 0 0 0 0 1.0 277 192.168.1.2_up 256K cbq 628 544K 9 6834 9 0 150 36 30K <-- 192.168.1.3_up 256K cbq 0 0 0 0 0 0 0 0 0 Ниже приведу результаты вывода команды pfctl, демонстрирующие, что правила для NAT и фильтрации загрузились правильно с помощью якорей. pfctl -a ext_if-out/192.168.1.2 -sr pass out quick on le0 inet all flags S/SA keep state queue 192.168.1.2_up tagged from_192.168.1.2 pfctl -a mpd-nat/192.168.1.2 -sn nat on le0 inet all tag from_192.168.1.2 tagged from_192.168.1.2 -> 10.0.10.182 pfctl -a ng-in/192.168.1.2 -sr pass in quick on ng0 inet from 192.168.1.2 to any flags S/SA keep state queue 192.168.1.2_down tag from_192.168.1.2 После того, как клиент отключился, все правила удаляются. 6. Выводы. Какие вижу минусы? Необходимость прописывать в конфиге pf.conf очереди для всех пользователей, и они не дожны удаляться. Тоже касается и mpd.secret. Думаю написать скриптик, запустив который, будет запрашиваться IP-адрес, ширина канала, логин\пароль и назначаемый mpd IP-адрес, а далее скрипт будет записывать введенные данные в соответствующие места конфиграционных файлов. При большом кол-ве пользователей большое кол-во правил для фаервола, что может снизить производительность.
|
Обсуждение | [ Линейный режим | Показать все | RSS ] |
|
Добавить комментарий |
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |