olNGIb4NkK5r2x7x4oG3GpEzizVpnY6KNCck9cym

哪些連接埠會使 Google Chrome / Microsoft Edge / Mozilla FireFox 訪問失敗,並顯示 "ERR_UNSAFE_PORT" 錯誤?

在 WHATWG 中給定了一組 bad port 清單,當客戶端使用 HTTP/HTTPS 協議訪問這些連接埠時,會被阻擋並顯示 "ERR_UNSAFE_PORT" 錯誤。

筆者在手邊的香橙派(OrangePi)開發板上測試運行 Fergejo 時,由於預設的連接埠(port)已經被占用,便隨手設了個 6666 感覺就很吉利的數字,卻沒想到使用 Google Chrome 瀏覽器嘗試訪問頁面時,卻顯示了 ERR_UNSAFE_PORT 的錯誤:

訪問 6666 連接埠時,提示 'ERR_UNSAFE_PORT' 錯誤
訪問 6666 連接埠時,提示 ERR_UNSAFE_PORT 錯誤

順手查了一下資料,才知道 Google Chrome、Microsoft Edge 和 Mozilla FireFox 等瀏覽器都有自己的預設非安全連接埠(unsafe port)名單。

這是為了防止潛在的連接埠(port)劫持或是惡意攻擊等安全風險,從而阻擋發送的請求,換句話說:如果訪問的連接埠屬於瀏覽器預設的非安全連接埠,發送的請求並不會被送到伺服器端,而是直接在瀏覽器客戶端被阻擋了

那麼有哪些連接埠會被瀏覽器視為是非安全連接埠(unsafe port)呢?除了在 Neo4j 的開發人員知識庫中有一份 List of Restricted Ports in Browsers 整理了常見的非安全連接埠,筆者還找了一下這些瀏覽器的專案倉庫,一併整理如下:

Google Chrome / Microsoft Edge

Google Chrome 並非開源專案,而 Microsoft Edge 則是基於開源的 Chromium 專案,兩者的名單應該相差不大。其中非安全連接埠(unsafe port)的部分可以在 /net/base/port_util.cc 找到:

// 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. See <https://fetch.spec.whatwg.org/#port-blocking>.
const int kRestrictedPorts[] = {
    0,      // Not in Fetch Spec.
    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
};

Morzilla Firefox

至於 Morzilla Firefox 的部分,在保哥的 開發與部署網站時需注意不要使用到 ERR_UNSAFE_PORT 不安全的埠號 一文中,提及的是一份測試案例

var BLOCKED_PORTS_LIST = [
    1,    // tcpmux
    7,    // echo
    9,    // discard
    11,   // systat
    13,   // daytime
    15,   // netstat
    17,   // qotd
    19,   // chargen
    20,   // ftp-data
    21,   // ftp
    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-ns
    139,  // netbios-ssn
    143,  // imap2
    161,  // snmp
    179,  // bgp
    389,  // ldap
    427,  // afp (alternate)
    465,  // smtp (alternate)
    512,  // print / exec
    513,  // login
    514,  // shell
    515,  // printer
    526,  // tempo
    530,  // courier
    531,  // chat
    532,  // netnews
    540,  // uucp
    548,  // afp
    554,  // rtsp
    556,  // remotefs
    563,  // nntp+ssl
    587,  // smtp (outgoing)
    601,  // syslog-conn
    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
    4045, // lockd
    4190, // sieve
    5060, // sip
    5061, // sips
    6000, // x11
    6566, // sane-port
    6665, // irc (alternate)
    6666, // irc (alternate)
    6667, // irc (default)
    6668, // irc (alternate)
    6669, // irc (alternate)
    6679, // osaut
    6697, // irc+tls
    10080, // amanda
];

不過筆者還是從 Mozilla Firefox 的專案倉庫中找到了對應的程式,位於 /network/base/nslOService.cpp 中:

// A general port blacklist.  Connections to these ports will not be allowed
// unless the protocol overrides.
//
// This list is to be kept in sync with "bad ports" as defined in the
// WHATWG Fetch standard at <https://fetch.spec.whatwg.org/#port-blocking>

int16_t gBadPortList[] = {
    1,      // tcpmux
    7,      // echo
    9,      // discard
    11,     // systat
    13,     // daytime
    15,     // netstat
    17,     // qotd
    19,     // chargen
    20,     // ftp-data
    21,     // ftp
    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,    // afp (alternate)
    465,    // smtp (alternate)
    512,    // print / exec
    513,    // login
    514,    // shell
    515,    // printer
    526,    // tempo
    530,    // courier
    531,    // chat
    532,    // netnews
    540,    // uucp
    548,    // afp
    554,    // rtsp
    556,    // remotefs
    563,    // nntp+ssl
    587,    // smtp (outgoing)
    601,    // syslog-conn
    636,    // ldap+ssl
    989,    // ftps-data
    990,    // ftps
    993,    // imap+ssl
    995,    // pop3+ssl
    1719,   // h323gatestat
    1720,   // h323hostcall
    1723,   // pptp
    2049,   // nfs
    3659,   // apple-sasl
    4045,   // lockd
    4190,   // sieve
    5060,   // sip
    5061,   // sips
    6000,   // x11
    6566,   // sane-port
    6665,   // irc (alternate)
    6666,   // irc (alternate)
    6667,   // irc (default)
    6668,   // irc (alternate)
    6669,   // irc (alternate)
    6679,   // osaut
    6697,   // irc+tls
    10080,  // amanda
    0,      // Sentinel value: This MUST be zero
};
那麼問題來了:「Google Chrome/Microsoft Edge 和 Mozilla Firefox 的非安全連接埠(unsafe port)清單一樣嗎?」不一樣!比對之後可以發現 在 Morzilla Firefox 的非安全連接埠(unsafe ports)名單中,多出了 4190 (sieve)6697 (irc+tls) 兩個非安全連接埠

規格文件:Fetch Standard

眼尖的你或許也有發現,兩份原始碼中其實都提到了 網頁超文字應用技術工作小組(Web Hypertext Application Technology Working Group, WHATWG) 的一份 Fetch Standard 規格,在其中的 Port Blocking 小節中列出了常見的 bad port,並且表示 如果請求是透過 HTTP/HTTPS 協議傳輸,並且連接埠屬於 bad port 就必須阻擋該請求

此外在這份文件中還提到了例外狀況,亦即在 [RFC7301] 中指出,如果透過了是 TLS 的 ALPN 機制進行協商的應用層協議,比如:HTTP/2、HTTP/3、gRPC 和 QUIC 等,由於協議由底層的加密層確定,因此無法被假冒為 HTTP 請求,不容易遭受惡意攻擊,因此可以避免對連接埠進行封鎖。

另外一件有趣的事,是 網頁超文字應用技術工作小組(Web Hypertext Application Technology Working Group, WHATWG) 給出的 bad port 清單中,其實列有 4190 (sieve)6697 (ircs-u) 連接埠,但不知道為什麼 Chromium 並沒有加上它?

張貼留言