Skip to content

Repository files navigation

AltWFC — serveur Nintendo WFC privé, sur le LAN

Les serveurs Nintendo Wi-Fi Connection sont éteints depuis 2014. Ce dépôt fait tourner AltWFC (dwc_network_server_emulator) sur le Mac, en Docker, pour rejouer en ligne sur les jeux DS et Wii — ici Mario Kart Wii — depuis une vraie console et depuis Dolphin, sans dépendre d'un service tiers et sans ouvrir un seul port sur la box.

Ce README est la synthèse. Le détail, les procédures et les pièges sont dans SETUP.md ; le raisonnement qui a mené à ces choix est dans docs/superpowers/specs/2026-08-06-altwfc-selfhost-design.md.

En un coup d'œil

Serveur 192.168.1.100 (le Mac), 3 conteneurs sous OrbStack
Exposition LAN uniquement, aucun port ouvert sur la box
Clients validés vraie Wii softmoddée · Dolphin sur Ayn Thor (Android)
Jeu validé Mario Kart Wii, en ligne, à plusieurs
État fonctionnel, vérifié les 2026-08-06 et 2026-08-07

Démarrer, arrêter

cd ~/code/wii/dwc-docker

docker compose up -d        # démarrer
docker compose ps           # état des 3 conteneurs
docker compose logs -f dwc  # suivre les connexions en direct
docker compose down         # arrêter — les comptes survivent

Les comptes, profils et friend codes vivent dans le volume Docker dwc-docker_data. Un down ne les détruit pas ; seul un down -v le ferait.

Le principe, en trois pièces

La console croit parler à Nintendo. On ne la modifie pas, on modifie le monde autour :

   console  ──DNS──▶  dnsmasq      « nintendowifi.net ? → 192.168.1.100 »
            ──HTTP─▶  HAProxy      aiguille selon l'en-tête Host
                        └────────▶ dwc   13 services GameSpy / NAS / Storage
  • dnsmasq ment sur *.nintendowifi.net et relaie le reste vers 1.1.1.1, pour que la console garde un accès internet normal.
  • HAProxy écoute sur le port 80 et route par nom d'hôte (nas, sake, gamestats, dls1). Une requête arrivant par IP brute est rejetée en 503 : c'est normal, pas une panne.
  • dwc est l'émulateur lui-même, code de 2014 en Python 2.7, épinglé à un commit précis dans le Dockerfile pour que deux builds à deux mois d'écart donnent le même serveur.

Une pièce manque, et elle est dans le jeu. La Wii contacte le NAS en HTTPS, avec un certificat Nintendo qu'on ne peut ni reproduire ni faire accepter. Rediriger le nom ne sert à rien si la poignée de main TLS échoue derrière : chaque jeu doit être converti en HTTP. C'est la grande différence avec la DS, dont le NAS accepte le trafic en clair.

Choisir sa voie côté client

Client DNS Patch HTTPS→HTTP
Vraie Wii Réglages Wii → Internet, DNS primaire 192.168.1.100 USB Loader GX, Private Server = NoSSL only — à la volée, le disque n'est jamais modifié
Dolphin / Android réglage Wi-Fi + RethinkDNS (voir piège n°2) ISO patchée d'avance avec les outils Wiimm
Dolphin / macOS une ligne dans /etc/hosts idem, ISO patchée

Deux points qui font gagner du temps :

  • Sur console, choisir NoSSL only et surtout pas AltWFC malgré le nom : cette entrée-là réécrit le domaine en zwei.moe, que ni dnsmasq ni HAProxy ne connaissent.
  • Dolphin n'a aucun réglage DNS pour la Wii, ni sur Android ni sur desktop. Le « DNS Server » de son interface pilote l'adaptateur Broadband GameCube. C'est le DNS du système hôte qui décide.

Procédures complètes dans SETUP.md : « Client 2 — vraie console Wii softmoddée », « Client 1 — Dolphin sur Ayn Thor », « Patcher l'ISO (voie Dolphin) ».

Les deux pièges qui coûtent une soirée

1. L'IP du Mac est distribuée par DHCP. Tout le montage repose sur 192.168.1.100 : au renouvellement du bail, l'adresse change et tout casse d'un coup, le DNS pointant vers une machine qui n'existe plus. C'est arrivé le 2026-08-07. Une réservation DHCP est posée depuis ; si l'IP dérive quand même, il faut la corriger dans dwc-docker/dnsmasq/dnsmasq.conf. Symptôme : ipconfig getifaddr en0 ne dit plus .100.

2. Sur Android, le réglage DNS du Wi-Fi ne pilote que l'IPv4. La box annonce en plus son propre résolveur IPv6 par Router Advertisement, qu'aucune case de l'interface Android ne couvre — et c'est lui qui gagne. Le jeu obtient alors les vraies IP Nintendo, mortes depuis 2014, et affiche erreur 23301 sans qu'un seul paquet n'atteigne le Mac. La vraie Wii y échappe parce qu'elle ignore l'IPv6 : la différence n'était pas entre l'émulateur et la console, mais entre pile simple et double pile. Correctif retenu : RethinkDNS en mode proxy Do53 vers 192.168.1.100:53, « Empêcher les fuites DNS » sur ON. Voir SETUP.md, « Le piège IPv6, qui coûte une soirée » et « Le correctif : RethinkDNS ».

Diagnostic express

Le test le plus concluant tient en une ligne, console Android branchée en USB :

adb shell ping -c 1 zzz-nimportequoi.nintendowifi.net

Ce nom n'existe pas chez Nintendo. S'il répond 192.168.1.100, c'est le joker de dnsmasq qui a parlé — aucun autre résolveur au monde ne peut produire cette réponse. C'est une preuve, pas un indice. Sinon, la console interroge quelqu'un d'autre.

Côté serveur, docker compose logs -f dwc : une connexion réussie laisse gamename: mariokartwii, un authtoken, un profileid et un friend code. La section « Diagnostiquer quand ça ne marche pas » de SETUP.md détaille le reste, dont deux pièges de mesure — tcpdump sur en0 ne voit que ce qui est adressé au Mac, et une capture vide ne prouve donc rien.

Structure du dépôt

SETUP.md            le cahier de bord : procédures, pièges, diagnostics
dwc-docker/         submodule → Jobierre/dwc-docker (fork de TheForcer)
  docker-compose.yml    3 services : haproxy, dwc, dnsmasq
  Dockerfile            build de l'émulateur, commit épinglé
  haproxy.cfg           routage par en-tête Host
  dnsmasq/              le résolveur menteur — c'est ici qu'est l'IP du Mac
  README.md             le README amont, conservé tel quel
upstream-src/       submodule → Jobierre/dwc_network_server_emulator
                    (fork de barronwaffles, code de l'émulateur, en lecture)
docs/superpowers/   le design et les décisions

Les deux sous-dossiers sont des submodules pointant sur mes forks, donc un clone simple les laisse vides :

git clone --recurse-submodules https://github.com/Jobierre/wii-server-2026.git

# dépôt déjà cloné sans l'option :
git submodule update --init

Chaque fork garde un remote upstream vers le dépôt d'origine, pour pouvoir récupérer une correction amont par git fetch upstream && git merge upstream/main.

Note : upstream-src/ n'est utile qu'à la lecture. Le Dockerfile ne s'en sert pas — il clone lui-même l'émulateur au commit 2c65a9f, épinglé dans son ARG DWC_COMMIT, qui est exactement celui référencé ici.

Le Dockerfile a dû être repris : python:2.7-slim repose sur une Debian archivée dont les dépôts renvoient 404, et Twisted ne s'installe plus par pip en Python 2.7. Il vient donc d'APT. Le détail est dans le design doc.

Limites connues

  • LAN uniquement, c'est un choix. Jouer avec des amis distants demanderait d'ouvrir onze ports et un vrai nom de domaine.
  • Le serveur vit avec le Mac : il s'arrête quand la machine s'éteint. Le stack se transplante tel quel sur un LXC Proxmox ou sur Unraid — seules les IP de dnsmasq.conf changeraient.
  • Le port 53 est occupé tant que le stack tourne, à savoir si un Pi-hole local arrive un jour.
  • Code de 2014, Python 2.7 : la compatibilité varie titre par titre.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors