2

開發與部署網站時需注意不要使用到 ERR_UNSAFE_PORT 不安全的埠號

 1 year ago
source link: https://blog.miniasp.com/post/2022/05/02/Dont-use-ERR_UNSAFE_PORT-for-your-website
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我昨天在授課的時候,突然遇到 Chrome 瀏覽器無法瀏覽網站的情況(ERR_UNSAFE_PORT),我踩到一個不知道算不算罕見的地雷,在深入瞭解之後,覺得有必要寫成文章提醒大家,因為你還真的很有可能會在不久的將來遇到這個問題,看完文章才不會讓你日後鬼打牆太久,讓我們繼續看下去。

問題發生的過程

我昨天在示範如何將 ASP.NET Core 部署到 IIS 站台,我很隨意的挑選了一個吉利的數字 10080 當成網站的 HTTP 埠號,結果用 Google Chrome 開啟網頁後,竟然出現以下錯誤:

ERR_UNSAFE_PORT

由於之前並沒有遇到過這種狀況,什麼叫 ERR_UNSAFE_PORT 呢?我當下先判斷可能跟 HSTS (HTTP Strict Transport Security) (HTTP強制安全傳輸技術) 有關,但調整了一下 Chrome 的 HSTS 設定,還是連不上。狀況很詭異,我甚至一度懷疑 Google Chrome 是不是把 HTTP (Port 80) 都給封鎖了?應該不太可能吧!結果我用 curl 呼叫這個網址,發現是可以連線的,只有 Google Chrome / Microsoft Edge 連不上而已。我最後換了一個 Port,並設定 HTTPS 安全連線,然後就可以運作了,真的相當詭異!

Google Chrome 有一組黑名單的埠號清單

我今天抽空研究了一下,發現在 Chromium 的原始碼中有定義一系列被列入黑名單的埠號清單 (blocked ports):

net/base/port_util.cc - chromium/src.git - Git at Google

// The general list of blocked ports. Will be blocked unless a specific
// protocol overrides it. (Ex: ftp can use port 21)
// When adding a port to the list, consider also adding it to kAllowablePorts,
// below.
const int kRestrictedPorts[] = {
    1,      // tcpmux
    7,      // echo
    9,      // discard
    11,     // systat
    13,     // daytime
    15,     // netstat
    17,     // qotd
    19,     // chargen
    20,     // ftp data
    21,     // ftp access
    22,     // ssh
    23,     // telnet
    25,     // smtp
    37,     // time
    42,     // name
    43,     // nicname
    53,     // domain
    69,     // tftp
    77,     // priv-rjs
    79,     // finger
    87,     // ttylink
    95,     // supdup
    101,    // hostriame
    102,    // iso-tsap
    103,    // gppitnp
    104,    // acr-nema
    109,    // pop2
    110,    // pop3
    111,    // sunrpc
    113,    // auth
    115,    // sftp
    117,    // uucp-path
    119,    // nntp
    123,    // NTP
    135,    // loc-srv /epmap
    137,    // netbios
    139,    // netbios
    143,    // imap2
    161,    // snmp
    179,    // BGP
    389,    // ldap
    427,    // SLP (Also used by Apple Filing Protocol)
    465,    // smtp+ssl
    512,    // print / exec
    513,    // login
    514,    // shell
    515,    // printer
    526,    // tempo
    530,    // courier
    531,    // chat
    532,    // netnews
    540,    // uucp
    548,    // AFP (Apple Filing Protocol)
    554,    // rtsp
    556,    // remotefs
    563,    // nntp+ssl
    587,    // smtp (rfc6409)
    601,    // syslog-conn (rfc3195)
    636,    // ldap+ssl
    989,    // ftps-data
    990,    // ftps
    993,    // ldap+ssl
    995,    // pop3+ssl
    1719,   // h323gatestat
    1720,   // h323hostcall
    1723,   // pptp
    2049,   // nfs
    3659,   // apple-sasl / PasswordServer
    4045,   // lockd
    5060,   // sip
    5061,   // sips
    6000,   // X11
    6566,   // sane-port
    6665,   // Alternate IRC [Apple addition]
    6666,   // Alternate IRC [Apple addition]
    6667,   // Standard IRC [Apple addition]
    6668,   // Alternate IRC [Apple addition]
    6669,   // Alternate IRC [Apple addition]
    6697,   // IRC + TLS
    10080,  // Amanda
};

由上述清單可以得知,我授課時所用到的 10080 正好就是黑名單之一! How Lucky!!! 😄

事實上,無論你走 HTTP 或 HTTPS,只要用到這幾個 Ports,就會讓所有 Chromium-based 的瀏覽器都連不上,直接從用戶端就封鎖了連線,完全連不上! 🔥

ERR_UNSAFE_PORT

若要讓 Google Chrome 可以開放這些限制的 Ports 清單,需要在啟動 Chrome 的時候加入 --explicitly-allowed-ports=10080 這樣的啟動參數。例如:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory=Default --explicitly-allowed-ports=10080

詳情請見 How to fix ERR_UNSAFE_PORT error on Chrome when browsing to unsafe ports 的各種回覆答案。

Mozilla Firefox 也有一組黑名單的埠號清單

沒錯,Mozilla Firefox 也有一組黑名單的埠號清單,我用 Firefox 開啟 Port 10080 的網站,會出現以下畫面:

This address is restricted

我從網路上只能找到一份相當古老的歷史文件 (April 21, 2008),基本上沒有什麼公信力,文件所列的 Ports 清單也跟 Chromium 不太一樣。

我最後則是從 Firefox 的原始碼找到一份測試案例,裡面有提到 WHATWG communityFetch Standard 規格中,有明確提到 2.9. Port blocking 清單! 🔥

Bingo! 我原本還以為不同瀏覽器可能會有不同的實作,有標準就好辦了,大家都可以清楚的知道哪些 Ports 絕對不能拿來用瀏覽器開啟了! 👍

如果你想要設定 Firefox 開放受限制的 Ports,可以參考 How to create a preference/string to override access to a restricted address/port. | Knowledge Base discussions | Forums | Mozilla Support 這份文件。(影片教學)

使用 .NET CLI 或 Visual Studio 2022 建立專案的注意事項

事實上,從 ASP.NET Core 6.0 開始,透過 .NET CLI 或 Visual Studio 2022 建立的全新專案,都會預設指派一個亂數的 Ports,我們可以從 Configure endpoints for the ASP.NET Core Kestrel web server 得知,新專案的 HTTP Ports 會介於 5000-5300 之間,而 HTTPS Ports 會介於 7000-7300 之間,而這個設定預設會放在 Properties/launchSettings.json 設定檔中。

是的,你沒想錯,你有 300 分之 2 的機率 (0.66%) 會選到 50605061 這兩個黑名單的埠號,請大家務必小心!

我有看了 ASP.NET Core 6.0 原始碼,他們並沒有對這兩個 Ports 做排除,我想應該「很少人這麼好運」會選中這兩個 Ports,但中獎率確實比中樂透還高阿! 😅

我們軟體開發這一行,有太多的鬼故事,我們常常會遇到無法解釋的問題,我們都知道解決問題的方法很簡單,你可能會想:「就換個 Port 就好啦,幹嘛這麼麻煩?」但我認為,每一次的鬼打牆就是最好的學習機會,找尋每一個幽靈背後的科學原理,才是持續進步的不二法門!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK