Фильтр анонсируемых адресов

Продолжаю делать записи для себя. На этот раз потребовалось отфильтровать роуты, отдаваемые другим. OSPF для этого не подходит: стандарт такого попросту не предусматривает. Значит, переключаемся на BGP. Минимальный конфиг для FRR

!
router bgp 65000
 bgp router-id 10.0.0.2
 no bgp ebgp-requires-policy
 neighbor 10.0.0.3 remote-as 65000
 !
 address-family ipv4 unicast
  redistribute connected
  redistribute static
  neighbor 10.0.0.3 next-hop-self
 exit-address-family
exit
!

На другой стороне есть адрес 6.7.8.9, котрый не должен попасть на этот роутер.

!
ip route 6.7.8.9/32 10.1.0.254
!
router bgp 65000
 bgp router-id 10.0.0.3
 no bgp ebgp-requires-policy
 neighbor 10.0.0.2 remote-as 65000
 !
 address-family ipv4 unicast
  redistribute connected
  redistribute static
  neighbor 10.0.0.2 next-hop-self
  neighbor 10.0.0.2 prefix-list nobad-out out
 exit-address-family
exit
!
ip prefix-list nobad-out seq 5 deny 6.7.8.9/32 le 32
ip prefix-list nobad-out seq 10 permit 10.1.0.0/24 le 32
!

Проверяем

router2# show ip route bgp
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

B>* 10.1.0.0/24 [200/0] via 10.0.0.3, ens19, weight 1, 00:16:06

ВНИМАНИЕ: правка “на живую” permit-list не приведет к перечитыванию правил на другой стороне. Надо вручную в router bgp прицепить-отцепить их. Почему так – хз.

Вариант лечения: не важно где сказать clear ip bgp 10.0.0.3 (ессно, на передатчике адрес приемника и наоборот), это сбросит сессию bgp и заставит перечитать роуты.

MultiWAN без боли и шума

О, сколько боли в слове MultiWAN! Стоит погуглить что-нибудь типа “есть два провайдера, как сделать так, чтобы можно было пользоваться одновременно или использовать второй как бекапный”, так сразу высыпается куча советов про метрики, маркировку трафика с помощью iptables и так далее. Правда, в последнее время все поутихло, но это потому, что в большинстве прошивок для домашних роутеров наконец-то доделали этот функционал.

Но я-то другой! У меня закидоныпросы! Вот прямо сейчас мне надо разрулить аж трех “провайдеров” на одной точке. Плюс пустить один из адресов через одного провайдера… В общем, попробовал я сначала натыкать галочек в любимом кинетике, потом сдался в сторону {pf|opn}sense, но и так не преуспел… Нет, наверняка можно было допинать, но я устал и сдался.

Итак, первоначальные условия. Есть три провайдера: через сотовую связь, ADSL и GPON. Работают одновременно. Рядом стоит сервер, который легко потянет кучу виртуалок. Необходимо клиентов (то есть меня) пускать в интернет, при этом приоритет gpon, adsl, сотик. Но один из служебных маршрутов должен уходить через ADSL. Вроде бы просто, да?

Для начала я вообще решил проверить, а возможно ли это без боли. Для этого я сделал стенд из трех виртуалок. Две я обозвал router1 и router2, а клиента – естественно client.

internet - (ens18)router1(ens19) - 10.0.0.1 - network
internet - (ens18)router2(ens19) - 10.0.0.2 - network
                  client (ens19) - 10.0.0.3 - network

Я опускаю настройку роутеров и клиента. Все друг друга видят, на роутерах включен форвард пакетов и SNAT, в общем, все работает на ручном приводе хорошо. Теперь необходима автоматика.

Ставлю на каждый хост FRR. Редактирую /etc/frr/daemons на предмет включения ospfd и запускаю. Далее скармливаю на всех хостах одну и ту же конструкцию, только меняю router id

!
interface ens18
 ip ospf passive
exit
!
interface ens19
 ip ospf dead-interval 30
exit
!
router ospf
 ospf router-id 10.0.0.1
 network 10.0.0.0/24 area 0.0.0.0
exit
!

Никакой авторизации и прочих заморочек. Поднимаю OSPF, запрещаю ему спамить в сторону провайдера и говорю, что все в сети 10/24 – наше. Проверяю, что роутеры видят друг друга.

client# show ip ospf neighbor 

Neighbor ID     Pri State           Dead Time Address         Interface                        RXmtL RqstL DBsmL
10.0.0.1          1 Full/DR           27.376s 10.0.0.1        ens19:10.0.0.3                       0     0     0
10.0.0.2          1 Full/Backup       28.362s 10.0.0.2        ens19:10.0.0.3                       0     0     0

В принципе, теперь можно расставлять роуты куда надо и радоваться жизни. Но мне-то надо рулить default роутом. И тут засада: по-умолчанию, чтобы не расхреначить все, роутеры по умолчанию дропают роуты на 0.0.0.0/0. Можно, конечно, воспользоваться хаком имени OpenVPN и анонсировать роуты 0.0.0.0/1 и 128.0.0.0/1, но это не наш метод. Немного погуглив, выянил, что достаточно добавить default-information originate always в секцию router ospf и все получится. Дескать, я edge/border/ваще_крутой роутер и ходи через меня.

client# show ip ospf route 
============ OSPF network routing table ============
N    10.0.0.0/24           [1] area: 0.0.0.0
                           directly attached to ens19

============ OSPF router routing table =============
R    10.0.0.1              [1] area: 0.0.0.0, ASBR
                           via 10.0.0.1, ens19

============ OSPF external routing table ===========
N E2 0.0.0.0/0             [1/1] tag: 0
                           via 10.0.0.1, ens19

И действительно, стоило мне такое сказать, как client тут же все увидел и обновил. Добавляю ту же строку в конфиг второго. Вуаля!

root@client:~# ip r
default nhid 22 proto ospf metric 20 
	nexthop via 10.0.0.1 dev ens19 weight 1 
	nexthop via 10.0.0.2 dev ens19 weight 1 
10.0.0.0/24 dev ens19 proto kernel scope link src 10.0.0.3 

Клиент прописал себе оба роута и казалось бы наступила красота. И даже все заработало, как положено: если один из роутеров исчезал или я дропал на нем интерфейс, то соответствующий роут исчезал тоже. И тут я познал боль (правда, небольшую, на уровне фейспалма)

В чем боль? А боль возникла из-за того, что для клиента оба роутера видны через один интерфейс. И он совершенно справедливо полагает, что между ними нет разницы. А если нет разницы, то роутим туда, куда получится.

Ладно, моя ошибка. Добавляю еще одну сеть, сажу туда router3 и один из интерфейсов клиента. В остальном повторяю все выше. Проверяю, что все завелось.

client# show ip ospf neighbor 

Neighbor ID     Pri State           Dead Time Address         Interface                        RXmtL RqstL DBsmL
10.0.0.1          1 Full/DR           24.884s 10.0.0.1        ens19:10.0.0.3                       0     0     0
10.0.0.2          1 Full/Backup       25.013s 10.0.0.2        ens19:10.0.0.3                       0     0     0
10.1.0.4          1 Full/Backup       22.051s 10.1.0.4        ens20:10.1.0.3                       0     0     0

client# 

client# show ip ospf border-routers 
============ OSPF router routing table =============
R    10.0.0.1              [1] area: 0.0.0.0, ASBR
                           via 10.0.0.1, ens19
R    10.0.0.2              [1] area: 0.0.0.0, ASBR
                           via 10.0.0.2, ens19
R    10.1.0.4              [1] area: 0.0.0.0, ASBR
                           via 10.1.0.4, ens20

root@client:~# ip r
default nhid 79 proto ospf metric 20 
	nexthop via 10.0.0.1 dev ens19 weight 1 
	nexthop via 10.0.0.2 dev ens19 weight 1 
	nexthop via 10.1.0.4 dev ens20 weight 1 
10.0.0.0/24 dev ens19 proto kernel scope link src 10.0.0.3 
10.1.0.0/24 dev ens20 proto kernel scope link src 10.1.0.3 

Как видно, теперь у меня аж три некстхопа. Ходи – не хочу.

Проверяю, как OSPF на client видит интерфейсы

client# show ip ospf interface 
ens19 is up
  ifindex 3, MTU 1500 bytes, BW 4294967295 Mbit <UP,BROADCAST,RUNNING,MULTICAST>
  Internet Address 10.0.0.3/24, Broadcast 10.0.0.255, Area 0.0.0.0
  MTU mismatch detection: enabled
  Router ID 10.0.0.3, Network Type BROADCAST, Cost: 1
  Transmit Delay is 1 sec, State DROther, Priority 1
  Designated Router (ID) 10.0.0.1 Interface Address 10.0.0.1/24
  Backup Designated Router (ID) 10.0.0.2, Interface Address 10.0.0.2
  Saved Network-LSA sequence number 0x80000004
  Multicast group memberships: OSPFAllRouters
  Timer intervals configured, Hello 10s, Dead 30s, Wait 30s, Retransmit 5
    Hello due in 6.368s
  Neighbor Count is 2, Adjacent neighbor count is 2
ens20 is up
  ifindex 4, MTU 1500 bytes, BW 4294967295 Mbit <UP,BROADCAST,RUNNING,MULTICAST>
  Internet Address 10.1.0.3/24, Broadcast 10.1.0.255, Area 0.0.0.0
  MTU mismatch detection: enabled
  Router ID 10.0.0.3, Network Type BROADCAST, Cost: 1
  Transmit Delay is 1 sec, State DR, Priority 1
  Designated Router (ID) 10.0.0.3 Interface Address 10.1.0.3/24
  Backup Designated Router (ID) 10.1.0.4, Interface Address 10.1.0.4
  Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
  Timer intervals configured, Hello 10s, Dead 30s, Wait 30s, Retransmit 5
    Hello due in 0.712s
  Neighbor Count is 1, Adjacent neighbor count is 1

Все правильно, по умолчанию для ethernet cost 1.

Добавляю на клиенте на интерфейс ens19, который смотрит на первые два роутера, опцию ip ospf cost 100. Согласно мануалам, это должно сказать, что туда надо трафик отправлять в последнюю очередь (ведь 100>1)

Проверяю. Вот это было до.

root@client:~# ip r
default nhid 87 proto ospf metric 20 
	nexthop via 10.0.0.1 dev ens19 weight 1 
	nexthop via 10.0.0.2 dev ens19 weight 1 
        nexthop via 10.1.0.4 dev ens20 weight 1
10.0.0.0/24 dev ens19 proto kernel scope link src 10.0.0.3 
10.1.0.0/24 dev ens20 proto kernel scope link src 10.1.0.3 

Включаю ip ospf cost

root@client:~# ip r
default nhid 91 via 10.1.0.4 dev ens20 proto ospf metric 20 
10.0.0.0/24 dev ens19 proto kernel scope link src 10.0.0.3 
10.1.0.0/24 dev ens20 proto kernel scope link src 10.1.0.3 

Проверяю, что вообще-то роуты вернутся, если что-то случится с router3

root@client:~# ip link set ens20 down
root@client:~# ip r
default nhid 95 proto ospf metric 20 
	nexthop via 10.0.0.1 dev ens19 weight 1 
	nexthop via 10.0.0.2 dev ens19 weight 1 
10.0.0.0/24 dev ens19 proto kernel scope link src 10.0.0.3 

Работает, прямо как я и задумал. Теперь садим на каждый роутер по скрипту, который будет проверять доступность интернета. Таких скриптов уйма на любой вкус, цвет и запах. Можно вообще какой-нибудь zabbix присобачить. Но главное, чтобы они шли и пускали два скриптика

root@router3:~# cat enable.sh 
#!/bin/bash
cat << EOF | /usr/bin/vtysh
conf t
router ospf
default-information originate always
exit
exit
exit
EOF

root@router3:~# cat disable.sh 
#!/bin/bash
cat << EOF | /usr/bin/vtysh
conf t
router ospf
no default-information originate always
exit
exit
exit
EOF

Их названия говорят сами за себя, как и то, что они делают. Позапускал их, проверил, что таблица роутинга перестраивается, как и положено, согласно правилам.

Теперь последнее: пустить определенный маршрут через определенный роутер. Пусть это будет 1.2.3.4/32 на router2. Это вообще просто. Просто создаем статический роут и просим распростанить статику.

root@router2:~# vtysh

Hello, this is FRRouting (version 8.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

router2# conf t
router2(config)# ip route 1.2.3.4/32 192.168.1.1
router2(config)# router ospf
router2(config-router)# redistribute static

И все получается согласно заветам лучших сетевиков.

root@client:~# ip r
default nhid 113 via 10.1.0.4 dev ens20 proto ospf metric 20 
1.2.3.4 nhid 115 via 10.0.0.2 dev ens19 proto ospf metric 20 
10.0.0.0/24 dev ens19 proto kernel scope link src 10.0.0.3 
10.1.0.0/24 dev ens20 proto kernel scope link src 10.1.0.3 

Теперь осталось развести router1 и router2 по разным подсетям, донастроить точно так же, как и router3, забекапить все и забыть до появления новых вводных.

А, да. Ну и всех жаждущих интернета отправить на client. Теперь точно все.

Запрет macOS менять имя машины

Довольно часто я со своим макбуком попадаю в чужие сети. И некоторые (не будем показывать пальцем) в DHCP ответе отдают новое имя машины. А macOS как и положено, меняет свое имя на указанное. Мелочь, но напрягает когда в терминале видишь непривычное имя.

Решение простое: сделать скрипт/выполнить следующие команды. Вместо mbook поставьте свое

NAME="mbook"
sudo scutil --set HostName ${NAME}
sudo scutil --set LocalHostName ${NAME}
sudo scutil --set ComputerName "${NAME}"

Решение простое: DHCP может переписать HostName, но приоритет у LocalHostName и остального выше.