Connessioni API con IPv6

Seguito di: API connection via ipv6 vs. ipv4 - support - Discourse Meta

Recentemente ho aggiornato Node.js da 18 a 20 e la mia applicazione ha improvvisamente smesso di ricevere risposte API da Discourse. Mi ci è voluto un po’ per capire che era correlato al problema sopra menzionato. L’ho verificato effettuando una connessione solo tramite IPv4 come:

import {Agent} from 'node:https'
import axios from 'axios'
import {env} from 'node:process'
export const axiosDiscourse = axios.create({
  baseURL: 'https://<discourse-url>',
  headers: {
    'api-key': env['DISCOURSE_KEY'],
    'api-username': env['DISCOURSE_USERNAME']
  },
  httpsAgent: new Agent({
    family: 4
  })
})

la parte importante è specificare l’agente HTTP: prima lo usavo senza. Questo ora funziona, ma stavo tentando di migrare da Axios, in modo da poter utilizzare altre librerie basate su fetch come Wretch (principalmente per ridurre le dimensioni del bundle utilizzandolo anche nel frontend): elbywan/wretch: A tiny wrapper built around fetch with an intuitive syntax. :candy: (github.com). Tuttavia, non c’è opzione per specificare IPv4 o IPv6 con fetch. Pertanto, ho pensato che dovessi:

  1. Forzare l’uso solo di IPv4 in qualche modo e nonostante tutti i miei tentativi finora, questo non è stato possibile.
  2. Verificare con Discourse come potrei far funzionare questo su IPv6.

Sto connettendomi a varie altre API dalla mia applicazione, nessuna ha questo problema, è solo la connessione con Discourse che fallisce.

Questo è l’errore che sto ricevendo nel caso possa aiutare:

Error: connect ETIMEDOUT 184.105.99.43:443
    at createConnectionError (node:net:1634:14)
    at Timeout.internalConnectMultipleTimeout (node:net:1685:38)
    at listOnTimeout (node:internal/timers:575:11)
    at processTimers (node:internal/timers:514:7) {
  errno: -110,
  code: 'ETIMEDOUT',
  syscall: 'connect',
  address: '184.105.99.43',
  port: 443
},
Error: connect ENETUNREACH 2602:fd3f:3:ff01::2b:443 - Local (:::0)
    at internalConnectMultiple (node:net:1176:40)
    at Timeout.internalConnectMultipleTimeout (node:net:1687:3)
    at listOnTimeout (node:internal/timers:575:11)
    at processTimers (node:internal/timers:514:7) {
  errno: -101,
  code: 'ENETUNREACH',
  syscall: 'connect',
  address: '2602:fd3f:3:ff01::2b',
  port: 443
}

Ciò che è interessante è che, a differenza del thread menzionato sopra, non ricevo risposta dopo molto tempo. La mia richiesta fallisce immediatamente con questo errore. La chiamata API funziona bene nel browser, curl e qualsiasi altra cosa che posso testare.

Il mio modo di effettuare una richiesta all’API non ha importanza finché effettuo una richiesta dalla mia applicazione. Semplicemente fallisce e funziona solo utilizzando l’opzione family come menzionato sopra. Nel thread collegato, vedo questo menzionato:

Dovrai indagare sul perché le connessioni IPv6 non funzionano sulla tua rete.

Ho 2 preoccupazioni riguardo a questo:

  1. Non so come verificarlo specificamente.
  2. Non sono sicuro del perché questo dovrebbe essere un problema solo con Discourse, e solo con la mia applicazione.
1 Mi Piace

Un altro punto da notare è che questo accade solo all’interno della mia istanza WSL. Se eseguo la mia applicazione direttamente sul mio dispositivo host Windows, è in grado di connettersi correttamente.

So che questo è probabilmente qualcosa di molto specifico per la mia configurazione, ma al momento non so dove cercare i problemi. Qualsiasi suggerimento sarebbe utile!

1 Mi Piace

Sembra che la libreria che stai utilizzando stia tentando connessioni sia tramite IPv4 che IPv6; questa è una buona notizia e significa che non hai lo stesso problema di qui!

Affrontiamoli separatamente:

Ciò significa che il tuo lato ha inviato un TCP SYN per tentare la connessione all’istanza ospitata, ma non ha ricevuto una risposta. Ciò generalmente significa una delle seguenti cose:

  • la richiesta non è arrivata al server
  • il server (o qualcosa lungo il percorso) l’ha deliberatamente eliminata silenziosamente
  • la risposta non è tornata alla tua macchina

Poiché

è probabile che si tratti di un problema con la configurazione di rete sulla tua macchina.

Ciò significa che il tuo stack di rete ha detto “Non posso arrivarci” ed è normale poiché ciò che stai utilizzando evidentemente ripiega su IPv4.

Considerando tutto, sospetto che:

  • IPv4 fallisca dalla tua macchina (non è chiaro se questo sia vero, per favore verifica - “è in grado di connettersi bene” potrebbe significare che sta utilizzando IPv4 o IPv6)
  • IPv4 fallisca dal tuo container WSL
  • IPv6 funzioni dalla tua macchina
  • IPv6 fallisca dal tuo container WSL

Per favore, invia una nota a @team con il tuo indirizzo IPv4 esterno e verificheremo se viene deliberatamente scartato - abbiamo alcuni intervalli IP mal comportati bloccati e questo ci permetterà di escluderlo.

Se, tuttavia, sia IPv4 che IPv6 funzionano dalla tua macchina ma falliscono dal tuo container WSL, questo è qualcosa che dovrai risolvere per quanto riguarda la tua configurazione WSL.

Grazie mille per la tua risposta.

Per quanto riguarda i tuoi sospetti, ecco cosa ho potuto testare finora:

  • Ho provato a disabilitare IPv6 dalle impostazioni di Windows:

Il che, a mio parere, dovrebbe far sì che le connessioni avvengano solo tramite IPv4. Se è così, ha funzionato.

  • Ho provato a eseguire:
 curl -4 https://<host>/latest.json?order=created

da WSL ed è andato bene (ho ricevuto la risposta).

  • Non sono sicuro di come testare solo IPv6 perché non appena disabilito IPv4, in modo simile a IPv6 dallo screenshot sopra (lasciando IPv6 attivo), il mio PC si è fondamentalmente disconnesso da Internet - tutte le connessioni sono fallite, il che era prevedibile.

  • Ho provato:

 curl -6 https://<host>/latest.json?order=created -v
*   Trying 2602:fd3f:3:ff01::2b:443...
* Immediate connect fail for 2602:fd3f:3:ff01::2b: Network is unreachable
* Closing connection 0
curl: (7) Couldn't connect to server

da WSL e non ha funzionato… all’istante.

Ho riscontrato alcuni problemi con WSL oggi, quindi ho finito per configurare una nuova installazione. Questa è un’istanza nuovissima con installati solo asdf e Node.js (e tutti i pacchetti di sistema aggiornati). Non sono sicuro se questo sia ancora correlato a qualche errata configurazione lato WSL - dovrei usare tutte le impostazioni predefinite in questo momento.

Sto condividendo il mio indirizzo IPv4 pubblico con il gruppo menzionato.

Beh, non vedo ancora un modo per inviare un messaggio privato, probabilmente perché sono un nuovo utente.

Qualcosa di più interessante… mentre controllavo il mio indirizzo IPv4 pubblico, il sito web ha tentato di mostrarmi anche il mio indirizzo IPv6 e ha detto: IPv6 non rilevato. Quindi, sono andato a verificare se avessi una connessione IPv6, e ho trovato questa pagina: Come configurare il servizio IPv6 sul router wireless TP-Link

Mostra che i router dovrebbero avere una sezione dedicata per utilizzare IPv6. Il mio router non ne ha una e non ottengo nemmeno l’opzione PPPoE v6 come mostrato lì. Quindi, forse, il mio router non supporta affatto IPv6 - il che potrebbe essere il motivo per cui le connessioni IPv6 non funzionano (e anche il motivo per cui ho sostanzialmente perso la connettività Internet quando ho disabilitato IPv4 nelle impostazioni di Windows).

EDIT: Ho questo router TL-WR841N | Router Wireless N da 300 Mbps | TP-Link India e dice che supporta IPv6 :thinking:

EDIT2: Ma usando qualcosa come: v6.testmyipv6.com mi dà ERR_NAME_NOT_RESOLVED, quindi sembra che IPv6 non funzioni davvero per me.

Se questo è il problema, ancora non capisco perché sia iniziato a succedere all’improvviso. Ha funzionato bene per un bel po’ di tempo.

Ti ho dato una piccola spinta. :slight_smile: Dovresti vedere il pulsante del messaggio se fai clic su @team ora. :+1:

1 Mi Piace

Grazie, inviato!

1 Mi Piace

Dato aggiuntivo, sono passato all’hotspot dalla mia rete mobile che utilizza IPv6. Ora posso verificare utilizzando:

curl -6 https://<host>/latest.json?order=created -v
*   Tentativo di connessione a 2602:fd3f:3:ff01::2b:443...
* Fallimento immediato della connessione per 2602:fd3f:3:ff01::2b: Rete non raggiungibile
* Chiusura connessione 0
curl: (7) Impossibile connettersi al server

fallisce ancora in modo simile. Tuttavia, con IPv4 disabilitato nelle impostazioni di Windows, riesco ad accedere a Internet a differenza di prima. Quindi nuovi dati:

  • IPv4 su Windows: Funziona
  • IPv6 su Windows: Funziona
  • IPv4 su WSL: Funziona
  • IPv6 su WSL: Fallisce

Se non specifico -4 o -6 a curl, torna a IPv4 (IPv6 fallisce immediatamente):

curl https://<host>/latest.json?order=created -v
*   Tentativo di connessione a 184.105.99.43:443...
*   Tentativo di connessione a 2602:fd3f:3:ff01::2b:443...
* Fallimento immediato della connessione per 2602:fd3f:3:ff01::2b: Rete non raggiungibile
* Connesso a <host> (184.105.99.43) porta 443 (#0)

Ho anche eseguito:

ping -6 google.com

Sia da Windows che da WSL. Funziona su Windows, fallisce in WSL. Penso di avere ora abbastanza informazioni e convalida che qualcosa non va con la connettività IPv6 della mia istanza WSL. Sembra un problema: cannot reach ipv6 only address · Issue #4518 · microsoft/WSL (github.com)

Finalmente!

Sulla base della discussione collegata sopra, sono stato in grado di aggiungere

[experimental]
networkingMode=mirrored

a .wslconfig e questo mi ha dato connettività IPv6 all’interno della mia istanza WSL. Ora posso eseguire correttamente:

curl -6 https://<host>/latest.json?order=created

Non funziona ancora sulla mia rete Wi-Fi, e questo è molto probabilmente perché questo vecchio router non supporta l’IPv6. Funziona bene quando uso l’hotspot del mio telefono.

Grazie mille @JammyDodger per gli spunti, mi hai guidato nella giusta direzione!

OK, quindi qualcosa è evidentemente cambiato tra il post originale e questo, dato che stavi ricevendo:

Sono contento di vedere che ora funziona.

Sì, ancora mi lascia perplesso. Come avevo già detto, prima riuscivo a inviare una richiesta curl tramite WSL e funzionava. In qualche modo, stava fallendo usando Axios nella mia applicazione (forse è una cosa di Axios o di Node.js?).

In qualche modo, curl -4 funziona ancora, e anche Axios funziona quando specifico httpFamily come mostrato nel mio post originale. Ma non è un errore per cui perderò altro sonno.

Solo per verifica, sono tornato a Node.js 18 e sono stato in grado di connettermi senza specificare httpFamily, quindi questo è sicuramente qualcosa che è cambiato in Node.js 19 o 20. Ma per questo, almeno ho scoperto questa cosa dell’IPv6, altrimenti non avrei ancora cercato o imparato su questo.

Sono anche in grado di eseguire il codice con bun invece di Node.js senza dover specificare la cosa dell’IPv4. Ho contattato Node.js: https://github.com/orgs/nodejs/discussions/50826