Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Router un service non-HTTP

⚠️ On ne traite pas le cas OPNsense.

Contexte

Certains services (comme coturn) ne sont pas des services web et ne sont donc pas gérables par Caddy (qui est un reverse-proxy HTTP uniquement).

On suppose ce service installé sur une machine virtuelle sans accès direct à Internet.

Avec des approximations pour simplifier, la configuration est la suivante :

                                            ┌────────────────────────┐                                          
                                            │  Caddy                 │                                          
                                            │                        │                                          
                      ┌─────────────────┐   │  eth0  ─┐     eth1 ──┐ │                                          
                      │ Hyperviseur     │   │         │            │ │                                          
                      │                 │   └─────────┼────────────┼─┘            ┌─────────────────┐           
                      │                 │             │            │              │ VM service      │           
   ┌────────────┐     │                 │             │            │              │                 │           
   │            │     │                 │       vmbr0 │            │ vmbr10       │                 │           
   │  Internet  │     │                 │          ┌──┼──────┐  ┌──┼───────┐      │                 │           
   │            ┼─────┼─────►  eno1 ────┼──────────┼► ▼      │  │  ▼    ◄──┼──────┼───── eth0       │           
   │            │     │                 │          │         │  │    ▲     │      │                 │           
   └────────────┘     │                 │          └─────────┘  └────┼─────┘      │                 │           
                      │      vmbr10 ────┼────────────────────────────┘            │                 │           
                      │                 │                                         │                 │           
                      └─────────────────┘                                         └─────────────────┘           

L'hyperviseur a l'accès à Internet et route l'IPv4 et des blocs IPv6 vers le bridge vmbr0 à destination de Caddy, qui ensuite communiquera avec les VM de services via le bridge vmbr10, qui lui est interne.

On suppose ici que notre application écoute sur le port 3478 sur la VM, et qu'on veut pouvoir y accéder depuis l'Internet.

Prérequis

Vérifier que le port 3478 est ouvert sur l'hyperviseur et la VM.

Vérifier que le domaine a bien un enregistrement A qui pointe vers l'hyperviseur (pas de CNAME à cause de l'IPv6, voir plus bas).

Cas de l'IPv4

Puisque l'hyperviseur et la VM sont sur le bridge vmbr10, il suffit de NATer le port 3478 depuis l'hyperviseur.

iptables -t nat -A PREROUTING -d <IP SERVICE>/32 -p tcp --dport 3478 -j DNAT --to-destination <IP VM eth0>

Pour que le changement soit persistent au démarrage, le rajouter dans /etc/network/interfaces.

Cas de l'IPv6

Le NAT n'existe pas en IPv6. Côté hébergeur, il est coutume de router une IPv4 et un bloc /64 IPv6 vers les machines louées. Une IP de ce bloc doit être attribuée directement à une interface de la VM.

Choisir l'IPv6

En général, un sous-bloc est déjà routé sur vmbr0:

# Depuis l'hyperviseur
$ ip -6 route
2a01:4f8:2220:235b:1000::/80 dev vmbr0 metric 1024 pref medium
2a01:4f8:2220:235b:1001::/80 dev vmbr0 metric 1024 pref medium
[...]

⚠️ Il faut nécessairement être sur vmbr0 pour que la VM ait accès l'IP publique de l'hyperviseur (sa passerelle).

En général toujours, les premières IP de ce bloc sont utilisées (par l'hyperviseur, Caddy). Pour être sûr on peut par rapport prendre les derniers chiffres de l'IPv4 du service pour choisir la nouvelle IPv6. Par exemple, si l'IP termine par .7.12, on pourra choisir:

2a01:4f8:2220:235b:1000::712

Créer un enregistrement AAAA qui pointe vers cette IP.

Attribuer l'IPv6

En général, les VM n'ont pas d'IPv6. Il faut arriver à la situation suivante :

                                         ┌────────────────────────┐                                           
                                         │  Caddy                 │                                           
                                         │                        │                                           
                   ┌─────────────────┐   │  eth0  ─┐     eth1 ──┐ │                                           
                   │ Hyperviseur     │   │         │            │ │                                           
                   │                 │   └─────────┼────────────┼─┘            ┌─────────────────┐            
                   │                 │             │            │              │ VM service      │            
┌────────────┐     │                 │             │            │              │                 │            
│            │     │                 │       vmbr0 │            │ vmbr10       │                 │            
│  Internet  │     │                 │          ┌──┼──────┐  ┌──┼───────┐      │                 │            
│            ┼─────┼─────►  eno1 ────┼──────────┼► ▼      │  │  ▼    ◄──┼──────┼───── eth0       │            
│            │     │                 │          │     ▲   │  │    ▲     │      │                 │            
└────────────┘     │                 │          └─────┼───┘  └────┼─────┘      │                 │            
                   │      vmbr10 ────┼────────────────┼───────────┘            │      eth1       │            
                   │                 │                └────────────────────────┼────────┐        │            
                   └─────────────────┘                                         └────────┼────────┘            
                                                                                        │                     
                                                                                        │                     
                                                                                                              
                                                                            2a01:4f8:2220:235b:1000::712      

C'est-à-dire créer une nouvelle interface sur la VM de service, la connecter au bridge "public" (vmbr0), lui attribuer l'IP et renseigner sa passerelle.

L'adresse IPv6 de la passerelle est logiquement portée par vmbr0.

# Sur l'hyperviseur
$ ip -6 a l vmbr0 | grep global
inet6 2a01:4f8:2220:235b::3/128 scope global 

Pour créer une interface et la configurer de façon pérenne, on préfèrera passer par l'interface graphique de Proxmox.

Idem pour la configuration de l'IP de l'interface et la passerelle.

Il faut ensuite redémarrer la machine.

Réparer la route

À ce stade, l'IPv6 n'est parfois pas accessible, bien que la route avec la passerelle existe. C'est parce que la passerelle n'est apparemment pas sur le même bloc que l'IP de la VM. Par exemple sur d3/coquelicot :

# Route de la coquelicot vers la passerelle sur d3 :
default via 2a01:4f8:2220:235b::3 dev eth1 metric 1 pref medium
# IPv6 coquelicot :
2a01:4f8:2220:235b:1000::712/80

L'IP de la passerelle est en effet implicitement sur le /64, ce qui suffit à décourager le routage. Il faudra rajouter l'option onlink sur la route pour expliciter le fait que ces deux machines se trouvent bien à un saut d'écart.

Il faut recréer la route. Dans notre exemple :

ip -6 route delete default via 2a01:4f8:2220:235b::3 dev eth1 metric 1 pref medium
ip -6 route add default via 2a01:4f8:2220:235b::3 dev eth1 onlink