Un cliente marca o servidor OpenVPN nunha VM de Compute Engine, a xanela de estado di conectado, e un ping a un host dentro da VPC segue sen chegar a ningures. O instinto é engadir outra liña push, e iso nunca o arranxa. Compute Engine decide cara a onde van os paquetes a partir da súa propia táboa de rutas e das direccións que unha interface da VM ten realmente, así que un pool de túnel que a VM non posúe é un pool ao que ninguén entrega.

Segue o paquete que falla en lugar do ficheiro de configuración, e as pezas que faltan aparecen en orde.

Comezar polo paquete que morre

O SYN sae do cliente, entra no túnel e chega á VM como un paquete encapsulado cara a un destino dentro da VPC. OpenVPN desencapsúlao e intenta reenvialo por eth0, onde a fabric fai unha pregunta antes de todo o demais: esta instancia posúe o enderezo de destino. Un pool de túnel recortado da subrede doutra persoa falla esa pregunta, e o paquete descártase antes de que se consulte calquera ruta ou regra de firewall.

Así que a dirección de cliente a VPC ten dous requisitos separados, e ningún deles é unha directiva push. A VM necesita un rango alias que cubra o pool de túnel, e iso é o que a converte en propietaria lexítima deses enderezos. A VPC necesita unha ruta que nomee a VM como next hop para cada prefixo protexido. Falte un dos dous e o paquete morre noutro sitio, mentres o cliente ve o mesmo silencio.

Le a falla nesa orde, porque desde o lado do cliente as dúas condicións son idénticas. Un túnel que di conectado mentres nada responde é a sinatura dun problema de topoloxía, non dun cifrado malo.

A instancia posúe o pool de túnel

Dálle á VM un rango secundario dentro da súa propia subrede e despois fai que OpenVPN reparta enderezos exactamente dese rango. Nunha instancia cuxo enderezo primario é 10.156.0.10/20, un alias /28 mantén o pool separado dos enderezos que outras instancias xa teñen:

gcloud compute instances network-interfaces update openvpn-vm \
  --zone=europe-west1-b \
  --aliases=eth0:10.156.1.0/28

A directiva server ten entón que describir o mesmo bloque. O seu primeiro enderezo pasa a ser a pasarela do túnel, e os enderezos restantes repártense aos clientes. Aquí dous números describen un bloque, unha rede e unha máscara, e esa é a sintaxe de pool que OpenVPN aínda espera.

server 10.156.1.0 255.255.255.240

Confirma que o enderezo chegou de verdade á interface e non só dentro da configuración de OpenVPN. A fabric reenvía o que informa a NIC, non o que creo o daemon. Un só comando o resolve:

ip -4 addr show dev eth0

Un enderezo secundario que nunca chega a eth0, ou un pool que se solapa con outra subrede, aparece máis tarde como perdas intermitentes en lugar de como un erro de arranque. O daemon arrinca, os clientes conéctanse, e só algúns destinos se comportan mal. Mantén pequeno o rango alias para que o pool sexa fácil de recoñecer nunha táboa de rutas. Nunca o recortes dunha subrede que outra instancia xa usa.

Darlle un next hop ao tráfico de retorno

Unha resposta dun host da VPC diríxese a un enderezo de cliente no pool de túnel, que non pertence a ningunha subrede que a VPC coñeza. Sen unha ruta para ese pool, a resposta detense no primeiro salto sen coincidencia, e a petición ben puido ter éxito no extremo remoto.

gcloud compute routes create openvpn-return \
  --network=prod-vpc \
  --destination-range=192.168.127.0/24 \
  --next-hop-instance=openvpn-vm \
  --next-hop-instance-zone=europe-west1-b \
  --priority=800

A mesma ruta fai falta para calquera prefixo que viva detrás dun cliente en lugar de dentro da VPC. Eses prefixos tamén necesitan unha entrada iroute no ficheiro ccd dese cliente. Esa entrada é contabilidade do lado do servidor: dille ao servidor que cliente posúe o prefixo, e non instala nada no propio cliente.

Garda a lista push para o lado cliente da conversa, porque só engade rutas á máquina que se conecta. Unha liña push para unha subrede da VPC e unha ruta da VPC de volta ao pool son dúas metades do mesmo camiño, e calquera metade soa produce un túnel que leva peticións pero non respostas.

Firewalls, reenvío e os saltos polo medio

A firewall da VPC avalía o paquete desencapsulado, así que unha regra de entrada ten que admitir o pool de túnel e calquera prefixo de sitio que chegue á VM por esa vía. Unha postura de denegación por defecto falla en silencio aquí: o paquete descártase despois do desencapsulamento, e o rexistro de OpenVPN mostra unha sesión sa.

En calquera host Linux que reenvíe en lugar de terminar, comproba que net.ipv4.ip_forward está activado. A regra de propiedade tamén se aplica aí: unha máquina que reenvía para unha subrede que non ten descarta o paquete igual que o faría a VM. Le o valor antes de culpar o túnel.

Cando falla exactamente un prefixo

A falla parcial é o caso máis fácil de ler, porque todo o demais do camiño xa está demostrado. Comeza pola lista de rutas e le o rango de destino e o next hop da entrada que debería cubrir o prefixo, despois le a descrición da instancia e compara o seu rango alias co pool que reparte o servidor.

gcloud compute routes list --filter=destination-range~10.164.0.0
 gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)

Unha ruta que falta amósase como ausencia de next hop para o prefixo, mentres que un alias que falta amósase como un paquete descartado na interface; desde o cliente as dúas cousas parécense e nesas dúas saídas son completamente distintas. Se están as dúas, o sospeitoso restante é o iroute ccd do cliente que reclama o prefixo.

Apunta os catro valores xunto ao túnel: rango alias, pool do servidor, prefixos empurrados, rutas da VPC. Un alias obsoleto rompe cada enderezo do pool, unha ruta obsoleta rompe un sentido, un push ausente esconde o prefixo ao cliente, e un iroute equivocado manda o prefixo ao par equivocado. A seguinte persoa que engada unha subrede necesita os catro nun só sitio, e a nota sae máis barata ca noite.

Artigos relacionados