Tres equipos Linux, un deseño: un concentrador OpenVPN accesible publicamente, un portátil de consumidor e unha máquina de saída detrás dun router doméstico corrente que non reenvía nada cara a dentro. A saída marca o concentrador por si mesma. O tráfico de internet do consumidor entra entón no túnel no portátil e sae polo enlace ascendente propio da saída. Todo o sorprendente desta disposición dedúcese dun detalle: a saída iniciou a conexión, así que o camiño cara a dentro xa existe e non fai falta ningunha redirección de porto para crealo.

O que segue percorre o camiño do paquete e non a orde da configuración, porque a configuración só ten sentido cando sabes que compoñente toma que decisión. Cada capa toma exactamente unha decisión, e os erros agrúpanse onde se dan dúas capas por unha.

Dúas sesións de transporte, un camiño interior

Cada equipo mantén a súa propia conexión exterior ao concentrador, e ningunha desas conexións sabe da outra. O tráfico do consumidor cara a internet é un fluxo interior aparte que se transporta dentro do túnel do consumidor e logo se emite de novo desde o túnel da saída. Ese fluxo interior é o que o concentrador ten que encamiñar e o que a saída ten que reenviar.

outer: consumer --TLS--> hub
outer: exit     --TLS--> hub
inner: consumer --tun--> hub --internal--> exit --tun--> uplink

Como ambas conexións exteriores saen do lado do cliente, o router da saída nunca ve un SYN entrante nin necesita nunca unha regra de NAT de destino. Só ten que manter vivo o transporte establecido, cousa que xa fai para calquera conexión duradeira. Nada na internet pública necesita chegar primeiro á saída, por iso un enderezo dinámico nese enlace ascendente non é un problema. O router segue tendo que permitir a sesión saínte, pero é o mesmo permiso que xa usa un navegador.

Que instala realmente iroute dentro do servidor

O concentrador é o único dispositivo que decide que par posúe que destino, e faino na súa propia táboa de encamiñamento de espazo de usuario, non na do núcleo. Unha entrada client-config-dir para a saída chamada exit-node pode reclamar alí o prefixo por defecto:

# /etc/openvpn/server/ccd/exit-node
iroute 0.0.0.0 0.0.0.0

Esa liña di ao proceso do servidor "os paquetes interiores con calquera destino pertencen a este cliente". Non engade unha ruta por defecto ao sistema operativo do concentrador nin converte o concentrador nunha pasarela de internet. Referencia de OpenVPN 2.6 mantén o encamiñamento interno específico do cliente e o encamiñamento do núcleo como mecanismos separados, e esa separación é a razón pola que o deseño funciona sen tocar a ruta por defecto do concentrador.

O consumidor necesita a instrución espello, entregada como push, para que o seu propio tráfico entre no túnel en lugar de saír pola súa pasarela local. Con topoloxía de subrede, o conxunto é unha ruta conectada no dispositivo tun da saída, así que a dirección de volta non necesita ningún push adicional; o que a saída non debe recibir é a redirección de abaixo, que devolvería o seu propio tráfico ascendente ao túnel que intenta usar. Envíaa só ao consumidor e le as rutas aplicadas no cliente en lugar de confiar en que se escolleu o ficheiro CCD.

# /etc/openvpn/server/ccd/consumer-01
push "redirect-gateway def1"

O núcleo da saída fai o reenvío

Dentro da saída, un paquete do consumidor chega á interface tun dirixido a algún equipo de internet. O núcleo consulta a súa táboa de encamiñamento, atopa o enlace ascendente real como a mellor coincidencia e logo aplica dúas políticas independentes: se o paquete pode reenviarse e se pode saír por esa interface con ese enderezo de orixe. O reenvío é un sysctl e vén desactivado por defecto en moitas distribucións.

Así que a saída necesita o reenvío IPv4 activado de forma persistente, unha regra que admita as orixes do túnel do consumidor cara ao enlace ascendente e o camiño de resposta de volta polo tun. Activar o reenvío para todo o equipo tamén cambia o comportamento de calquera outra cousa que encamiñe a través del, por iso a regra debería nomear as orixes e as interfaces en lugar de aceptalo todo.

A tradución de orixe é o que compra o camiño de volta

Un equipo de internet non ten ruta cara a un enderezo 10.90.0.x, así que as respostas descartaríanse antes de chegar á saída. Reescribir a orixe mentres o paquete sae polo enlace ascendente resólveo, e o seguimento de conexións desfai a reescritura á volta.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp1s0 -j MASQUERADE
ip -4 route get 10.90.0.9   # run on the exit: must point at the tun

A regra de arriba é un punto de partida para unha interface ascendente, non unha política de cortafuegos. Estreita a orixe ás asignacións que realmente autorizaches e mantén a política de entrada propia da saída separada, para que a máscara do tráfico do túnel non expoña en silencio servizos locais. Nun equipo con enderezo ascendente dinámico, a máscara tamén che aforra seguir o enderezo a man.

Onde pode o concentrador impoñer normas e onde non

Con client-to-client e o camiño de datos tradicional de espazo de usuario, o concentrador entrega paquetes interiores entre pares dentro do proceso do servidor. Nunca atravesan a cadea FORWARD do núcleo do concentrador, así que unha regra do núcleo alí non pode restrinxir o tránsito entre pares, por coidadosamente escrita que estea. A imposición ten que vivir na política propia do servidor: quen pode conectarse, que ficheiro CCD recibe e se se concede ou non a propiedade por defecto da saída.

Por iso un iroute por defecto é unha decisión ampla de confianza. A saída debe aceptar lexitimamente tráfico de volta de enderezos de internet arbitrarios, e debe ser unha máquina que controles, parchees e vixíes. Darlle a mesma propiedade a un par ao que non lle confiarías un router é o erro ao que este deseño invita.

A pertenza é o control real. Calquera cliente que poida configurar as súas propias rutas pode intentar usar a saída, así que restrinxir quen pode conectarse, ou a que pares servirá a saída, forma parte do deseño e non é unha idea posterior.

Fallar de forma segura cando a saída desaparece

Desconecta a saída e a propiedade por defecto interior desaparece coa súa sesión. O que non debe pasar é que o concentrador se converta en silencio na saída substituta: ningunha ruta por defecto do conxunto VPN cara ao enlace ascendente do concentrador, e ningunha regra ampla de máscara que reenviaría de boa gana o mesmo tráfico. Proba ese fallo a propósito e logo proba a recuperación cun fluxo novo e non cunha páxina que xa estaba aberta.

# on the consumer, with the exit up and then down
ip -4 route get 1.1.1.1
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com

Se o tráfico do consumidor segue chegando a internet despois de que a saída se fose, algo máis o transporta e o límite que pretendías non existe. Trata DNS e IPv6 tamén como decisións separadas: unha ruta IPv4 máis máscara non di nada do tráfico AAAA, e un resolutor empurrado polo concentrador responderá desde onde saia realmente a consulta.

Artigos relacionados