คำตอบสั้น ๆ สำหรับ WSL1:
กำหนดค่ากฎไฟร์วอลล์ของคุณเพียงครั้งเดียว และทุกอย่างควร "ใช้งานได้" นี่เป็นวิธีที่ง่ายที่สุด
คำตอบสั้น ๆ สำหรับ WSL2:
เมื่อคุณกำหนดค่าต่างๆ อย่างถูกต้องแล้ว คุณสามารถเริ่มต้นการส่งต่อพอร์ตได้อย่างง่ายดายด้วยคำสั่งเดียวจาก Ubuntu/WSL2:
ssh -f -N -R 8080:localhost:8080 "$(ชื่อโฮสต์).local"
รายละเอียดเกี่ยวกับวิธีการกำหนดค่าอยู่ด้านล่าง ไม่จำเป็นต้องง่าย แต่ทั้งหมดนี้เป็นการตั้งค่าเพียงครั้งเดียว
(มาก) รายละเอียดเพิ่มเติม:
ตามที่ Steeldriver ระบุไว้ในความคิดเห็น WSL1 และ WSL2 ทำงานแตกต่างกันที่นี่
หมายเหตุด้านข้างเพียงเพื่อชี้แจงคำศัพท์ (เนื่องจากมีความแตกต่างกันเล็กน้อยในความคิดเห็น): "WSL" หมายถึงระบบย่อยเองซึ่งควบคุมทั้งสองเวอร์ชัน - WSL1 และ WSL2
หมายเหตุด้านข้าง 2 โปรดอย่าปล่อยให้ความยาวของโพสต์นี้ทำให้คุณตกใจ ฉันแค่ มาก รายละเอียด พิจารณาจาก ปัญหา Github ที่เกี่ยวข้อง มีมากถึง (ปัจจุบัน) 536 ความคิดเห็น ฉันคิดว่าฉันค่อนข้างรัดกุมเมื่อเปรียบเทียบ ;-)
WSL1
WSL1 เป็นกรณีการใช้งานที่ง่ายกว่าอย่างแน่นอน เนื่องจากเป็น "เลเยอร์การแปล" ระหว่าง Linux syscalls และเคอร์เนลของ Windows จึงใช้อินเทอร์เฟซเครือข่าย Windows "ของจริง" ด้วยเหตุนี้ คุณจึงสามารถเชื่อมต่อโดยตรงจากอุปกรณ์อื่นบนเครือข่ายไปยังพอร์ตใน WSL1
คุณน่าจะ ทำ ยังคงต้องการกฎไฟร์วอลล์อย่างไรก็ตาม ฉันจะครอบคลุมสิ่งนั้นในคำตอบ WSL2 เนื่องจากเป็นเรื่องปกติสำหรับทั้งสองอย่าง ดู ใหม่ NetFirewallRule
คำสั่งในส่วน WSL2 เพียงเรียกใช้คำสั่งเดียว (ครั้งเดียว) สำหรับกฎไฟร์วอลล์
อย่างไรก็ตาม หากเว็บแอปของคุณไม่ต้องการ WSL2 (และส่วนใหญ่ต้องการ ไม่) โดยปกติแล้วการเรียกใช้จากอินสแตนซ์ WSL1 จะง่ายกว่ามาก (หรืออย่างน้อยก็เคยเป็น) นั่นคือสิ่งที่คนส่วนใหญ่จบลงด้วยการทำ ในทางกลับกัน ด้วยวิธี WSL2/SSH ใหม่ (อย่างน้อยสำหรับฉัน) ที่ฉันเสนอด้านล่าง มันไม่เจ็บปวดเท่าที่เคยทำใน WSL2 ผมจะปล่อยให้คุณเลือกทางไหน ณ จุดนี้ฉันคิดว่าทั้งสองจะใช้ได้เท่าเทียมกัน
หากคุณเลือกที่จะใช้ WSL1 ฉันขอแนะนำให้เก็บอินสแตนซ์ Ubuntu สองอินสแตนซ์ไว้ -- หนึ่งมี WSL1 และอีกอันมี WSL2 นั่นคือสิ่งที่ฉันทำ.
หากต้องการคัดลอกอินสแตนซ์ WSL2 ที่มีอยู่ของคุณไปยัง WSL1 ใหม่ ให้ออกจากอินสแตนซ์ที่มีอยู่และจาก PowerShell:
#ปรับเส้นทางฐานได้ตามต้องการ
$WSL_ROOT = "$env:USERPROFILE\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p "$WSL_ROOT\images"
mkdir -p "$WSL_ROOT\อินสแตนซ์\Ubuntu_WSL1"
ซีดี $WSL_ROOT
wsl -l -v
# ยืนยันชื่อการแจกจ่าย - หากไม่ใช่ "Ubuntu" ให้ปรับบรรทัดต่อไปนี้ตามต้องการ
wsl --export Ubuntu "$WSL_ROOT\images\$WSL_IMAGE_NAME"
wsl --import Ubuntu_WSL1 .\instances\Ubuntu_WSL1\ .\images\$WSL_IMAGE_NAME --version 1
wsl ~ -d Ubuntu_WSL1
ณ จุดนี้ คุณจะอยู่ในอินสแตนซ์ของ Ubuntu WSL1 แต่คุณจะถูกรูท เนื่องจาก WSL ไม่ "จำ" ชื่อผู้ใช้เริ่มต้นสำหรับ --นำเข้า
อินสแตนซ์ ทำตาม "วิธีที่ 1" ของฉัน จากคำตอบนี้ เพื่อตั้งชื่อผู้ใช้เริ่มต้นของคุณ
ณ จุดนี้ คุณมีอินสแตนซ์ WSL Ubuntu สองอินสแตนซ์ หนึ่งอินสแตนซ์สำหรับ WSL1 (Ubuntu_WSL1
) และอีกอันสำหรับ WSL2 (น่าจะเป็น อูบุนตู
หรือบางที อูบุนตู-20.04
). หากคุณใช้ Windows Terminal ระบบจะตรวจจับทั้งคู่และสร้างโปรไฟล์สำหรับการเปิดใช้งาน หรือคุณสามารถเปิดใช้งานด้วยตนเองได้ตลอดเวลา wsl ~ -d <ดิสโทรเนม>
.
อีกทางเลือกหนึ่งคือการง่าย แปลง เป็น WSL1 และใช้เฉพาะ ขั้นตอนนี้คล้ายกับการคัดลอก เนื่องจากคุณยังคงต้องการสำรองข้อมูลอยู่ ออกจากอินสแตนซ์และจาก PowerShell อีกครั้ง:
#ปรับเส้นทางฐานได้ตามต้องการ
$WSL_ROOT = "$env:USERPROFILE\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p "$WSL_ROOT\images"
ซีดี $WSL_ROOT
wsl -l -v
# ยืนยันชื่อการแจกจ่าย - หากไม่ใช่ "Ubuntu" ให้ปรับบรรทัดต่อไปนี้ตามต้องการ
wsl --export Ubuntu "$WSL_ROOT\images\$WSL_IMAGE_NAME"
wsl --set-version อูบุนตู 1
ไม่จำเป็นต้องรีเซ็ตชื่อผู้ใช้เริ่มต้นในกรณีนี้
WSL2
WSL2 เริ่มซับซ้อนขึ้นมาก แม้ว่าจะมีลิงก์ในความคิดเห็นไปยังเอกสารเกี่ยวกับวิธีการทำ แต่เราจะชี้ให้คุณไปที่ ปัญหา Github ดั้งเดิมและความคิดเห็น ที่เริ่มคนมาแนวนี้จริงๆ
มีสองปัญหาจริงที่ต้องแก้ไขเพื่อให้สิ่งนี้ทำงานใน WSL2:
ประการแรก เครือข่าย WSL2 เป็นเครือข่ายเสมือน (จริง ๆ แล้วคือ Hyper-V vNIC) มันไม่ได้อยู่ใน "เครือข่ายสำนักงาน" ของคุณ ตามที่คุณระบุในคำถามของคุณ ก่อนอื่นคุณต้องมีวิธีบอกโฮสต์ Windows ให้กำหนดเส้นทางแพ็กเก็ตไปยังเครือข่ายเสมือน WSL2 ของคุณสำหรับพอร์ตนั้น
การส่งต่อนั้นซับซ้อนเนื่องจากที่อยู่เครือข่าย WSL2 เสมือนเปลี่ยนไปทุกครั้งที่รีบูต (หรือ wsl -- ปิดเครื่อง
). นั่นหมายความว่า (อย่างน้อยด้วยวิธีที่บันทึกไว้ในความคิดเห็นและปัญหา Github) ที่คุณต้องทำซ้ำขั้นตอน:
- ค้นหาที่อยู่ IP WSL2
- การลบกฎไฟร์วอลล์เก่า
- กำลังลบกฎการส่งต่อเก่า
- การสร้างกฎไฟร์วอลล์ใหม่
- การสร้างกฎการส่งต่อใหม่
... ทุกครั้งที่คุณรีบูต เจ็บอะไรนักหนาวะ!
ดังนั้นฉันจะเสนอสิ่งที่ฉันเชื่อว่าเป็นวิธีที่ง่ายกว่า คุณยังสามารถถอยกลับไปใช้วิธีอื่นได้หากต้องการ นี้มีบางอย่าง เล็กน้อย การตั้งค่าที่ซับซ้อน แต่ต้องทำเกือบทั้งหมดเท่านั้น ครั้งหนึ่ง.
วิธีนี้ใช้ SSH เพื่อให้การส่งต่อพอร์ต เนื่องจากสิ่งนี้เริ่มต้นจาก WSL2-end จึงมีข้อดีหลายประการ:
ประการแรก สามารถทำได้โดยเป็นส่วนหนึ่งของขั้นตอนเดียวกันเมื่อคุณเรียกใช้แอปพลิเคชัน (เว็บเซิร์ฟเวอร์) คุณไม่ได้พูดถึงสถาปัตยกรรม/ภาษาของแอป แต่ฉันจะถือว่าหนึ่งในนั้นใช้กันมากที่สุด -- Node หากเป็นกรณีนี้ คุณอาจรวมไว้ในของคุณด้วยซ้ำ วิ่ง npm
สคริปต์ เกือบจะมีเทคนิคที่จะใช้ได้กับสถาปัตยกรรมใดๆ ก็ตาม
สิ่งสำคัญที่สุดคือไม่ต้องการที่อยู่ IP ของ WSL2 เพื่อหลีกเลี่ยงความจำเป็นในการทำ 4 ขั้นตอนข้างต้นทุกครั้งที่คุณรีบูต
เอาล่ะ ไปเลย ประการแรก มีการตั้งค่า "ครั้งเดียว":
เปิดใช้งานเซิร์ฟเวอร์ Windows OpenSSH คุณสามารถปฏิบัติตาม Microsoft คำแนะนำแต่ฉันจะสรุปที่นี่ เริ่มต้นด้วยการเปิดพรอมต์ PowerShell ในฐานะผู้ดูแลระบบ จากนั้น:
เพิ่ม WindowsCapability - ออนไลน์ - ชื่อ OpenSSH.Client~~~~0.0.1.0
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
ตั้งค่าบริการ - ชื่อ sshd -StartupType 'อัตโนมัติ'
สิ่งนี้ควรสร้างกฎการส่งต่อ SSH โดยอัตโนมัติ อีกครั้งดูที่ เอกสาร หากคุณประสบปัญหาใด ๆ
แก้ไข C:\ProgramData\ssh\sshd_config
และตรวจสอบให้แน่ใจว่า GatewayPort ใช่
ไม่ได้แสดงความคิดเห็น ฉันเชื่อว่ามันถูกปิดใช้งานโดยค่าเริ่มต้น
ย้อนกลับไปใน PowerShell ผู้ดูแลระบบของคุณ ให้เรียกใช้:
เริ่มบริการ sshd
คุณไม่ได้ระบุหมายเลขพอร์ตที่เว็บแอปของคุณเรียกใช้ ดังนั้นฉันจะเลือก 8080
สำหรับตัวอย่างเหล่านี้ ปรับตามต้องการ ยังอยู่ในผู้ดูแลระบบ PowerShell ให้เรียกใช้:
New-NetFirewallRule -DisplayName 8080 -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow -Profile ส่วนตัว
นี้:
- อนุญาตการรับส่งข้อมูล TCP ขาเข้า
- บนพอร์ต 8080
- จากอุปกรณ์บนเครือข่ายส่วนตัว
หากตั้งค่าเครือข่ายของคุณ สาธารณะ
, วาง - โปรไฟล์ส่วนตัว
ออกจากผู้ดูแลระบบ PowerShell
เมื่อหลีกทางให้ ทุกอย่างก็เข้าที่ ในการเริ่มต้นการส่งต่อ ณ จุดนี้ ให้ดำเนินการต่อไปนี้จาก Ubuntu/WSL2:
ssh -f -N -R 8080:localhost:8080 "$(ชื่อโฮสต์).local"
ใช้ของคุณ หน้าต่าง ชื่อผู้ใช้และรหัสผ่าน
ณ จุดนี้ คุณควรเข้าถึงเว็บแอปของคุณจากคอมพิวเตอร์เครื่องอื่น (หรือโทรศัพท์ หรืออะไรก็ตาม) บนเครือข่ายสำนักงานเดียวกัน
คำอธิบาย:
- เชื่อมต่อ จาก อูบุนตู/WSL2
- ถึง OpenSSH Server ที่เราตั้งค่าไว้
- ใช้
"$(ชื่อโฮสต์).local"
ซึ่ง (ควร) ค้นหาชื่อ DNS ที่ถูกต้องเสมอผ่าน mDNS (คำอธิบายใน คำตอบนี้.
- ไม่ได้จัดสรรเทอร์มินัล (
-น
) และทำงานในพื้นหลัง (-ฉ
) หลังจากร้องขอข้อมูลรับรองการเข้าสู่ระบบ
- มันบอกโฮสต์ SSH ระยะไกล (Windows) ให้ส่งต่อการรับส่งข้อมูลที่ได้รับบนพอร์ต 8080 ไปยังพอร์ตท้องถิ่น (WSL2) 8080
- เพราะเราระบุ
GatewayPort ใช่
ในการกำหนดค่าเซิร์ฟเวอร์ หมายความว่าจะขยายการส่งต่อไปยัง อื่นๆ โฮสต์บนเครือข่ายด้วย