Pull to refresh

Продвинутый роутер на DD-Wrt

Продвинутый роутер на DD-Wrt


Когда-то давно когда я впервые поставил dd-wrt на свой роутер (Dlink dir-615), я просто подумал что это прошивка ну как бы просто «еще одна прошивка» для тех кто недоволен стандартной от производителя роутера, однако подключившись по telnet к роутеру я увидел самый что не на есть Linux.

В статье ни будет ни слова о том как прошить роутер. Это делается весьма индивидуально для каждой модели роутера. Зато будет то как настроить на нем 2 точки доступа и в целом оптимизировать, а также создавать туннели между такими роутерами.


Просто Linux

Сходив по телнету на роутер можно увидеть самый обычный Linux. Ну так как в комплекте Linux то наверняка есть:
— Фаервол Iptables
— поддержка ip_conntrack
— утилиты из iproute2.

Также наверняка есть дополнительные утилиты:
— brctl (для управления мостами)
— ping, telnet, ssh, mount и все что полагается иметь обычному сетевому маршрутизатору на Linux

Две точки доступа или как осчастливить соседей

Когда я увидел что в настройках Wi-Fi есть возможность создать еще одну точку доступа, я как бы удивился. Оказывается почти все чипы Wi-Fi это умеют, только добрые дяди из $vendor обычно такой функционал считают лишним для домохозяек (а много ли домохозяек настраивают роутеры).
Постепенно разбираясь во всем я решил обеспечить всей улице (у роутера 2 антенны и очень неплохая мощьность) бесплатный интернет, передо мной стало 2 проблемы (решение которых я и опишу далее):
1. Как обеспечить моей домашней сети безопасность путем отрезания доступа в нее с бесплатной точки доступа.
2. Как порезать скорость, чтобы добрые соседи не поедали мой канал.

Ну решение первого прозрачно, фаервол. Но как, что и где не понятно. Второе же тоже понятно, раз есть iproute2 есть и tc, а он может… да чего он только не может.

Создаем точку (Конфигурация интерфейса)

точки доступа создаем вторую точку доступа и называем ее как нибудь

дополнительно Открываем дополнительные параметры, и устанавливаем «Конфигурация Сети: Не в мосте», «Многоадресные потоки: Отключить», «Masquerade/NAT: Отключить». И вибираем ip адрес для этого виртуального интерфейса, я выбрал маленькую сеть на 16 ip адресов.

шифрование Далее надо убедиться что отключено шифрование на этой точке.

Комманды

комманды Переходим к командному блоку.

Настройка sysctl

Сначала предлагаю настроить sysctl, так как самой утилиты sysctl нет в комплекте, то настроим через proc

echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
echo "1" > /proc/sys/net/ipv4/tcp_abort_on_overflow
echo "0" > /proc/sys/net/ipv4/tcp_ecn
echo "600" > /proc/sys/net/ipv4/tcp_fin_timeout
echo "750" > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo "9" > /proc/sys/net/ipv4/tcp_keepalive_probes
echo "7200" > /proc/sys/net/ipv4/tcp_keepalive_time
echo "65536" > /proc/sys/net/ipv4/tcp_max_orphans
echo "1024" > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo "180000" > /proc/sys/net/ipv4/tcp_max_tw_buckets
echo "1" > /proc/sys/net/ipv4/tcp_orphan_retries
echo "3" > /proc/sys/net/ipv4/tcp_reordering
echo "1" > /proc/sys/net/ipv4/tcp_retrans_collapse
echo "3" > /proc/sys/net/ipv4/tcp_retries1
echo "15" > /proc/sys/net/ipv4/tcp_retries2
echo "0" > /proc/sys/net/ipv4/tcp_rfc1337
echo "4096 87380 4194304" > /proc/sys/net/ipv4/tcp_rmem
echo "1" > /proc/sys/net/ipv4/tcp_sack
echo "5" > /proc/sys/net/ipv4/tcp_syn_retries
echo "5" > /proc/sys/net/ipv4/tcp_synack_retries
echo "1" > /proc/sys/net/ipv4/tcp_timestamps
echo "1" > /proc/sys/net/ipv4/tcp_window_scaling
echo "196608 262144 393216" > /proc/sys/net/ipv4/tcp_mem
echo "4096 16384 4194304" > /proc/sys/net/ipv4/tcp_wmem
echo "65535" > /proc/sys/net/ipv4/ip_conntrack_max
echo "65535" > /proc/sys/net/netfilter/nf_conntrack_max
echo "65535" > /proc/sys/net/ipv4/netfilter/ip_conntrack_max
echo "65535" > /proc/sys/net/nf_conntrack_max
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo "6168" > /proc/sys/net/ipv4/icmp_ratemask
echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
echo "1" > /proc/sys/net/ipv4/conf/all/arp_filter
echo "0" > /proc/sys/net/ipv4/conf/all/log_martians
echo "0" > /proc/sys/net/ipv4/conf/all/mc_forwarding
echo "0" > /proc/sys/net/ipv4/conf/all/proxy_arp
echo "1" > /proc/sys/net/ipv4/conf/all/secure_redirects
echo "1" > /proc/sys/net/ipv4/conf/all/send_redirects
echo "1" > /proc/sys/net/ipv4/conf/all/shared_media
echo "500" > /proc/sys/net/ipv4/route/error_cost
echo "262144" > /proc/sys/net/ipv4/ipfrag_high_thresh
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo "1024 4999" > /proc/sys/net/ipv4/ip_local_port_range
echo "1" > /proc/sys/net/ipv4/ip_no_pmtu_disc
echo "0" > /proc/sys/net/ipv4/ip_nonlocal_bind
echo "30" > /proc/sys/net/ipv4/ipfrag_time
echo "120" > /proc/sys/net/ipv4/inet_peer_gc_maxtime
echo "10" > /proc/sys/net/ipv4/inet_peer_gc_mintime
echo "600" > /proc/sys/net/ipv4/inet_peer_maxttl
echo "120" > /proc/sys/net/ipv4/inet_peer_minttl
echo "65664" > /proc/sys/net/ipv4/inet_peer_threshold
echo "2" > /proc/sys/net/ipv4/tcp_adv_win_scale
echo "31" > /proc/sys/net/ipv4/tcp_app_win
echo "1" > /proc/sys/net/ipv4/tcp_dsack
echo "0" > /proc/sys/net/ipv4/tcp_ecn
echo "1" > /proc/sys/net/ipv4/tcp_fack
echo "20" > /proc/sys/net/ipv4/igmp_max_memberships
echo "0" > /proc/sys/net/ipv4/conf/all/bootp_relay

вставляем код в textarea в блоке Команды, и нажимаем «Сохранить параметры запуска» (Save startup)

фаервол iptables

Ниже приведу команды своего фаервола, думаю кому-то будет интересно что зачем, поэтому команды комментируются.

#####################################
# Назначаем дисциплиной обработки очереди htb
tc qdisc add dev `nvram get wan_ifnames` root handle 1: htb default 2
# создаем класс в 100 мегабит, и дисциплину sfq для равномерного распределения трафика между клиентами
tc class add dev `nvram get wan_ifnames` parent 1: classid 1:1 htb rate 100mbit
tc qdisc add dev `nvram get wan_ifnames` parent 1:1 handle 2: sfq perturb 10

# Режем скорость на интерфейсе ath0.1 наша точка для гостей и соседей
tc class add dev `nvram get wan_ifnames` parent 1: classid 1:3 htb rate 1024kbit
tc qdisc add dev `nvram get wan_ifnames` parent 1:3 handle 3: sfq perturb 10
# все пакеты помеченные флагом 0x2ff будут попадать в эту дисциплину
tc filter add dev `nvram get wan_ifnames` parent 1:0 protocol ip prio 1 handle 0x2ff fw classid 1:3
# а вот правило фаервола.
# если пакеты вылетают в wan порт, а прилетают с интерфейса ath0.1 тогда поставить им метку 0x2ff
iptables -t mangle -A FORWARD -o `nvram get wan_ifnames` -i ath0.1 -j MARK --set-mark 0x2ff

# С ath0.1 исходящий трафик порезан, теперь надо порезать трафик приходящий на ath0.1
# добавляем дисциплину
tc qdisc add dev ath0.1 root handle 1: htb default 1
# все что вылетает на ath0.1 летит в очередь 1:1 с указанной скоростью
tc class add dev ath0.1 parent 1: classid 1:1 htb rate 1024kbit

# Теперь правило которое отбрасывает все пакеты которые направляются с ath0.1 и НЕ во внешний мир
iptables -t nat -I POSTROUTING -j SNAT -s `nvram get ath0.1_ipaddr`/`nvram get ath0.1_netmask` -o `nvram get wan_ifnames` --to-source `nvram get wan_ipaddr`
iptables -I FORWARD -i ath0.1 ! -o `nvram get wan_ifnames` -j DROP
#####################################
# Далее я удаляю какое-то магическое правило с роутера, зачем оно нужно ума не приложу, ну и не нужно оно
iptables -t nat -D POSTROUTING -o br0 -j MASQUERADE -s `nvram get lan_ipaddr`/`nvram get lan_netmask` -d `nvram get lan_ipaddr`/`nvram get lan_netmask`

# Стандартный SNAT направляет все пакеты со всех подсетей и со всех интерфейсов кроме WAN
# в интернет натируя трафик, мне это неподходит, да и вам не подходит, ведь на очереди тунели.
# удаляем это правило
iptables -t nat -D POSTROUTING -j SNAT -o `nvram get wan_ifnames` --to `nvram get wan_ipaddr`
# и добавляем правило которое натирует только подсеть на портах LAN
iptables -t nat -I POSTROUTING -j SNAT -s `nvram get lan_ipaddr`/`nvram get lan_netmask` -o `nvram get wan_ifnames` --to-source `nvram get wan_ipaddr`

# некоторые простые защиты
# Игнор всего фрагментированного
iptables -A INPUT -f -j DROP
# Ограничение колличества syn пакетов (Anty SYN Flood)
iptables -A INPUT -p tcp --syn -m limit --limit 100/second --limit-burst 150 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
# игнор пакетов с "неправильными" флагами
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# Так как проц не резиновый а телнет демон, чтобы не зафлудили по telnet
iptables -A INPUT -i `nvram get wan_ifnames` -p tcp --dport 23 -m state --state NEW -m recent --set --name TELNET
iptables -A INPUT -i `nvram get wan_ifnames` -p tcp --dport 23 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name TELNET -j DROP
# И наконец корректная обработка tcp при разных MTU
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o tun0 -j TCPMSS --clamp-mss-to-pmtu

################################################
# Далее я пишу 2 скрипта, которые в дальнейшем организуют туннели
# про это далее
################################################
insmod etherip
mount -t tmpfs none /opt
echo '#!/bin/sh' > /opt/etherip.sh
echo 'ip tunnel del $1 2>&1 > /dev/null' >> /opt/etherip.sh
echo 'ip tunnel add $1 mode etherip remote $2 local `nvram get wan_ipaddr`' >> /opt/etherip.sh
echo 'ip addr add $3 dev $1' >> /opt/etherip.sh
echo 'ip link set $1 up' >> /opt/etherip.sh
chmod a+x /opt/etherip.sh
# /opt/etherip.sh tun-name remote IFace

echo '#!/bin/sh' > /opt/gre.sh
echo 'ip tunnel del $1 2>&1 > /dev/null' >> /opt/gre.sh
echo 'ip tunnel add $1 mode gre remote $2 key $3 ttl 255' >> /opt/gre.sh
echo 'ip addr add $4 peer $5 dev $1' >> /opt/gre.sh
echo 'ip link set $1 up' >> /opt/gre.sh
chmod a+x /opt/gre.sh
# /opt/gre.sh tun-name remote KEY localIP remoteIP


Так, вроде все готово, теперь о том как клиенты свободной точки будут получать IP. DHCP конечно, только вот нужен второй DHCP сервер, и он есть из коробки.
image

Туннели

Итак теперь представьте ситуацию. У вас есть 2 офиса, в них… стоп. Все проще, у вас есть друг с dd-wrt, также у вас есть банальное желание поиграть с ним… ну скажем в queke II coop. У друга один провайдер а у вас другой. Ну казалось бы ответ очевиден, Hamachi или всякое-там разное проприетарное. Отличное решение обычной проблемы. а теперь представим что всетаки есть 2 офиса, и коннект должен быть 24*7*365 и мало того там есть всякие принтеры, пусть даже корпоративный прокси. Cisco, скажете вы, дороговато, скажу я.
Обратим внимание на 2 скрипта приведенные в файерволе, да это туннелирование gre или ethernet over ip (протокол etherip поддерживаемый freebsd cisco но почему-то не поддерживаемый в Linux). Логика создания туннеля такова.

Есть 2 устройства alpha и beta, на устройстве alpha lan подсеть 192.168.2.0/24, на устройстве beta 192.168.3.0/24. На устройстве alpha wan IP al.p.h.a на beta b.e.t.a. На alpha создается интерфейс 10.0.0.1/30 на beta 10.0.0.2/30 и 2 маршрута.

ALPHA
/opt/etherip.sh beta b.e.t.a 10.0.0.1/30
route add -net 192.168.3.0/24 gw 10.0.0.2


BETA
/opt/etherip.sh alpha al.p.h.a 10.0.0.2/30
route add -net 192.168.2.0/24 gw 10.0.0.1


Общая логика такова. Так к чему я про друга с quake II, лучше попробуйте с ним. Не надо экспериментов в production.

Что дальше?


К сожалению у меня сейчас потерян коннект с роутером dir-320 в который были воткнуты 3 провайдра. Дело в том, что на dir-320 мало того что есть usb и туда можно поставить какой нибудь nginx+postgresql+python+django, так у него внутри умный свитч, а это значит что там создается 3 интерфейса в портах lan, а порт wan включается в конторский свитч. В итоге балансировка, отказоустойчивость, wi-fi, firewall, банилка «xxxxклассников».
Эта контора звонила мне год назад, сказали что к ним пришел специалист и что он спрашивает пароль на роутер, утверждая что я перепутал порты WAN и LAN, я спросил «А у вас все работает?», они ответили утвердительно, тогда я спросил зачем от туда лезет и они внятно мне не объяснили, я сказал «Я дам вам пароль но если этот мастер что нибудь сломает, то я к вам не поеду, а если и поеду то проделаю все работу заново, а это стоит столько же», в общем пароль им не пригодился, год уже не звонят. Бог знает может уже развалились, а может ip сменился, но доступа сейчас нет.

Вообще возможности dd-wrt мне напоминают cisco. В том смысле что если уж reboot не помог, то что-то сломалось не в этой железке.

Все команды я попытался завязать на nwram роутеров, чтобы разные модели работали одинаково. Единственная разница это имя wi-fi адаптера может быть другим. Ну тогда заменяем все ath на имя вашего адаптера в командах.

Удачных экспериментов.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.