Отделен изход: VPN пул на usb0, трафик на шлюза по eth0
Пренасочените VPN клиенти могат да излизат през usb0, докато шлюзът запазва своя маршрут по подразбиране по eth0. Постройте пълна избрана таблица и след това направете така, че отказът да затваря, а не да пропуска.
Клиентите се свързват и удостоверяват, след което трафикът им излиза по грешния ъплинк, защото единственият маршрут по подразбиране на машината принадлежи на самия шлюз. Замяната на този маршрут би счупила собствените обновявания на машината и достъпа за управление, затова изборът трябва да е по-тесен от „целия трафик“. Работещата форма е правило за политика, обвързано с вътрешния адрес на източника на клиентския пул, сочещо към втора таблица за маршрутизация, която притежава алтернативния WAN. Оттам нататък проверката е за пълнота и поведение при отказ, а не за самото правило.
Потвърдете, че адресът на източника оцелява до решението за маршрутизация
Правило за политика, което съвпада с диапазон на източник, се задейства само когато пакетът все още носи този източник в момента на търсенето. Пренасоченият клиентски трафик го прави, стига нищо по-нагоре по веригата да не го е презаписало преди маршрутизацията. Трафикът, генериран от шлюза, не го прави, и точно затова собственият маршрут по подразбиране на шлюза може да остане където е.
Тук локалните тестове подвеждат. Пуснат на шлюза curl е локално генериран поток с адреса на шлюза, затова той взема основната таблица и не доказва нищо за клиентския път. Тествайте от свързан клиент или генерирайте трафик с източник, който наистина принадлежи на пула.
Започнете, като запишете реалните стойности: префикса на пула, тунелния интерфейс, който го носи, адреса и следващия хоп на втория WAN и номера на таблицата, която смятате да използвате. Изчистете старите правила от всеки предишен опит, преди да добавите нови, защото дублирани правила с различни приоритети дават откази, които изглеждат случайни.
Постройте избрана таблица, която е пълна
Таблицата не е маршрут по подразбиране с приятел. Тя се нуждае от достатъчно маршрути, така че всяко търсене да се решава вътре в нея, включително свързания маршрут за подмрежата на WAN, за да е достижим следващият хоп. За пул 10.77.0.0/24 на tun1, WAN адрес 203.0.113.20/24 със следващ хоп 203.0.113.1 и таблица 600:
ip -4 route replace 203.0.113.0/24 dev usb0 src 203.0.113.20 table 600
ip -4 route replace 10.77.0.0/24 dev tun1 table 600
ip -4 route replace default via 203.0.113.1 dev usb0 table 600
ip -4 rule add priority 1500 from 10.77.0.0/24 lookup 600
Правилото стои на приоритет под всяко съществуващо правило, което прихваща всичко, така че съвпадащите клиенти първо попадат в таблица 600, а всичко останало пада към основната таблица. Справката за ip-rule описва изцяло модела на подредено търсене и синтаксиса на селектора.
След това помислете какво не съдържа таблицата. Дестинация, която има маршрут само в основната таблица, например подмрежа за управление, достижима през eth0, няма да бъде намерена в таблица 600 и няма да се върне към основната, след като там има маршрут по подразбиране. Ако тези пътища са важни, добавете ги изрично към избраната таблица, което обикновено е правилният отговор за таблица за VPN изход.
Дръжте собствения трафик на слушателя извън политиката
Слушателят на OpenVPN има собствена външна връзка, пренасяна по онзи ъплинк, по който клиентът го е достигнал. Този трафик трябва да запази обратния път, с който е пристигнал, а широко правило, покриващо публичния адрес на сървъра или целия тунелен интерфейс, може да го дръпне в алтернативната таблица. Ограничете правилото до вътрешния пул и нищо друго.
Филтрирането по обратен път заслужава поглед по същата причина. Когато отговорите към клиентите излизат през usb0, докато заявката е пристигнала по друга връзка, строга настройка rp_filter може да изхвърли пакети, които политиката за маршрутизация смята за валидни. Проверете действащите sysctl стойности на двата интерфейса, преди да заключите, че правилото се е провалило.
Подредбата има значение и спрямо всичко останало на машината. Docker мостове, втори VPN и всякакви съществуващи правила от образ на доставчик добавят приоритети, затова прочетете целия списък с правила, вместо да предполагате, че приоритет 100 е сам.
Направете така, че препращането и транслацията да съвпадат с маршрута
Маршрутизацията избира ъплинк; тя не дава разрешение за препращане. Ядрото трябва да има включено препращане на IPv4, а защитната стена трябва да приема посоката от клиента към WAN и обратния трафик. Правилна таблица с верига FORWARD, която изхвърля потока, дава същия симптом като липсващ маршрут, затова двете се проверяват в един и същ проход.
Ако вторият WAN няма да маршрутизира частен пул обратно към вас, транслирайте източника на този изход. За интерфейс с динамичен адрес обичайният избор е тясно правило за маскарад, ограничено до пула и интерфейса:
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -o usb0 -j MASQUERADE
Обхватът тук е по-важен от целта. Правило за маскарад, което съвпада с всеки изходящ интерфейс, ще презапише и трафик, който правилно излиза през eth0, а това скрива грешки в маршрутизацията, вместо да ги поправя. Транслацията се изпълнява след решението за маршрутизация, така че никога не може да поправи пакет, изпратен по грешния ъплинк.
Разходите за тунела също изискват внимание, щом пътищата се различават. Ако клиентите договорят голям TCP MSS, а алтернативният WAN има по-нисък MTU или тунел вътре в себе си, големите сегменти забиват, докато малките работят. Ограничаването на MSS по пътя на препращане превръща това в предвидимо поведение, а не в периодично забиване.
Решете какво се случва, когато usb0 изчезне
Празната таблица не е състояние на затваряне при отказ. Ако съвпадащият маршрут изчезне, търсенето продължава към следващото правило, достига основната таблица и взема маршрута по подразбиране на eth0. Трафикът, който е трябвало да излезе през втория WAN, тихо излиза през първия, което за внедряване с маршрутизация по политика обикновено е резултатът, който искате най-малко.
Там, където такова връщане е неприемливо, добавете изричен терминален маршрут в таблица 600, например маршрут по подразбиране от тип blackhole, или изхвърлете пула в защитната стена, докато интерфейсът е спрян. Всяка от двете е решение, което можете да запишете; мълчанието не е.
Устойчивостта е последният пункт. Който и да притежава двете връзки, било то мрежовият мениджър, скрипт на диспечер или жизненият цикъл на връзката, трябва да пресъздава маршрутите и правилото при всяко повторно свързване, без да добавя дубликати. Проверете със заявка от реален клиент и отделна заявка от шлюза, потвърдете наблюдавания изход и в двата случая, след което извадете втория WAN и вижте кой от двата резултата, които сте проектирали, наистина се случва. IPv6 се нуждае от собствена таблица, правило и транслация; правилото за IPv4 по-горе не казва нищо за него.