A omisión de cgroup en nftables tamén necesita unha corrección da dirección de orixe
Marcar un cgroup envíao a outra táboa, e o socket conserva a dirección que xa tiña. Clasifica, encamiña e traduce como tres pasos separados.
Marcar o tráfico dun cgroup é a parte fácil. Tres decisións separadas teñen que aliñarse antes de que unha soa aplicación saia pola interface física mentres todo o demais permanece no túnel: que socket pertence á excepción, que consulta de encamiñamento desencadea a marca e que dirección de orixe leva o paquete cando sae. A maioría dos intentos fallidos acertan a primeira, acertan a medias a segunda e nunca miran a terceira.
Tres decisións, non unha
A clasificación responde quen está exento. O encamiñamento responde a onde vai no seu lugar o paquete marcado. A selección de orixe responde que verá o extremo remoto e a onde debe volver a resposta.
Estas fallan de forma independente. Un paquete pode estar clasificado, reencamiñado á interface física e aínda así levar unha dirección privada que ningún router augas arriba pode devolver, o que produce un tempo de espera que parece exactamente un bloqueo de cortafogos. Nada no paso de clasificación che avisa diso. Nada no paso de encamiñamento tampouco.
A orde tamén importa. A clasificación ocorre cando se xera o paquete, o encamiñamento ocorre despois e a tradución ocorre no punto de saída.
Se non podes nomear cal das tres etapas está rota, non estás depurando, estás reordenando regras e esperando.
Fai coincidir un cgroup que siga existindo mañá
nftables pode comprobar a pertenza dun socket a cgroup v2, o que é realmente útil porque segue o proceso e non o destino. A trampa é o identificador. Unha aplicación de escritorio lanzada desde un menú adoita vivir nun scope transitorio cuxo nome cambia no seguinte lanzamento.
nft list ruleset
systemctl status session.slice 2>/dev/null
cat /proc/self/cgroupCopiar o nome dun scope dunha sesión e codificalo de forma fixa produce unha regra que funciona hoxe e mañá deixa de coincidir en silencio. Pon a aplicación, en cambio, nun contexto de execución deliberado e estable, como un scope ou unha unit dedicada que controles, e fai que coincida con iso. Así a regra sobrevive a reinicios e actualizacións de paquetes. Tamén se converte en algo sobre o que un compañeiro pode razoar sen o teu historial de sesións.
Sé tamén preciso sobre que mecanismo estás usando. A clasificación net_cls de cgroup v1 e a coincidencia de socket de cgroup v2 son cousas distintas, e un campo cun nome parecido na documentación non as fai intercambiables.
É unha cadea de tipo route a que desencadea a segunda consulta
Para o tráfico xerado localmente, o tipo de cadea decide se ocorre algo despois de poñer a marca. Unha cadea de saída de tipo filter pode marcar un paquete e o núcleo seguirá usando a ruta que xa elixira. Unha cadea de tipo route é o mecanismo que pide unha consulta nova.
table inet bypass {
chain mark {
type route hook output priority mangle; policy accept;
socket cgroupv2 level 2 "app.slice" meta mark set 0x1 comment "app bypass"
}
}
ip rule add fwmark 0x1 lookup 200
ip route add default via 203.0.113.1 dev wlan0 table 200A marca necesita entón unha regra de política que a envíe a unha táboa, e esa táboa debe estar completa: unha ruta por defecto, calquera destino local que a aplicación siga necesitando e unha pasarela augas arriba que realmente responda.
Elixe o valor da marca con intención. WireGuard usa o seu propio fwmark para o tráfico de transporte exterior, e aterrar por accidente no mesmo número pode interferir coa excepción de encamiñamento do propio túnel de formas que son dolorosas de diagnosticar.
A dirección de orixe non segue a ruta
Un socket que xa elixiu unha dirección de orixe para a ruta do túnel conserva esa dirección tras o reencamiñamento. Nada no cambio de encamiñamento a reescribe, por iso o paquete sae pola interface física cunha orixe privada que a rede augas arriba non pode devolver.
O síntoma visible é unha aplicación que parece enviar datos e nunca recibe resposta, e un rexistro de cortafogos que non mostra nada porque o paquete nunca volveu.
A corrección estreita é unha regra de tradución de orixe limitada á marca desa aplicación e á súa interface de saída real, integrada co NAT que xa exista en lugar de substituílo:
table inet bypass {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
meta mark 0x1 oifname "wlan0" masquerade
}
}Traduce a excepción e nada máis. Unha regra masquerade xeral arranxa o síntoma e destrúe a túa capacidade de dicir que tráfico tomou que camiño. Fai coincidir a marca, a interface de saída real e, se podes, a dirección propia da aplicación. As regras amplas son fáciles de escribir e case imposibles de auditar despois.
Que segue escapando da excepción
A resolución de nomes pode vir dun proceso resolver separado noutro cgroup, así que clasificar o socket do navegador non clasifica as súas consultas. Se as consultas do resolver quedan no túnel mentres a conexión sae fóra del, as respostas split-horizon poden non coincidir co camiño. Esa discrepancia produce fallos que parecen erros de DNS e non o son.
Os procesos fillos herdan o cgroup na maioría das configuracións, pero un axudante que se move ao seu propio scope non o fai. Comproba en lugar de supoñer, sobre todo para calquera cousa que se reexecute.
Por último, decide que debe pasar cando o túnel está caído. Unha excepción que se converte en silencio nunha omisión completa é unha postura de seguridade distinta da que falla pechada, e só unha das dúas é a que querías.