Quand l’émulateur n’atteint pas un serveur de build que le navigateur de l’hôte ouvre sans problème, la question utile n’est pas de savoir si le VPN fonctionne. C’est de savoir lequel de deux mécanismes manque à l’invité. L’appareil virtuel exécute sa propre pile réseau derrière le NAT de l’émulateur, et sa liste de résolveurs est une copie prise au démarrage, donc un tunnel monté ensuite change le chemin de l’hôte sans changer ce que l’invité demande. Comprendre ces deux couches explique presque toutes les variantes de ce problème.

L’invité est une pile distincte derrière un NAT fixe

Le réseau QEMU en mode utilisateur place l’invité à 10.0.2.15, la passerelle à 10.0.2.2 et le service DNS à 10.0.2.3 jusqu’à 10.0.2.6. Le trafic sortant de l’invité n’est pas relayé par le noyau de l’hôte ; il est traduit en sockets côté hôte, une par connexion de l’invité, et ces sockets sortent de l’espace d’adressage de l’hôte. C’est pourquoi une connexion de l’invité hérite de la décision de routage de l’hôte au moment de sa création, et pourquoi l’invité n’a aucune entrée dans la table de routage qui nomme votre tunnel.

Le même mécanisme donne à l’invité une sortie utile. 10.0.2.2 est un alias de l’interface de bouclage de l’hôte, donc un service qui écoute sur 127.0.0.1 sur le portable est joignable depuis l’invité à cette adresse. Tout ce que le client n’expose que sur la boucle est joignable ainsi, et c’est la base du montage de proxy décrit plus bas.

Ce que l’invité ne peut pas faire, c’est observer le réseau de l’hôte comme s’il était un espace de noms posé dessus. Il n’y a ni pont, ni table de routage partagée, ni résolveur hérité, seulement le service NAT qui accepte ses paquets et l’instantané que le lanceur a pris au démarrage de l’appareil virtuel.

Le DNS est un instantané, pas une vue en direct

Au démarrage, l’émulateur lit la liste de résolveurs de l’hôte et remet à l’invité jusqu’à quatre serveurs, exposés aux adresses 10.0.2.3 à 10.0.2.6. Si le tunnel était coupé à ce moment, l’instantané contient le résolveur public que le portable utilisait, et l’invité continue de l’interroger toute sa vie. Les noms publics se résolvent, les noms internes échouent, et chaque symptôme désigne le VPN alors que la valeur périmée réelle est une liste de résolveurs capturée quelques minutes avant la montée du tunnel.

La correction par l’ordre n’est donc pas une légende. Connectez d’abord le tunnel, redémarrez ensuite l’émulateur, et préférez un démarrage à froid à une restauration d’instantané, car une image de démarrage rapide peut revenir avec l’état de résolveur et de routage qu’elle avait enregistré. Si vous voulez voir ce que l’invité utilise maintenant, interrogez l’appareil et non l’hôte :

adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.example

L’émulateur accepte aussi un résolveur explicite au lancement, ce qui est utile quand vous savez exactement quel serveur l’invité doit utiliser et dangereux quand ce serveur est public :

emulator -avd Pixel_API_34 -dns-server 203.0.113.53

Un résolveur public n’a aucune copie d’une zone interne, donc en épingler un transforme un problème d’ordre en échec permanent. Si le profil impose un DNS privé, laissez le tunnel le fournir et démarrez l’invité à froid au lieu de coder en dur une adresse.

Le routage suit l’hôte au moment de la connexion

Comme les connexions de l’invité deviennent des sockets de l’hôte, la décision de routage est prise à la création du socket. Un tunnel monté avant la requête signifie que la requête sort par le tunnel selon les routes du profil. Un profil à tunnel divisé qui ne transporte que des préfixes choisis laissera volontiers votre sous-réseau privé dehors, donc la joignabilité de l’hôte est une hypothèse sur l’invité, pas un résultat. Les connexions existantes de l’invité gardent le chemin avec lequel elles ont été créées, c’est pourquoi un client qui se reconnecte ne corrige pas toujours un téléchargement bloqué dans l’émulateur.

La vérification se fait sur l’interface de l’hôte, pas dans les statistiques de l’invité :

sudo tcpdump -ni tun0 'host 203.0.113.10'

Si la requête de l’invité apparaît sur l’interface du tunnel, le routage fonctionne et le problème est au-dessus. Si elle apparaît sur l’interface physique, le profil ne couvre pas ce préfixe, et aucune reconfiguration côté invité n’y changera rien.

Quand le client ne propose qu’un proxy de bouclage

Certains clients commerciaux ne créent aucun tunnel système. Ils exposent un écouteur HTTP ou SOCKS sur 127.0.0.1 et attendent que les applications l’utilisent. L’invité ne voit pas ce socket directement, mais on peut dire à l’émulateur de l’utiliser, soit par les contrôles étendus (Paramètres, puis Proxy, mode manuel, hôte 127.0.0.1 et le port affiché par le client), soit au lancement :

emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080

Copiez le port depuis la fenêtre du client ; un port deviné échoue en silence et ressemble à un tunnel cassé. Gardez à l’esprit ce que cela couvre : un réglage de proxy HTTP est respecté par les applications conscientes du proxy, et les sockets bruts l’ignorent totalement. Si la charge de travail est un binaire natif qui ouvre ses propres connexions, le chemin par proxy n’équivaut pas à un tunnel et la comparaison doit être faite explicitement.

Prouvez le résultat depuis l’intérieur de l’invité

Séparez la résolution du routage avec deux tests dans la même session. Un nom qui échoue alors que l’adresse numérique répond est un problème d’instantané DNS, et la correction est l’ordre ou un résolveur explicite. Si les deux échouent, cela indique le routage ou la politique, et la vérification suivante est de savoir si l’application tourne dans un profil de travail avec ses propres restrictions réseau.

Enfin, sachez sur quel invité vous testez. De très anciennes images de l’émulateur ont été livrées sans le support tun dont un client VPN côté invité a besoin, donc aucun profil n’y pouvait fonctionner ; les images actuelles l’incluent. Un client qui échoue sur une image actuelle est un problème de client ou de profil, et reconstruire le tunnel de l’hôte ne changera pas le résultat.

Articles similaires