Puncte:2

Accesați aplicația WSL2 Ubuntu în rețeaua mașinii găzduite

drapel tr

Rulez o aplicație în WSL2 a cărei distribuție este Ubuntu 20.04. Pot accesa aplicația în browser Windows cu IP-ul Ubuntu.

Acum, vreau să accesez această aplicație în rețeaua mea (adică în rețeaua mea de birou pe altă mașină)

Înțeleg că IP-ul ubuntu este disponibil numai pentru mașina gazdă. Cum îl pot pune la dispoziția altora din rețeaua mea?

Cum putem face asta? Te rog ajuta-ma.

drapel hr
WSL sau WSL2? procedura pare să fie diferită - vezi, de exemplu, [WSL Port Forwarding](https://dev.to/vishnu12/wsl-port-forwarding-2e22)
drapel tr
Este WSL2, dar exemplul de mai sus este pentru WSL. Te rog corectează-mă dacă greșesc
drapel hr
*Cred* că nu trebuie să faceți nimic pentru WSL (ar trebui să „funcționeze doar”), în timp ce pentru WSL2 trebuie să configurați redirecționarea portului așa cum este descris în articolul legat. Dar să vedem ce răspunsuri primești.
NotTheDr01ds avatar
drapel vn
@steeldriver Ai dreptate. Voi adăuga mult mai multe detalii în răspunsul meu. A trecut ceva timp de când am făcut asta, dar am câteva idei noi de încercat de ultima dată pe care le voi propune dacă funcționează. Redirecționarea portului va funcționa, dar această postare pare să complice prea mult. Sper să pot propune ceva mai eficient, dar vom vedea.
drapel hr
@NotTheDr01ds grozav - aștept cu nerăbdare să citești!
NotTheDr01ds avatar
drapel vn
Și @Raushan, doar pentru claritate, documentul pe care Steeldriver l-a legat este pentru WSL2. După cum se notează în partea de sus, WSL1 nu avea nevoie de așa ceva. Dar din nou, nu urma acel document. Va funcționa, dar am o soluție (pe care am confirmat-o acum) pe care o scriu ca răspuns care cred că este mai ușor.
Puncte:3
drapel vn

Răspuns scurt pentru WSL1:

Configurați regulile pentru firewall o dată și totul ar trebui să „funcționeze”. Aceasta este cea mai ușoară metodă.

Răspuns scurt pentru WSL2:

După ce aveți lucrurile configurate corect, puteți iniția foarte ușor redirecționarea portului cu o singură comandă din Ubuntu/WSL2:

ssh -f -N -R 8080:localhost:8080 „$(hostname).local”

Detalii despre modul de configurare sunt mai jos. Nu este neapărat ușor, dar totul este o configurare o singură dată.


(Mult) mai multe detalii:

După cum a menționat Steeldriver în comentarii, WSL1 și WSL2 se comportă diferit aici.

Notă secundară doar pentru a clarifica terminologia (deoarece diferă ușor în comentarii): „WSL” se referă la subsistemul în sine care controlează ambele versiuni - WSL1 și WSL2.

Notă secundară 2. Vă rugăm să nu lăsați lungimea acestei postări să vă sperie. eu sunt doar foarte detaliat. Considerând problemă legată de Github este de până la (momentan) 536 de comentarii, cred că sunt destul de concis prin comparație ;-).


WSL1

WSL1 este cu siguranță cazul de utilizare mai ușor. Deoarece este un „strat de traducere” între apelurile de sistem Linux și kernel-ul Windows, acesta utilizează de fapt interfața(e) de rețea Windows „adevărată”. Din acest motiv, vă puteți conecta direct de pe un alt dispozitiv din rețea la un port din WSL1.

Probabil tu do mai trebuie totuși o regulă pentru firewall. Voi acoperi asta în răspunsul WSL2, deoarece este comun pentru ambele. Vezi New-NetFirewall Rule comanda din secțiunea WSL2. Doar rulați acea comandă (o singură dată) pentru regula firewall.

Cu toate acestea, dacă aplicația dvs. web nu necesită WSL2 (și majoritatea o fac nu), este de obicei mult mai ușor să-l rulați dintr-o instanță WSL1 (sau cel puțin era înainte). Asta fac majoritatea oamenilor. Pe de altă parte, cu noua metodă (cel puțin pentru mine) WSL2/SSH pe care o propun mai jos, nu mai este atât de dureros ca înainte să faci asta în WSL2. Vă las pe voi ce rută să alegeți. În acest moment, consider că oricare dintre ele este la fel de valabil.

Dacă alegeți să utilizați WSL1, aș recomanda să păstrați două instanțe Ubuntu -- Una cu WSL1 și alta cu WSL2. Asta fac.

Pentru a copia instanța WSL2 existentă într-un nou WSL1, părăsiți cel existent și, din PowerShell:

# Ajustați calea de bază după cum doriți
$WSL_ROOT = "$env:USERPROFILE\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p „$WSL_ROOT\imagini”
mkdir -p „$WSL_ROOT\instances\Ubuntu_WSL1”
cd $WSL_ROOT
wsl -l -v
# Confirmați numele distribuției - Dacă nu este „Ubuntu”, ajustați următoarea linie după cum este necesar
wsl --export Ubuntu „$WSL_ROOT\images\$WSL_IMAGE_NAME”
wsl --import Ubuntu_WSL1 .\instances\Ubuntu_WSL1\ .\images\$WSL_IMAGE_NAME --versiunea 1
wsl ~ -d Ubuntu_WSL1

În acest moment, vă veți afla într-o instanță Ubuntu WSL1, dar veți fi root, deoarece WSL nu își „amintește” numele de utilizator implicit pentru --import'd cazuri. Urmați „Metoda 1” din acest raspuns pentru a seta numele de utilizator implicit.

În acest moment, aveți două instanțe WSL Ubuntu, una pentru WSL1 (Ubuntu_WSL1) și altul pentru WSL2 (probabil Ubuntu sau poate Ubuntu-20.04). Dacă utilizați Windows Terminal, acesta le va detecta pe ambele și va crea profiluri pentru lansare. Sau puteți lansa oricând manual folosind wsl ~ -d <distroname>.

O altă opțiune ar fi cea simplă convertit la WSL1 și să-l folosească exclusiv. Pașii pentru aceasta sunt similari cu copierea acestuia, deoarece probabil că doriți totuși să faceți o copie de rezervă. Din nou, ieșiți din instanță și din PowerShell:

# Ajustați calea de bază după cum doriți
$WSL_ROOT = "$env:USERPROFILE\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p „$WSL_ROOT\imagini”
cd $WSL_ROOT
wsl -l -v
# Confirmați numele distribuției - Dacă nu este „Ubuntu”, ajustați următoarea linie după cum este necesar
wsl --export Ubuntu „$WSL_ROOT\images\$WSL_IMAGE_NAME”
wsl --set-version Ubuntu 1

Nu este nevoie să resetați numele de utilizator implicit în acest caz.


WSL2

WSL2 începe să devină mult mai complicat. Deși există un link în comentarii către un document despre cum să o faceți, vă voi indica problema originală Github și comentariu asta chiar a pus oamenii în această direcție.

Există două probleme reale care trebuie rezolvate pentru ca acest lucru să funcționeze în WSL2:

  • În primul rând, rețeaua WSL2 este o rețea virtuală (de fapt o vNIC Hyper-V). Nu se află în „rețeaua de birouri”, așa cum menționați în întrebarea dvs. Mai întâi trebuie să aveți o modalitate de a spune gazdei Windows să direcționeze pachetele către rețeaua virtuală WSL2 pentru acel port.

  • Această redirecționare este complicată de faptul că adresa rețelei virtuale WSL2 se modifică la fiecare repornire (sau wsl --oprire). Asta înseamnă (cel puțin cu metoda documentată în comentarii și acea problemă Github) că trebuie să repeți procesul de:

    • Găsirea adresei IP WSL2
    • Stergerea vechilor reguli de firewall
    • Ștergerea vechilor reguli de redirecționare
    • Crearea de noi reguli de firewall
    • Crearea de noi reguli de redirecționare

... de fiecare dată când reporniți. Ce durere, nu?!

Așa că o să propun ceea ce cred că este o metodă mai ușoară. Puteți încă să reveniți la cealaltă metodă dacă doriți. Aceasta are unele puțin configurație complicată, dar aproape toate trebuie făcute o singura data.

Această metodă utilizează SSH pentru a furniza redirecționarea portului. Deoarece aceasta este inițializată de la capătul WSL2, are câteva avantaje:

  • În primul rând, se poate face ca parte a aceluiași pas atunci când rulați aplicația (server web). Nu menționați arhitectura/limbajul aplicației, dar voi presupune că unul dintre cele mai comune -- Node. Dacă acesta este cazul, probabil că îl puteți include chiar și în dvs rulare npm scenariu. Există aproape sigur o tehnică care va funcționa pentru orice arhitectură.

  • Cel mai important, nu are nevoie de adresa IP a WSL2. Acest lucru evită necesitatea de a face 4 dintre acești pași de mai sus de fiecare dată când reporniți.

Deci, iată-ne. În primul rând, există configurația „o singură dată”:

  • Activați serverul Windows OpenSSH. Puteți urmări Microsoft instrucțiuni, dar voi rezuma aici. Începeți prin a deschide un prompt PowerShell ca administrator, apoi:

    Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    Set-Service -Name sshd -StartupType 'Automatic'
    

    Acest lucru ar trebui să creeze automat regulile de redirecționare SSH. Din nou, vezi doc dacă întâmpinați vreo problemă.

  • Editați | × C:\ProgramData\ssh\sshd_config și asigură-te că GatewayPorts da nu este comentat. Cred că este dezactivat implicit.

  • Înapoi în PowerShell de administrator, rulați:

    Start-Service sshd
    
  • Nu menționați numărul portului pe care rulează aplicația dvs. web, așa că voi alege 8080 de dragul acestor exemple. Ajustați după cum este necesar. Încă în admin PowerShell, rulați:

    New-NetFirewallRule -DisplayName 8080 -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow -Profil Privat
    

    Acest:

    • Permite traficul TCP de intrare
    • Pe portul 8080
    • De pe dispozitivele din rețeaua privată

    Dacă rețeaua dvs. este setată Public, aruncați -Profil Privat

  • Ieșiți din PowerShell de administrator

Cu asta din drum, totul este la locul lui. Pentru a începe redirecționarea în acest moment, executați următoarele din Ubuntu/WSL2:

ssh -f -N -R 8080:localhost:8080 „$(hostname).local”

Foloseste-ti Windows nume de utilizator și parolă.

În acest moment, ar trebui să aveți acces la aplicația dvs. web de pe alt computer (sau telefon, sau orice altceva) din aceeași rețea de birou.

Explicaţie:

  • Se conectează din Ubuntu/WSL2
  • La serverul OpenSSH pe care l-am configurat
  • Folosind „$(nume gazdă).local” care (ar trebui) să găsească întotdeauna numele DNS corect prin mDNS (explicația în acest raspuns.
  • Nu alocă un terminal (-N) și rulează în fundal (-f) după solicitarea acreditărilor de conectare
  • Îi spune gazdei SSH la distanță (Windows) să redirecționeze traficul primit pe portul său 8080 către portul local (WSL2) 8080.
  • Pentru că noi am precizat GatewayPorts da în configurația serverului, aceasta înseamnă că va extinde acea redirecționare către alte gazdele din rețea.
Puncte:0
drapel cn

In timp ce Răspuns furnizat de @NotTheDr01ds este corect și foarte informativ, iată o altă soluție care utilizează PowerShell alimentat de Bash pe Ubuntu pe WSL :)

Adăugați următoarea funcție în partea de jos a paginii dvs ~/.bashrc fişier. Dacă aveți mai multe instanțe WSL, puteți face asta pentru fiecare dintre ele.

Modificați valorile pentru wsl_port și win_port conform nevoilor tale. Modificați opțional valoarea lui win_ip dacă doriți să ascultați la o anumită interfață de rețea în loc de toate interfețele disponibile, care este sensul 0.0.0.0.

wsl_win_proxy() {
    wsl_ip="$(rută ip | grep -oP '^.*src \K[0-9\.]+')"
    wsl_port="8080"

    win_ip="0.0.0.0"
    win_port="8080"

    rule_name="TCP de intrare ${win_port}"
    win_get_fw_rule_cmd="Get-NetFirewallRule | Unde { \$_.DisplayName -eq '${rule_name}' }"
    win_new_fw_rule_cmd="New-NetFirewallRule -DisplayName '${rule_name}' -Direction Inbound -Action Allow -Protocol TCP -LocalPort ${win_port}"

    dacă ! netsh.exe portproxy interfață arată tot | grep -q -P "${win_ip}\s+${win_port}\s+${wsl_ip}\s+${wsl_port}"
    atunci
        powershell.exe Start-Process -Verb runAs -FilePath „netsh.exe” \
            -ArgumentList "interfață","portproxy","add","v4tov4",\
                    "listenport=$win_port","listenaddress=$win_ip",\
                    "connectport=$wsl_port","connectaddress=$wsl_ip"

        dacă [[ $? -eq 0 ]]
        atunci
            echo „Este creat proxy-ul portului „${win_ip}:${win_port} > ${wsl_ip}:${wsl_port}”.
        altfel
            echo „Proxy portul „${win_ip}:${win_port} > ${wsl_ip}:${wsl_port}” a eșuat.”
        fi

        dacă ! powershell.exe ${win_get_fw_rule_cmd} | grep -q „$nume_regulă”
        atunci
            echo „Deschide PowerShell ca administrator și creează următoarea regulă de firewall:”
            echo -e '\033[1;33m'"$win_new_fw_rule_cmd"'\033[0m'
        fi
    fi
}
wsl_win_proxy

Acum, când deschideți WSL, funcția se va crea proxy de port automat. Comanda PowerShell utilizată trebuie executată cu privilegii de administrator, așa că Windows vă va cere conformarea. Dacă proxy de port deja exista nimic nu se va intampla.

A doua parte a funcției va testa dacă este adecvată regula firewall. Testul va fi efectuat de DisplayName al regulii, astfel încât să puteți elimina regulile create anterior pentru portul țintă pentru a permite funcționarea corectă a funcției. Dacă regula firewall nu există deja nimic nu se va întâmpla, altfel vi se va instrui cum să îl creați. Vi se va solicita acea acțiune numai atunci când este nou proxy de port este creat.

Opțional, puteți elimina sau comenta linia wsl_win_proxy care invocă funcția și o pornește ca comandă shell atunci când aveți nevoie de asta.


Următoarele comenzi PowerShell vă vor ajuta să gestionați cele create proxy porturi.

netsh portproxy interfață arată tot
resetare portproxy interfață netsh

Referinte:

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.