LINUX.ORG.RU

2 провайдера и разделение трафика

 , ,


2

2

Научите плиз, как это осилить? Хочу из локальной сети запросы в инет на, к примеру, 443 порт отправлять через одного провайдера и получать с него же, все остальное через второго. Добавил 2 таблицы в rt_tables, правила такие

ip route add $PROV1_SUB dev $PROV1 src $IP1 table PROV1
ip route add default via $PROV1_GW table PROV1
ip route add $PROV2_SUB dev $PROV2 src $IP2 table PROV2
ip route add default via $PROV2_GW table PROV2

ip route add $PROV1_SUB dev $PROV1 src $IP1
ip route add $PROV2_SUB dev $PROV2 src $IP2

ip route add default via $PROV1_GW

ip route add from $IP1 table PROV1
ip route add from $IP2 table PROV2

ip route add $LOCAL_SUB dev $LOCAL_IP table PROV1
ip route add $PROV2_SUB dev $PROV2 table PROV1
ip route add 127.0.0.0/8 dev lo table PROV1
ip route add $LOCAL_SUB dev $LOCAL_IP table PROV2
ip route add $PROV1_SUB dev $PROV1 table PROV2
ip route add 127.0.0.0/8 dev lo table PROV2

ip rule add from all fwmark 400 table PROV2
Как в nftables (на худой конец iptables) фильтровать трафик меткой? Никогда этого не делал, нахожу примеры в которых конкретный источник указан, а мне нужно чтоб любой источник из локальной сети был.

Вы эту мешанину заново набирали, или это копипаста из скрипта с ошибками?

примеры в которых конкретный источник указан, а мне нужно чтоб любой источник из локальной сети был.

Ну дак не указывайте источник, будет любой.

iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2

mky ★★★★★ ()
Ответ на: комментарий от mky

Засада была в rp_filter. Был в состоянии 1, перевел в 2 и все заработало

achilles_85 ()
Ответ на: комментарий от achilles_85

Да ну:

ip route add from $IP1 table PROV1

ну и:

ip route add $LOCAL_SUB dev $LOCAL_IP table PROV1

хотя, может у вас $LOCAL_IP содержит имя интерфейса (eth0), а не ip-адрес.

mky ★★★★★ ()
Ответ на: комментарий от mky

Все переписал, в первом посту вырвиглаз. Это поднимаю через post-up в файле interfaces

#!/bin/bash

# LTE
IF1=wwan0
IF1_IP=`ip addr | grep $IF1 | awk -F"/" '/inet/{ print gensub (/.* /,"","g",$1)}'`
IF1_GW_IP=`ip route | awk '/default.*'$IF1'/ { print $3 }'`
IF1_NET=`ip route | awk '/'$IF1_IP'/ { print $1 }'`

# Local net
IF3=eth0
IF3_IP=`ip addr | grep $IF3 | awk -F"/" '/inet/{ print gensub (/.* /,"","g",$1)}'`
IF3_GW_IP=`ip route | awk '/'$IF3'/ { print $9 }'`
IF3_NET=`ip route | awk '/'$IF3'/ { print $1 }'`

ip route add $IF1_NET dev $IF1 src $IF1_IP table LTE
ip route add default via $IF1_GW_IP table LTE
ip route add $IF1_NET dev $IF1 src $IF1_IP
ip route add default via $IF1_GW_IP
ip route add $IF3_NET dev $IF3 table LTE
ip route add $IF3_NET dev $IF3 table WG
ip route add $IF1_NET dev $IF1 table WG
ip route add 127.0.0.0/8 dev lo table LTE
ip route add 127.0.0.0/8 dev lo table WG
ip rule add from $IF1_IP table LTE
ip rule add from all fwmark 400 table WG
Эти маршруты поднимаются через конфиг WG клиента
ip route add $WG_NET dev $WG_DEV src $WG_IP table WG
ip route add default via $WG_GW_IP table WG
ip route add $WG_NET dev $WG_DEV src $WG_IP
ip rule add from $WG_IP table WG
ip route add $WG_NET dev WG_DEV table LTE
В iptables так
iptables -t mangle -A PREROUTING -p tcp --dport 700 -j MARK --set-mark 400
Все работает. Хочу удалять роуты перед перезапуском интерфейсов, но команда
ip rule delete from $IF1_IP table LTE
ругается, хочет prefix вместо названия таблицы. Нельзя как-то по названию таблицы удалять правило?

achilles_85 ()
Ответ на: комментарий от achilles_85

Вообще хочу все в один скрипт загнать и вызывать скрипт с аргументом. К примеру так

#/bin/bash
case "$1" in
  "ifup")
    ip route add $IF1_NET dev $IF1 src $IF1_IP table LTE
    ip route add default via $IF1_GW_IP table LTE
    ip route add $IF1_NET dev $IF1 src $IF1_IP
    ip route add default via $IF1_GW_IP
    ip route add $IF3_NET dev $IF3 table LTE
    ip route add $IF3_NET dev $IF3 table WG
    ip route add $IF1_NET dev $IF1 table WG
    ip route add 127.0.0.0/8 dev lo table LTE
    ip route add 127.0.0.0/8 dev lo table WG
    ip rule add from $IF1_IP table LTE
    ip rule add from all fwmark 400 table WG
    ;;
  "ifdown")
    ip route delete $IF1_NET dev $IF1 src $IF1_IP table LTE
    ip route delete default via $IF1_GW_IP table LTE
    ip route delete $IF1_NET dev $IF1 src $IF1_IP
    ip route delete default via $IF1_GW_IP
    ip route delete $IF3_NET dev $IF3 table LTE
    ip route delete $IF3_NET dev $IF3 table WG
    ip route delete $IF1_NET dev $IF1 table WG
    ip route delete 127.0.0.0/8 dev lo table LTE
    ip route delete 127.0.0.0/8 dev lo table WG
    ip rule delete from $IF1_IP table LTE
    ip rule delete from all fwmark 400 table WG
    ;;
  "wgup")
    ip route add $WG_NET dev $WG_DEV src $WG_IP table WG
    ip route add default via $WG_GW_IP table WG
    ip route add $WG_NET dev $WG_DEV src $WG_IP
    ip rule add from $WG_IP table WG
    ip route add $WG_NET dev WG_DEV table LTE
    ;;
  "wgdown")
    ip route delete $WG_NET dev $WG_DEV src $WG_IP table WG
    ip route delete default via $WG_GW_IP table WG
    ip route delete $WG_NET dev $WG_DEV src $WG_IP
    ip rule delete from $WG_IP table WG
    ip route delete $WG_NET dev WG_DEV table LTE
    ;;
  *)
    echo "invalid option"
    exit 1
    ;;
esac
Если таблица дефолтная, то первый запуск скрипта с ifup, wgup, после запускаю на удаление wgdown, ifdown - все проходит без ошибок. Повторный запуск ifup - получаю в консоли кучу сообщений

achilles_85 ()
Ответ на: комментарий от achilles_85

ПРодолжение

Usage: ip route { list | flush } SELECTOR
       ip route save SELECTOR
       ip route restore
       ip route showdump
       ip route get [ ROUTE_GET_FLAGS ] ADDRESS
                            [ from ADDRESS iif STRING ]
                            [ oif STRING ] [ tos TOS ]
                            [ mark NUMBER ] [ vrf NAME ]
                            [ uid NUMBER ] [ ipproto PROTOCOL ]
                            [ sport NUMBER ] [ dport NUMBER ]
       ip route { add | del | change | append | replace } ROUTE
SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]
            [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]
            [ type TYPE ] [ scope SCOPE ]
ROUTE := NODE_SPEC [ INFO_SPEC ]
NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]
             [ table TABLE_ID ] [ proto RTPROTO ]
             [ scope SCOPE ] [ metric METRIC ]
             [ ttl-propagate { enabled | disabled } ]
INFO_SPEC := { NH | nhid ID } OPTIONS FLAGS [ nexthop NH ]...
NH := [ encap ENCAPTYPE ENCAPHDR ] [ via [ FAMILY ] ADDRESS ]
            [ dev STRING ] [ weight NUMBER ] NHFLAGS
FAMILY := [ inet | inet6 | mpls | bridge | link ]
OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ]
           [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]
           [ window NUMBER ] [ cwnd NUMBER ] [ initcwnd NUMBER ]
           [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]
           [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]
           [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ]
           [ pref PREF ] [ expires TIME ] [ fastopen_no_cookie BOOL ]
TYPE := { unicast | local | broadcast | multicast | throw |
          unreachable | prohibit | blackhole | nat }
TABLE_ID := [ local | main | default | all | NUMBER ]
SCOPE := [ host | link | global | NUMBER ]
NHFLAGS := [ onlink | pervasive ]
RTPROTO := [ kernel | boot | static | NUMBER ]
PREF := [ low | medium | high ]
TIME := NUMBER[s|ms]
BOOL := [1|0]
FEATURES := ecn
ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl ]
ENCAPHDR := [ MPLSLABEL | SEG6HDR ]
SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]
SEGMODE := [ encap | inline ]
ROUTE_GET_FLAGS := [ fibmatch ]
Error: any valid address is expected rather than "table".
Usage: ip route { list | flush } SELECTOR
       ip route save SELECTOR
       ip route restore
       ip route showdump
       ip route get [ ROUTE_GET_FLAGS ] ADDRESS
                            [ from ADDRESS iif STRING ]
                            [ oif STRING ] [ tos TOS ]
                            [ mark NUMBER ] [ vrf NAME ]
                            [ uid NUMBER ] [ ipproto PROTOCOL ]
                            [ sport NUMBER ] [ dport NUMBER ]
       ip route { add | del | change | append | replace } ROUTE
SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]
            [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]
            [ type TYPE ] [ scope SCOPE ]
ROUTE := NODE_SPEC [ INFO_SPEC ]
NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]
             [ table TABLE_ID ] [ proto RTPROTO ]
             [ scope SCOPE ] [ metric METRIC ]
             [ ttl-propagate { enabled | disabled } ]
INFO_SPEC := { NH | nhid ID } OPTIONS FLAGS [ nexthop NH ]...
NH := [ encap ENCAPTYPE ENCAPHDR ] [ via [ FAMILY ] ADDRESS ]
            [ dev STRING ] [ weight NUMBER ] NHFLAGS
FAMILY := [ inet | inet6 | mpls | bridge | link ]
OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ]
           [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]
           [ window NUMBER ] [ cwnd NUMBER ] [ initcwnd NUMBER ]
           [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]
           [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]
           [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ]
           [ pref PREF ] [ expires TIME ] [ fastopen_no_cookie BOOL ]
TYPE := { unicast | local | broadcast | multicast | throw |
          unreachable | prohibit | blackhole | nat }
TABLE_ID := [ local | main | default | all | NUMBER ]
SCOPE := [ host | link | global | NUMBER ]
NHFLAGS := [ onlink | pervasive ]
RTPROTO := [ kernel | boot | static | NUMBER ]
PREF := [ low | medium | high ]
TIME := NUMBER[s|ms]
BOOL := [1|0]
FEATURES := ecn
ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl ]
ENCAPHDR := [ MPLSLABEL | SEG6HDR ]
SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]
SEGMODE := [ encap | inline ]
ROUTE_GET_FLAGS := [ fibmatch ]
Command line is not complete. Try option "help"
Usage: ip route { list | flush } SELECTOR
       ip route save SELECTOR
       ip route restore
       ip route showdump
       ip route get [ ROUTE_GET_FLAGS ] ADDRESS
                            [ from ADDRESS iif STRING ]
                            [ oif STRING ] [ tos TOS ]
                            [ mark NUMBER ] [ vrf NAME ]
                            [ uid NUMBER ] [ ipproto PROTOCOL ]
                            [ sport NUMBER ] [ dport NUMBER ]
       ip route { add | del | change | append | replace } ROUTE
SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]
            [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]
            [ type TYPE ] [ scope SCOPE ]
ROUTE := NODE_SPEC [ INFO_SPEC ]
NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]
             [ table TABLE_ID ] [ proto RTPROTO ]
             [ scope SCOPE ] [ metric METRIC ]
             [ ttl-propagate { enabled | disabled } ]
INFO_SPEC := { NH | nhid ID } OPTIONS FLAGS [ nexthop NH ]...
NH := [ encap ENCAPTYPE ENCAPHDR ] [ via [ FAMILY ] ADDRESS ]
            [ dev STRING ] [ weight NUMBER ] NHFLAGS
FAMILY := [ inet | inet6 | mpls | bridge | link ]
OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ]
           [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]
           [ window NUMBER ] [ cwnd NUMBER ] [ initcwnd NUMBER ]
           [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]
           [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]
           [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ]
           [ pref PREF ] [ expires TIME ] [ fastopen_no_cookie BOOL ]
TYPE := { unicast | local | broadcast | multicast | throw |
          unreachable | prohibit | blackhole | nat }
TABLE_ID := [ local | main | default | all | NUMBER ]
SCOPE := [ host | link | global | NUMBER ]
NHFLAGS := [ onlink | pervasive ]
RTPROTO := [ kernel | boot | static | NUMBER ]
PREF := [ low | medium | high ]
TIME := NUMBER[s|ms]
BOOL := [1|0]
FEATURES := ecn
ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl ]
ENCAPHDR := [ MPLSLABEL | SEG6HDR ]
SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]
SEGMODE := [ encap | inline ]
ROUTE_GET_FLAGS := [ fibmatch ]
abdul@homegate:~$ ip rule ls
0:      from all lookup local
32764:  from all fwmark 0x190 lookup WG
32765:  from 10.114.139.73 lookup LTE
32766:  from all lookup main
32767:  from all lookup default
Что делаю не так?

achilles_85 ()
Ответ на: комментарий от achilles_85

Понял где туплю. При удалении роутов удаляется вся инфа из ip route, после скрипт не может определить переменные. Как вообще по правильному нужно сделать? Грузить только раз все роуты и после не трогать? К примеру если сделать рестарт сервиса networking, то роуты опять загрузяться из файла interfaces и я получу дубли в таблице правил. Как сделать правильно?

achilles_85 ()
Ответ на: комментарий от achilles_85

я получу дубли в таблице правил.

Добавлять удалять правила скриптом, который смотрит их текущее стостояние (парсит вывод ″ip rule show″). Как более простой вариант, для каждого правила определить его «место» (параметр ″pref″), перед добавлением делать удаление правила с этим pref (с выхлопом в /dev/null), чтобы железобетонно.

pref задавать «с зазором», чтобы не было сложности добавить новые. То есть типа:

ip rule del pref 15000 >/dev/null 2>&1

ip rule add pref 15000 from $IP1 table PROV1

ip rule del pref 16000 >/dev/null 2>&1

ip rule add pref 16000 from $IP2 table PROV2

mky ★★★★★ ()
Ответ на: комментарий от mky

Все оказалось проще, тупо спешу и не вижу очевидные вещи. Когда я вручную пускаю скрипт на удаление маршрутов, то естественно таблица маршрутизации опустошается. И после я пытаюсь наполнить ее скриптом, но скрипт ищет гейты и подсети в пока пустой таблице, переменных нет и получается бардак. Если же в интерфейсах прописать post-up на добавление маршрутов и pre-down на удаление, то все работает правильно. Перед рестартом сети

systemctl restart networking
активируется pre-down и удаляет маршруты с правилами, далее интерфейсы перезапускаются, в таблице маршрутизации появляются маршруты по умолчанию, далее срабатывает post-up и скрипт может считать переменные. Спасибо за подсказки, вроде задача решена

achilles_85 ()
Ответ на: комментарий от mky

Единственное осталось придумать как пускать p2p трафик через нужный интерфейс. Мне тут подсказали направление layer 7 ndpi bittorrent, но пока не вдуплил

achilles_85 ()
Ответ на: комментарий от achilles_85

Никогда такого не делал, не уверен, что такое возможно. Чтобы соединение работало, нужно чтобы все пакеты ходили по одному маршруту. Поэтому решать по какому маршруту пойдёт соединение можно только по содержимому первого пакета. Не знаю, в bittorrent первый пакет достаточно ли уникален, чтобы ndpi отличил его от других протоколов?

mky ★★★★★ ()
Ответ на: комментарий от achilles_85

помочь

achilles_85, можете мне помочь на коммерческой основе настроить роутинг на ubuntu 18+ (т.е. это netplan) работу 3proxy с несколькими (10) сетевыми интерфейсами (cdc_ether, usb модемы), т.е. отдельный http-прокси на каждый сетевой интерфейс? Напишите мне пожалуйста job.rabota@gmail.com или телеграмм @odnokasanie

zobrist ()
Ответ на: помочь от zobrist

Сорян, хотел бы помочь даже на безвозмездной основе, но я вряд ли с ходу такое осилю. С 3proxy дел не имел, а тянуть резину не люблю

achilles_85 ()
Ответ на: комментарий от achilles_85

Спасибо, чо откликнулся, achilles_85! А 3proxy не сложен же, он принимает запрос на одном интерфейсе и с другого интерфейса делает новый запрос, но того же содержания и транслирует обратно ответ.

Так основная проблема - это то, что 3proxy с ошибкой выполняет запрос с другого интерфейса, проблема в ненастроенном роутинге.

Если понимаете как настроить роутинг на ubuntu, то давайте попробуем настроить?

zobrist ()
Ответ на: комментарий от achilles_85

Спасибо, коллега, жду!

Я начитавшись форумов у себя имею (настройки и вывод комманд): https://rentry.co/9k5ci но не работает роутинг через eth1, т.е. делаю

curl -4 --interface 192.168.8.100 2ip.ru

и выполнение висит без результатов. Хотя если используя 3proxy с настроенным http-прокси с исходящим интерфейсом 192.168.8.100 открывает страницу с дашбоард модема, но больше ничего.

zobrist ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.