Todo funciona ata que o executador de compilación necesita o mesmo socket do servidor que usa o convidado VPN, e entón ninguén pode explicar por que unha tarefa pode ler as chaves da pasarela. Todo se instalou nunha soa máquina porque cabía, e a cada convidado déuselle acceso amplo porque era a forma máis rápida de facelo funcionar. O resultado é un servidor cuxa fronteira de confianza é o cable de alimentación. Separar os roles custa menos traballo do que parece, e comeza por poñerlles nome.

Tres roles que agora comparten todo

Unha entrada VPN, un conxunto de servizos privados e un executador de compilación queren cousas distintas. O primeiro necesita un porto público e unha rede estreita no lado privado. O segundo necesita almacenamento persistente e segredos de aplicación. O terceiro executa código que escribiu outra persoa.

Dar aos tres o mesmo acceso é o que fai confuso o síntoma, porque entón calquera deles pode afectar os demais. Unha tarefa de compilación que alcanza o socket do hipervisor é unha tarefa que pode deter a VPN. Un convidado de servizos cunha ruta á rede de xestión pode cambiar a configuración do conmutador. Os privilexios son o problema, e a lista de procesos só é onde se ve. Nomear primeiro os roles dá a cada privilexio un lugar onde vivir.

O esquema de abaixo é un punto de partida para esa separación, non unha promesa de alta dispoñibilidade. Trátao como unha hipótese que verificar, non como o deseño rematado.

Separa tres roles, non tres procesos

Tres convidados nun servidor dan tres conxuntos de privilexios e tres posicións de rede. Non dan tres dominios de fallo, e o deseño debería dicilo en voz alta.

A separación só axuda se un compromiso nun convidado non concede automaticamente os demais, e iso é un axuste do hipervisor, non unha convención de nomes. Chamar pasarela a unha VM non impide que outro convidado chegue ao servidor. Le a configuración do conmutador virtual en lugar do nome do servidor e despois confirma que cada convidado está onde cres.

host
├─ vpn-gw      10.60.10.2/24   public 51820/udp only
├─ services    10.60.0.10/24   no route to the management network
└─ ci-runner   10.60.20.2/24   outbound only, no host socket

Escribe a topoloxía e despois verifícaa coas ferramentas que a posúen. Un convidado que aparece na ponte equivocada é un achado, non un detalle. Corrixe a rede antes de cambiar calquera configuración de servizo.

Deixa que o convidado VPN abra só as portas que posúe

Publica o porto do túnel no enrutador e nada máis. Os portos de administración de convidados pertencen a un camiño de xestión, non a internet, e a propia interface do hipervisor tamén pertence alí.

A rede do lado privado debería chegar aos servizos que necesitan os usuarios remotos e deterse aí. A autenticación da aplicación segue activada, porque un túnel é transporte e non un inicio de sesión. Mantén a táboa de rutas do convidado VPN o bastante pequena para describila nunha frase. Se non podes describila con esa sinxeleza, a fronteira xa se difuminou.

virsh net-list --all
virsh net-dumpxml lab-private
sudo nft list ruleset | grep -n -E '51820|10.60'

Calquera cousa que escoite no servidor e non se necesite para a xestión non debería escoitar en absoluto. Iso inclúe a API do hipervisor, que é fácil deixar exposta nunha interface pública.

As tarefas de compilación necesitan outro tipo de fronteira

Unha tarefa de CI executa ordes controladas polo repositorio, así que a súa confianza depende de quen pode subir código. Un executador de shell executa esas ordes como o usuario do executador no servidor, e esa é a fronteira máis ampla dispoñible.

Os executadores de contedores son máis estreitos, e un contedor privilexiado non é dos estreitos. Mantén o executador no seu propio convidado co seu propio ámbito de rede, e dálle só o acceso a artefactos e despregamento que necesitan as tarefas. Os traballadores refugables reducen o estado retido; non reducen a alcanzabilidade nin a exposición de segredos. Ambas as cousas aínda necesitan límites explícitos.

O convidado de servizos posúe os datos, así que o seu plan de copia de seguridade é o que ten que funcionar. Mantén os repositorios, as subidas e a base de datos no mesmo calendario. Proba unha restauración en lugar de ler o estado da tarefa.

Planifica o fallo que comparten os tres

Un servidor é un dominio de fallo. Un reinicio elimina o túnel e todos os servizos privados no mesmo momento, e é xusto cando unha vía de entrada importa máis.

Conserva un acceso por consola que non dependa do convidado VPN, xa sexa unha consola física, unha interface de xestión fóra de banda ou unha consola do provedor. Unha instantánea gardada no mesmo disco non é unha copia independente, e unha copia de seguridade que se executa dentro do convidado que protexe tampouco. Despois proba o arranque en frío como unha secuencia e non como unha lista: servidor, redes virtuais, camiño do túnel e unha aplicación nomeada baixo unha conta ordinaria.

virsh list --all
systemctl is-active libvirtd
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://10.60.0.10/
ss -ltnp | grep -E ':51820|:443'

A orde de arranque dos procesos non demostra nada sobre rutas e DNS, así que proba o camiño en lugar dos estados das unidades. O camiño é o que un usuario remoto necesita de verdade.

Artigos relacionados