Настройка OpenWRT, mwan3, adblock, openvpn, IPv6 (6in4) ч.3 заключительная
В этой части привожу конфигурацию маршрутизатора, который занят балансировкой трафика от других маршрутизаторов. Грубо говоря сумматор.
Файл скрипта для NATv6 и маскарадинга IPv6 /etc/firewall.nat6
Приведен пример файлов для таблиц ipset.
Большинство описаний опций я опущу, так как часть из них описана в ч.2.
****************************
/etc/config/network
config interface 'lan'
option ifname 'eth0.1'
option proto 'static'
option ipaddr '192.168.1.1' # адрес балансирующего маршрутизатора
option netmask '255.255.255.0'
option ip6assign '60'
option force_link '0'
option delegate '0'
config device 'wan_eth0_1010_dev'
option name 'eth0.1010'
option macaddr 'хх:хх:хх:хх:хх:хх'
config device 'wan_eth0_1020_dev'
option name 'eth0.1020'
option macaddr 'хх:хх:хх:хх:хх:хх'
config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'
config switch_vlan
option device 'switch0'
option vlan '1'
option ports '5t 0 1 2'
config switch_vlan
option device 'switch0'
option vlan '1020'
option ports '5t 4t'
config switch_vlan
option device 'switch0'
option vlan '1010'
option ports '5t 3t'
config interface 'wan41' # интерфес IPv4 для первого провайдера от вышестоящего маршрутизатора
option proto 'dhcp'
option ifname 'eth0.1010'
option metric '10'
option delegate '0'
config interface 'wan42' # # интерфес IPv4 для второго провайдера от вышестоящего маршрутизатора
option proto 'dhcp'
option ifname 'eth0.1020'
option metric '11'
option delegate '0'
config interface 'wan61' # интерфес IPv6 для первого провайдера от вышестоящего маршрутизатора
option proto 'dhcpv6'
option reqprefix 'auto'
option ifname 'eth0.1010'
option reqaddress 'force'
option metric '20'
option delegate '0'
config interface 'wan62' # интерфес IPv6 для первого провайдера от вышестоящего маршрутизатора
option proto 'dhcpv6'
option reqprefix 'auto'
option ifname 'eth0.1020'
option reqaddress 'force'
option metric '21'
option delegate '0'
config route # маршрут для доступа к самому первому маршрутизатору, подробней описано в первой части
option interface 'wan41'
option gateway '192.168.10.1'
option target '192.168.0.1'
config route # маршрут для доступа к самому первому маршрутизатору, подробней описано в первой части
option interface 'wan42'
option gateway '192.168.20.1'
option target '192.168.0.2'
Ранее писал что непосредственно к кабелю провайдера, который заходит в квартиру, у меня подключены дешевые 100 мегабитные маршрутизаторы. Что бы получить к ним доступ для настроек и прописаны эти маршруты. Более подробней зачем я их подключил описано в первой части публикаций.
****************************
/etc/config/dhcp
config dnsmasq
option domainneeded '1'
option localise_queries '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option rebind_protection '0'
option allservers '1'
option localservice '1'
option filterwin2k '1'
option quietdhcp '1'
option ednspacket_max '4096'
option resolvfile '/tmp/resolv.conf.auto'
option cachesize '10000'
option dnsforwardmax '200'
list notinterface 'wan62'
list notinterface 'wan41'
list notinterface 'wan42'
list notinterface 'wan61'
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option dhcpv6 'server'
option ra 'server'
option force '1'
option ra_default '1'
option ra_management '1'
option leasetime '5m'
config dhcp 'wan41'
option interface 'wan41'
option ignore '1'
config dhcp 'wan42'
option interface 'wan42'
option ignore '1'
config dhcp 'wan61'
option interface 'wan61'
option ignore '1'
config dhcp 'wan62'
option interface 'wan62'
option ignore '1'
****************************
/etc/config/firewall
config defaults
option input 'ACCEPT'
option output 'ACCEPT'
option syn_flood '1'
option drop_invalid '1'
option flow_offloading '1'
option flow_offloading_hw '1'
option forward 'ACCEPT'
config include 'nat6'
option type 'script'
option path '/etc/firewall.nat6'
option family 'any'
option reload '1'
config zone
option input 'ACCEPT'
option forward 'ACCEPT'
option name 'lan'
option output 'ACCEPT'
option network 'lan'
config zone
option family 'ipv4'
option name 'wan41'
option masq '1'
option masq6 '0'
option masq6_privacy '0'
option output 'ACCEPT'
option input 'ACCEPT'
option network 'wan41'
option forward 'ACCEPT'
option mtu_fix '1'
config zone
option family 'ipv4'
option name 'wan42'
option masq '1'
option masq6 '0'
option masq6_privacy '0'
option output 'ACCEPT'
option input 'ACCEPT'
option network 'wan42'
option forward 'ACCEPT'
option mtu_fix '1'
config zone
option name 'wan61'
option masq '1'
option masq6 '1'
option masq6_privacy '0'
option output 'ACCEPT'
option network 'wan61'
option family 'ipv6'
option input 'ACCEPT'
option forward 'ACCEPT'
option mtu_fix '1'
config zone
option name 'wan62'
option masq '1'
option masq6 '1'
option masq6_privacy '0'
option output 'ACCEPT'
option network 'wan62'
option family 'ipv6'
option input 'ACCEPT'
option forward 'ACCEPT'
option mtu_fix '1'
config rule
option src 'wan41'
option name 'all_wan41'
option family 'ipv4'
option proto 'all'
option dest 'lan'
option device 'eth0.1010'
option direction 'in'
option target 'ACCEPT'
config rule
option src 'wan42'
option name 'all_wan42'
option family 'ipv4'
option proto 'all'
option dest 'lan'
option device 'eth0.1020'
option direction 'in'
option target 'ACCEPT'
config rule
option src 'wan61'
option name 'all_wan61'
option family 'ipv6'
option proto 'all'
option dest 'lan'
option device 'eth0.1010'
option direction 'in'
option target 'ACCEPT'
config rule
option src 'wan62'
option name 'all_wan62'
option family 'ipv6'
option proto 'all'
option dest 'lan'
option device 'eth0.1020'
option direction 'in'
option target 'ACCEPT'
config forwarding
option dest 'wan41'
option src 'lan'
config forwarding
option dest 'wan42'
option src 'lan'
config forwarding
option dest 'wan61'
option src 'lan'
config forwarding
option dest 'wan62'
option src 'lan'
config redirect
option src 'wan41'
option name 'wan41'
option target 'DNAT'
option dest 'lan'
list proto 'all'
config redirect
option src 'wan42'
option name 'wan42'
option target 'DNAT'
option dest 'lan'
list proto 'all'
config redirect
option src 'wan61'
option name 'wan61'
option target 'DNAT'
option dest 'lan'
list proto 'all'
config redirect
option src 'wan62'
option name 'wan62'
option target 'DNAT'
option dest 'lan'
list proto 'all'
****************************
/etc/config/mwan3
config rule 'all_v4'
option proto 'all'
option sticky '0'
option use_policy 'balanced_wan'
option src_ip '192.168.0.0/16'
config rule 'all_v6'
option proto 'all'
option sticky '0'
option use_policy 'balanced_wan6'
option src_ip 'fd00::/8'
config rule 'drop_all'
option src_ip '0.0.0.0/0'
option proto 'all'
option sticky '0'
option use_policy 'unreachable'
config globals 'globals'
option mmx_mask '0x3F00'
option rtmon_interval '2'
config interface 'wan41'
option enabled '1'
list track_ip '8.8.4.4'
option family 'ipv4'
option track_method 'ping'
option count '1'
option size '56'
option max_ttl '60'
option check_quality '0'
option interval '5'
option down '3'
option up '3'
option initial_state 'offline'
option failure_interval '3'
option recovery_interval '3'
option timeout '1'
option reliability '1'
list flush_conntrack 'ifup'
list flush_conntrack 'ifdown'
list flush_conntrack 'connected'
list flush_conntrack 'disconnected'
config interface 'wan42' # аналогично config interface 'wan41'
config interface 'wan61'
option enabled '1'
option family 'ipv6'
option track_method 'ping'
option count '1'
option size '56'
option check_quality '0'
option interval '5'
option down '3'
option up '3'
option initial_state 'offline'
option max_ttl '70'
option failure_interval '3'
option recovery_interval '3'
option timeout '1'
option reliability '1'
list track_ip 'yahoo.com'
list flush_conntrack 'ifup'
list flush_conntrack 'ifdown'
list flush_conntrack 'connected'
list flush_conntrack 'disconnected'
config interface 'wan62' # аналогично config interface 'wan61'
config member 'wan_41'
option interface 'wan41'
option metric '1'
option weight '1'
config member 'wan_42'
option interface 'wan42'
option metric '1'
option weight '1'
config member 'wan_61'
option interface 'wan61'
option weight '1'
option metric '2'
config member 'wan_62'
option interface 'wan62'
option weight '1'
option metric '2'
config policy 'balanced_wan'
option last_resort 'unreachable'
list use_member 'wan_41'
list use_member 'wan_42'
config policy 'balanced_wan6'
list use_member 'wan_61'
list use_member 'wan_62'
option last_resort 'unreachable'
****************************
Вот и вся конфигурация маршрутизатора занятого балансировкой трафика от первых двух
****************************
Файл скрипта реализующего маскарадинг для NATv6 /etc/firewall.nat6
set -eo pipefail
. /lib/functions.sh
. /lib/functions/network.sh
. /usr/share/libubox/jshn.sh
log() {
logger -t nat6 -s "$@"
}
get_ula_prefix() {
uci get network.globals.ula_prefix
}
validate_ula_prefix() {
local ula_prefix="$1"
if [ $(echo "$ula_prefix" | grep -c -E "^([0-9a-fA-F]{4}):([0-9a-fA-F]{0,4}):") -ne 1 ] ; then
log "Fatal error: IPv6 ULA ula_prefix=\"$ula_prefix\" seems invalid. Please verify that a ula_prefix is set and valid."
return 1
fi
}
ip6t() {
ip6tables "$@"
}
ip6t_ensure_append() {
if ! ip6t -C "$@" >/dev/null 2>&1; then
ip6t -A "$@"
fi
}
nat6_init() {
iptables-save -t nat \
| sed -e "/\s[DS]NAT\s/d;/\sMASQUERADE$/d" \
| ip6tables-restore -T nat
}
masq6_network() {
# $config contains the ID of the current section
local network_name="$1"
local device
network_get_device device "$network_name" || return 0
local done_net_dev
for done_net_dev in $DONE_NETWORK_DEVICES; do
if [[ "$done_net_dev" == "$device" ]]; then
log "Already configured device=\"$device\", so leaving as is."
return 0
fi
done
log "Found device=\"$device\" for network_name=\"$network_name\"."
if [ $zone_masq6_privacy -eq 1 ]; then
log "Enabling IPv6 temporary addresses for device=\"$device\"."
log "Accepting router advertisements on $device even if forwarding is enabled (required for temporary addresses)"
echo 2 > "/proc/sys/net/ipv6/conf/$device/accept_ra" \
|| log "Error: Failed to change router advertisements accept policy on $device (required for temporary addresses)"
log "Using temporary addresses for outgoing connections on interface $device"
echo 2 > "/proc/sys/net/ipv6/conf/$device/use_tempaddr" \
|| log "Error: Failed to enable temporary addresses for outgoing connections on interface $device"
fi
append DONE_NETWORK_DEVICES "$device"
}
handle_zone() {
# $config contains the ID of the current section
local config="$1"
local zone_name
config_get zone_name "$config" name
# Enable masquerading via NAT6?
local zone_masq6
config_get_bool zone_masq6 "$config" masq6 0
log "Firewall config=\"$config\" zone=\"$zone_name\" zone_masq6=\"$zone_masq6\"."
if [ $zone_masq6 -eq 0 ]; then
return 0
fi
# IPv6 privacy extensions: Use temporary addrs for outgoing connections?
local zone_masq6_privacy
config_get_bool zone_masq6_privacy "$config" masq6_privacy 1
log "Found firewall zone_name=\"$zone_name\" with zone_masq6=\"$zone_masq6\" zone_masq6_privacy=\"$zone_masq6_privacy\"."
log "Setting up masquerading nat6 for zone_name=\"$zone_name\" with zone_masq6_privacy=\"$zone_masq6_privacy\""
local ula_prefix=$(get_ula_prefix)
validate_ula_prefix "$ula_prefix" || return 1
local postrouting_chain="zone_${zone_name}_postrouting"
log "Ensuring ip6tables chain=\"$postrouting_chain\" contains our MASQUERADE."
if ! ip6t_ensure_append "$postrouting_chain" -t nat -s "$ula_prefix" -j MASQUERADE; then
# Some releases of OpenWrt just leave the nat table empty for some reason (version dependent?)
log "Could not find table=\"$postrouting_chain\", but yolo so adding to POSTROUTING directly."
ip6t_ensure_append "POSTROUTING" -t nat -s "$ula_prefix" -j MASQUERADE
fi
local DONE_NETWORK_DEVICES=""
config_list_foreach "$config" network masq6_network
log "Done setting up nat6 for zone=\"$zone_name\" on devices: $DONE_NETWORK_DEVICES"
}
main() {
nat6_init
config_load firewall
config_foreach handle_zone zone
}
main "$@"
Создайте на компьютере файл без расширения, и присвойте ему имя "firewall.nat6". После чего откройте его программой Notepad++, и вставьте в него описанный выше код. После чего выберете в меню Правка-Формат Конца Строк-Преобразовать в UNIX (LF). Все файлы в юникс системах имеют в качестве окончания строки символ "Перевод на строку", или LF если включить отображение непечатаемых символов. Когда в системах Windows обычно окончание строки имеет два символа "Перевод на строку" и "Возврат каретки", то есть CR LF.
Поместите файл firewall.nat6 в каталог /etc маршрутизатора. Или в любой другой, при этом изменив путь в строке option path '/etc/firewall.nat6' в файле настроек фаервола.
Внимание! Это работоспособная версия скрипта, так сказать сборная солянка, на странице сайта OpenWRT информация устаревшая, код от этого отличается и у меня не заработал.
****************************
Содержимое файлов из опций option loadfile '/etc/namev4' и option loadfile '/etc/namev6', описанных во второй части, в качестве примера.
Файл '/etc/namev4'
ххх.ххх.ххх.ххх/18
ххх.ххх.ххх.ххх/18
ххх.ххх.ххх.ххх/21
ххх.ххх.ххх.ххх/32
В этом файле должны быть только списки подсетей, которые будут маршрутизироваться через VPN. Этот список для ipset таблиц не поддерживает единичные IP в привычном виде, по крайне мере так описано в документации на ipset, при выбранных мной опциях option match 'dest_net' и option storage 'hash'. Поэтому, если все же нужно добавить единичный IP в этот список, то нужно указать сеть размерностью 32, то есть вот так: ххх.ххх.ххх.ххх/32, что допускается в документации RFC 6890.
Файл '/etc/namev6'
хххх:хххх::/48
хххх:хххх::/44
хххх:хххх::/32
С этими файлами, при их создании и сохранении, поступайте точно так как описано для фала /etc/firewall.nat6
****************************
Опишу некоторые баги (или фичи?). Ранее писал, что объясню для чего нужно тегировать трафик гуляющий между маршрутизаторами. Вся проблема в управляемом коммутаторе внутри маршрутизатора, настройка которого при загрузке, и перезагрузке, устанавливается по умолчанию. В этот момент порт который сконфигурирован как WAN превращается в LAN и через этот порт провайдер, или мой промежуточный маршрутизатор, выдает IP на мой ПК. Это приводит к тому что после загрузки маршрутизатора этот IP продолжает "висеть" в сетевой карте, и приходится либо кабель переподключать, либо выключать и включать сетевую карту в ПК. Это известный баг, я писал на форум OpenWRT и тривиального решения к сожалению нет. Но при моей ситуации с кучей маршрутизаторов этот баг решается тем, что я присваиваю тег VLANам, и этот тег не слетает во время перезагрузки, что позволяет не пропускать трафик не совпадающий по тегу. Короче, в итоге, все работает как надо))
Так же OpenWRT позволяет обновлять пакеты, но там нет кнопки обновить все сразу. У меня есть решение этой задачи, которое позволяет автоматом, после загрузки маршрутизатора, проверить репозиторый на обновления, и обновить все пакеты для которых вышли новые версии. Если интересно, то пишите в комментариях, опишу как это делается в отдельном посте.
Для периодического обновления списков блокировок AddBlock создается задача в cron. Для этого в файл /etc/crontabs/root нужно добавить строку "0 * * * * /etc/init.d/adblock reload", без кавычек. Эта строка создает задачу перезапуска блокировщика в начале каждого часа, что тем самым приводит к скачиванию актуальных списков блокировок. В противном случае списки будут обновляться при каждом запуске маршрутизатора, или ручном перезапуске блокировщика.
****************************
Ссылки на использованные материалы:
https://github.com/akatrevorjay/openwrt-masq6 ссылка на проект скрипта для маскарадинга NATv6
https://openwrt.org/docs/guide-user/network/ipv6/ipv6.nat6 инструкция для настройки NAT6 and IPv6 masquerading с официального сайта OpenWRT
https://openwrt.org/docs/guide-user/network/wan/multiwan/mwa... инструкция по настройке mwan3 с официального сайта OpenWRT
https://openwrt.org/docs/guide-user/firewall/firewall_config... настройка фаервола с сайта OpenWRT
https://github.com/openwrt/packages/blob/master/net/adblock/... проект блокировщика рекламы, там самые актуальные настройки
https://openwrt.su/nastrojka/vpn-klient-na-openwrt неплохая инструкция по настройке OpenVPN
Остальное по крупицам в сети, а так же в ходе двухнедельных бдений, и поскрипыванием извилин мозга. Надеюсь, что в трех постах дал исчерпывающие настройки по основным компонентам, которые могут понадобиться в домашних маршрутизаторах работающих под управлением OpenWRT.
****************************
По итогу получилось следующее:
Суммарная скорость при тестировании через https://www.speedtest.net/, или при закачке торрентов, составляет сумму скоростей всех каналов. В реальности где-то 181-188 мегабит на прием, и 185-189 мегабит на отдачу.
При обрыве одного канала все автоматом переходит на оставшийся канал, включая потоки онлайнового радио через плеер.
Реализована блокировка рекламы на уровне доменов.
Обход заблокированных сайтов в известной стране.
Возможность получить доступ к сайтам по протоколу IPv6. При этом маскарадинг разбрасывает входящий трафик в маршрутизатор на несколько тоннелей.
Всего в сумме получается шесть внешних IPv6. Потому, при проверке IPv6 адреса в интернете, например на сайтах https://test-ipv6.com/index.html.ru_RU или https://ipv6-test.com/, я вижу разные свои внешние IP. Два внешних IPv4, и шесть IPv6.
Весь этот огород из маршрутизаторов не делает мне нервы и лишний раз не беспокоит. Вся конфигруация стабильно работает без перебоев. При этом маршрутизаторы выключаются при выключении ПК, и всех остальных потребителей трафика. Например ночью когда все спят. При подаче питания все само запускается и работоспособно через полторы минуты.
Цена за маршрутизаторы составила около 150$.
Все что ставилось в ТЗ все было реализовано ))
Все замечания и предложения пишите в комментариях. Если остались какие-либо непонятные моменты или неточности, то отвечу в комментах, или распишу отдельным постом.
PS: Пораскинув немного мозгами, пришел к выводу что всю эту кухню можно реализовать при помощи всего одного маршрутизатора и управляемого коммутатора, что бы тегировать VLANы. Но проверять я это конечно же не буду))