Điểm:2

Truy cập ứng dụng của WSL2 Ubuntu trên mạng của máy được lưu trữ

lá cờ tr

Tôi đang chạy một ứng dụng trong WSL2 có bản phân phối là Ubuntu 20.04. Tôi có thể truy cập ứng dụng trong trình duyệt windows bằng IP của Ubuntu.

Bây giờ, tôi muốn truy cập ứng dụng này trên mạng của mình (ý tôi là trong mạng văn phòng của tôi trên máy khác)

Tôi hiểu rằng IP của Ubuntu chỉ khả dụng cho máy chủ. Làm thế nào tôi có thể làm cho nó có sẵn cho những người khác trên mạng của tôi?

Làm thế nào chúng ta có thể làm điều này? Hãy giúp tôi.

lá cờ hr
WSL hay WSL2? quy trình có vẻ khác - xem ví dụ [Chuyển tiếp cổng WSL](https://dev.to/vishnu12/wsl-port-forwarding-2e22)
lá cờ tr
WSL2 của nó, nhưng ví dụ trên là dành cho WSL. Hãy sửa cho tôi nếu sai
lá cờ hr
Tôi *nghĩ* đó là trường hợp bạn không cần phải làm bất cứ điều gì đối với WSL (nó sẽ "chỉ hoạt động"), trong khi đối với WSL2, bạn cần thiết lập chuyển tiếp cổng như được mô tả trong bài viết được liên kết. Nhưng hãy xem bạn nhận được câu trả lời nào.
NotTheDr01ds avatar
lá cờ vn
@steeldriver Bạn nói đúng. Tôi sẽ thêm nhiều chi tiết hơn trong câu trả lời của mình. Đã lâu rồi tôi không làm việc này, nhưng tôi có một vài ý tưởng mới để thử kể từ lần trước và tôi sẽ đề xuất nếu chúng hiệu quả. Chuyển tiếp cổng sẽ hoạt động, nhưng bài đăng đó dường như quá phức tạp. Tôi hy vọng tôi có thể đề xuất một cái gì đó hiệu quả hơn, nhưng chúng ta sẽ thấy.
lá cờ hr
@NotTheDr01ds tuyệt vời - rất mong được đọc!
NotTheDr01ds avatar
lá cờ vn
Và @Raushan, để rõ ràng, tài liệu mà Steeldriver liên kết là dành cho WSL2. Như ghi chú ở trên cùng, WSL1 không cần bất cứ thứ gì như vậy. Nhưng một lần nữa, đừng làm theo tài liệu đó. Nó sẽ hoạt động, nhưng tôi có một giải pháp (hiện tôi đã xác nhận) mà tôi đang viết ra như một câu trả lời mà tôi tin là dễ dàng hơn.
Điểm:3
lá cờ vn

câu trả lời ngắn cho WSL1:

Định cấu hình quy tắc tường lửa của bạn một lần và mọi thứ sẽ "hoạt động". Đây là phương pháp dễ nhất.

câu trả lời ngắn cho WSL2:

Khi bạn đã cấu hình mọi thứ đúng cách, bạn có thể bắt đầu chuyển tiếp cổng rất dễ dàng bằng một lệnh duy nhất từ ​​Ubuntu/WSL2:

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

Chi tiết về cách cấu hình ở bên dưới. Nó không nhất thiết phải dễ dàng, nhưng tất cả chỉ là thiết lập một lần.


(Nhiều) chi tiết hơn:

Như Steeldriver đã lưu ý trong các nhận xét, WSL1 và WSL2 hoạt động khác nhau ở đây.

Lưu ý bên lề chỉ để làm rõ thuật ngữ (vì nó hơi khác trong các nhận xét): "WSL" đề cập đến chính hệ thống con kiểm soát cả hai phiên bản -- WSL1 và WSL2.

Lưu ý bên lề 2. Xin đừng để độ dài của bài đăng này làm bạn sợ hãi. Tôi chỉ rất chi tiết. Cân nhắc việc vấn đề Github liên quan lên đến (hiện tại) 536 bình luận, tôi nghĩ rằng tôi khá ngắn gọn khi so sánh ;-).


WSL1

WSL1 chắc chắn là trường hợp sử dụng dễ dàng hơn. Vì nó là một "lớp dịch thuật" giữa các tòa nhà chọc trời của Linux và nhân Windows, nên nó thực sự sử dụng (các) giao diện mạng Windows "thực". Vì lý do này, bạn có thể kết nối trực tiếp từ một thiết bị khác trên mạng với một cổng trong WSL1.

bạn có khả năng làm Tuy nhiên, vẫn cần một quy tắc tường lửa. Tôi sẽ trình bày điều đó trong câu trả lời WSL2, vì nó phổ biến cho cả hai. xem Quy tắc tường lửa mạng mới lệnh trong phần WSL2. Chỉ cần chạy một lệnh đó (một lần) cho quy tắc tường lửa.

Tuy nhiên, nếu ứng dụng web của bạn không yêu cầu WSL2 (và hầu hết không phải), việc chạy nó từ phiên bản WSL1 thường dễ dàng hơn nhiều (hoặc ít nhất là nó đã từng như vậy). Đó là những gì hầu hết mọi người kết thúc làm. Mặt khác, với phương pháp WSL2/SSH mới (ít nhất là đối với tôi) mà tôi đề xuất bên dưới, việc thực hiện điều này trong WSL2 gần như không khó khăn như trước đây. Tôi sẽ để bạn chọn con đường nào. Tại thời điểm này, tôi coi một trong hai đều có giá trị như nhau.

Nếu bạn chọn sử dụng WSL1, tôi khuyên bạn nên giữ hai phiên bản Ubuntu -- Một với WSL1 và một với WSL2. Đó là những gì tôi làm.

Để sao chép phiên bản WSL2 hiện có của bạn sang WSL1 mới, hãy thoát khỏi phiên bản hiện có và từ PowerShell:

# Điều chỉnh đường dẫn cơ sở như mong muốn
$WSL_ROOT = "$env:USERPROFILE\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p "$WSL_ROOT\hình ảnh"
mkdir -p "$WSL_ROOT\instance\Ubuntu_WSL1"
cd $WSL_ROOT
wsl -l -v
# Xác nhận tên phân phối - Nếu không phải là "Ubuntu", hãy điều chỉnh dòng sau nếu cần
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

Tại thời điểm này, bạn sẽ ở phiên bản Ubuntu WSL1, nhưng bạn sẽ là người chủ, vì WSL không "nhớ" tên người dùng mặc định cho --nhập khẩu'd trường hợp. Làm theo "Phương pháp 1" của tôi từ câu trả lời này để đặt tên người dùng mặc định của bạn.

Tại thời điểm này, bạn có hai phiên bản WSL Ubuntu, một phiên bản dành cho WSL1 (Ubuntu_WSL1) và một cái khác cho WSL2 (có thể Ubuntu hoặc có lẽ Ubuntu-20.04). Nếu bạn đang sử dụng Windows Terminal, nó sẽ phát hiện cả hai và tạo hồ sơ để khởi chạy. Hoặc bạn luôn có thể khởi chạy thủ công bằng cách sử dụng wsl ~ -d <tên distro>.

Một lựa chọn khác là đơn giản đổi sang WSL1 và sử dụng riêng nó. Các bước cho việc này tương tự như sao chép nó, vì có thể bạn vẫn muốn sao lưu. Một lần nữa, thoát khỏi phiên bản và từ PowerShell:

# Điều chỉnh đường dẫn cơ sở như mong muốn
$WSL_ROOT = "$env:USERPROFILE\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p "$WSL_ROOT\hình ảnh"
cd $WSL_ROOT
wsl -l -v
# Xác nhận tên phân phối - Nếu không phải là "Ubuntu", hãy điều chỉnh dòng sau nếu cần
wsl --export Ubuntu "$WSL_ROOT\images\$WSL_IMAGE_NAME"
wsl --set-phiên bản Ubuntu 1

Không cần thiết lập lại tên người dùng mặc định trong trường hợp này.


WSL2

WSL2 bắt đầu trở nên phức tạp hơn rất nhiều. Mặc dù có một liên kết trong các nhận xét đến một tài liệu về cách thực hiện, nhưng tôi sẽ chỉ cho bạn vấn đề và bình luận Github ban đầu đã thực sự bắt đầu mọi người theo hướng này.

Có hai vấn đề thực sự phải được giải quyết để tính năng này hoạt động trong WSL2:

  • Đầu tiên, mạng WSL2 là một mạng ảo (thực ra là Hyper-V vNIC). Nó không nằm trên "mạng văn phòng" của bạn, như bạn lưu ý trong câu hỏi của mình. Trước tiên, bạn cần có một số cách để yêu cầu máy chủ lưu trữ Windows định tuyến các gói đến mạng ảo WSL2 của bạn cho cổng đó.

  • Việc chuyển tiếp đó rất phức tạp bởi thực tế là địa chỉ mạng WSL2 ảo thay đổi sau mỗi lần khởi động lại (hoặc wsl --shutdown). Điều đó có nghĩa là (ít nhất là với phương pháp được ghi lại trong các nhận xét và vấn đề Github đó) mà bạn phải lặp lại quy trình:

    • Tìm địa chỉ IP WSL2
    • Xóa các quy tắc tường lửa cũ
    • Xóa các quy tắc chuyển tiếp cũ
    • Tạo quy tắc tường lửa mới
    • Tạo quy tắc chuyển tiếp mới

... mỗi khi bạn khởi động lại. Thật là một nỗi đau, phải không?!

Vì vậy, tôi sẽ đề xuất những gì tôi tin là một phương pháp dễ dàng hơn. Bạn vẫn có thể quay lại phương pháp khác nếu muốn. Điều này có một số khinh bỉ thiết lập phức tạp, nhưng hầu như tất cả chỉ phải được thực hiện Một lần.

Phương pháp này sử dụng SSH để cung cấp cổng chuyển tiếp. Vì điều này được khởi tạo từ đầu cuối WSL2 nên nó có một số ưu điểm:

  • Đầu tiên, nó có thể được thực hiện như một phần của cùng một bước khi bạn chạy ứng dụng của mình (máy chủ web). Bạn không đề cập đến kiến ​​trúc/ngôn ngữ của ứng dụng, nhưng tôi sẽ cho rằng một trong những ngôn ngữ phổ biến nhất -- Node. Nếu đúng như vậy, bạn thậm chí có thể đưa nó vào chạy npm kịch bản. Gần như chắc chắn có một kỹ thuật phù hợp với mọi kiến ​​trúc.

  • Quan trọng nhất, nó không cần địa chỉ IP của WSL2. Điều này tránh phải thực hiện 4 trong số các bước trên mỗi khi bạn khởi động lại.

Vì vậy, ở đây chúng tôi đi. Đầu tiên, có thiết lập "một lần":

  • Kích hoạt máy chủ Windows OpenSSH. Bạn có thể theo dõi Microsoft hướng dẫn, nhưng tôi sẽ tóm tắt ở đây. Bắt đầu bằng cách mở lời nhắc PowerShell với tư cách Quản trị viên, sau đó:

    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 'Tự động'
    

    Điều này sẽ tự động tạo quy tắc chuyển tiếp SSH. Một lần nữa, hãy xem tài liệu nếu bạn gặp bất kỳ rắc rối nào.

  • Chỉnh sửa C:\ProgramData\ssh\sshd_config và đảm bảo rằng GatewayPorts có không được bình luận ra ngoài. Tôi tin rằng nó bị tắt theo mặc định.

  • Quay lại PowerShell quản trị của bạn, chạy:

    Bắt đầu dịch vụ sshd
    
  • Bạn không đề cập đến số cổng mà ứng dụng web của bạn chạy dưới dạng đó, vì vậy tôi sẽ chọn 8080 vì lợi ích của những ví dụ này. Điều chỉnh khi cần thiết. Vẫn trong quản trị viên PowerShell, hãy chạy:

    Mới-NetFirewallRule -DisplayName 8080 -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow -Profile Private
    

    Cái này:

    • Cho phép lưu lượng truy cập TCP đến
    • Trên cổng 8080
    • Từ các thiết bị trên mạng riêng

    Nếu mạng của bạn được đặt Công cộng, thả -Hồ sơ cá nhân

  • Thoát quản trị viên PowerShell của bạn

Với điều đó ra khỏi con đường, mọi thứ ở vị trí. Để bắt đầu chuyển tiếp tại thời điểm này, hãy thực hiện thao tác sau từ Ubuntu/WSL2:

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

Sử dụng của bạn các cửa sổ tên người dùng và mật khẩu.

Tại thời điểm này, bạn sẽ có quyền truy cập vào ứng dụng web của mình từ một máy tính khác (hoặc điện thoại hoặc bất kỳ thứ gì) trên cùng một mạng văn phòng.

Giải trình:

  • kết nối từ Ubuntu/WSL2
  • Đến Máy chủ OpenSSH mà chúng tôi đã thiết lập
  • Sử dụng "$(tên máy chủ).local" cái nào (nên) luôn tìm đúng tên DNS qua mDNS (giải thích trong câu trả lời này.
  • Nó không phân bổ một thiết bị đầu cuối (-N) và chạy trong nền (-f) sau khi yêu cầu thông tin đăng nhập
  • Nó yêu cầu máy chủ SSH từ xa (Windows) chuyển tiếp lưu lượng truy cập nhận được trên cổng 8080 của nó sang cổng 8080 cục bộ (WSL2).
  • Bởi vì chúng tôi đã chỉ định GatewayPorts có trong cấu hình máy chủ, điều này có nghĩa là nó sẽ mở rộng quá trình chuyển tiếp đó sang khác máy chủ trên mạng là tốt.
Điểm:0
lá cờ cn

Trong khi câu trả lời cung cấp bởi @NotTheDr01ds là chính xác và rất nhiều thông tin, đây là một cách giải quyết khác sử dụng PowerShell do Bash cung cấp trên Ubuntu trên WSL :)

Thêm chức năng sau vào dưới cùng của bạn ~/.bashrc tập tin. Nếu bạn có nhiều phiên bản WSL, bạn có thể làm điều đó cho từng phiên bản.

Thay đổi các giá trị cho wsl_portwin_port theo nhu cầu của bạn. Tùy ý thay đổi giá trị của win_ip nếu bạn muốn nghe ở giao diện mạng nhất định thay vì tất cả các giao diện có sẵn, đó là ý nghĩa của 0.0.0.0.

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

    win_ip="0.0.0.0"
    win_port="8080"

    rule_name="TCP gửi đến ${win_port}"
    win_get_fw_rule_cmd="Get-NetFirewallRule | Ở đâu { \$_.DisplayName -eq '${rule_name}' }"
    win_new_fw_rule_cmd="New-NetFirewallRule -DisplayName '${rule_name}' -Direction Inbound -Action Allow -Protocol TCP -LocalPort ${win_port}"

    nếu ! netsh.exe giao diện portproxy hiển thị tất cả | grep -q -P "${win_ip}\s+${win_port}\s+${wsl_ip}\s+${wsl_port}"
    sau đó
        powershell.exe Start-Process -Verb runAs -FilePath "netsh.exe" \
            -ArgumentList "giao diện","portproxy","thêm","v4tov4",\
                    "listenport=$win_port","listenaddress=$win_ip",\
                    "connectport=$wsl_port","connectaddress=$wsl_ip"

        nếu [[ $? -eq 0 ]]
        sau đó
            echo "Proxy cổng '${win_ip}:${win_port} > ${wsl_ip}:${wsl_port}' đã được tạo."
        khác
            echo "Proxy cổng '${win_ip}:${win_port} > ${wsl_ip}:${wsl_port}' không thành công."
        fi

        nếu ! powershell.exe ${win_get_fw_rule_cmd} | grep -q "$rule_name"
        sau đó
            echo "Mở PowerShell với tư cách Quản trị viên và tạo quy tắc tường lửa sau:"
            echo -e '\033[1;33m'"$win_new_fw_rule_cmd"'\033[0m'
        fi
    fi
}
wsl_win_proxy

Bây giờ khi bạn mở WSL, chức năng sẽ tạo cổng proxy tự động. Lệnh của PowerShell đã sử dụng phải được thực thi với các đặc quyền của quản trị viên, vì vậy Windows sẽ yêu cầu bạn cung cấp cấu hình. Nếu cổng proxy đã tồn tại sẽ không có gì xảy ra.

Phần thứ hai của chức năng sẽ kiểm tra sự phù hợp quy tắc tường lửa. Kiểm tra sẽ được thực hiện bởi DisplayName của quy tắc, vì vậy bạn có thể xóa các quy tắc đã tạo trước đó cho cổng đích để cho phép chức năng hoạt động bình thường. Nếu quy tắc tường lửa đã tồn tại sẽ không có gì xảy ra, nếu không bạn sẽ được hướng dẫn cách tạo nó. Bạn sẽ được nhắc thực hiện hành động đó chỉ khi có một cổng proxy được tạo ra.

Theo tùy chọn, bạn có thể xóa hoặc nhận xét dòng wsl_win_proxy gọi hàm này và khởi động nó dưới dạng lệnh trình bao khi bạn cần.


Các lệnh sau của PowerShell sẽ giúp bạn quản lý tệp đã tạo cổng proxy.

portproxy giao diện netsh hiển thị tất cả
thiết lập lại portproxy giao diện netsh

Người giới thiệu:

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.