ByteScope

6379

連接埠 6379 · Redis

TCPIANA 有指派資料庫

Redis 伺服器聽 RESP 的連接埠——你的用戶端說連不到的那一個,也是暴露在外的快取幾個小時內就會被找到的那一個。

查出是誰占用連接埠 6379

照你的系統挑一行貼上去執行。它會直接印出占著這個連接埠的行程,以及它綁在哪個位址上——通常看到這兩件事答案就出來了。

  • macOS
    sudo lsof -nP -iTCP:6379 -sTCP:LISTEN

    `-n` 跳過反向 DNS 查詢,`-P` 跳過連接埠名稱查詢,所以位址維持數字;`-iTCP:6379` 收斂到那個連接埠,`-sTCP:LISTEN` 收斂到監聽狀態——這正是 lsof 自己的手冊拿來當範例的那個組合。欄位依序是 COMMAND、PID、USER、FD、TYPE、DEVICE、SIZE/OFF、NODE、NAME。第二欄是你會去停掉的那個行程,最後一欄是綁定位址,印成 `127.0.0.1:6379 (LISTEN)` 或 `*:6379 (LISTEN)`。回送位址代表只有這台機器連得進來,這也是為什麼容器或另一台主機永遠連不到;`*` 則是每一張介面。完全沒有任何一行、lsof 以 1 結束,代表連接埠是真的空的。不加 `sudo` 只看得到自己的行程,所以由 launch daemon 或 Docker 啟動的 `redis-server` 看起來會像什麼都沒有。

  • Linux
    sudo ss -tlnp 'sport = :6379'

    ss(8) 手冊對每個旗標都有定義:`-t` 顯示 TCP socket,`-l` 只顯示監聽中的 socket,`-n` 不解析服務名稱,`-p` 顯示使用該 socket 的行程,而 `sport = :6379` 是它文件裡寫的 `{dport|sport} [OP] [FAMILY:]:PORT` 過濾格式。讀 Local Address:Port 那一欄:`0.0.0.0:6379` 是每一個 IPv4 位址,`127.0.0.1:6379` 只有回送位址,`[::]:6379` 是 IPv6 萬用位址,在預設的 Linux 主機上也會收 IPv4 連線。持有者印成 `users:(("redis-server",pid=1234,fd=6))`。沒有 `ss` 的機器上,比較舊的 `netstat -tlnp` 給你同樣的三件事;netstat 的手冊提醒你要有超級使用者權限才看得到不屬於你的 socket 的程式名稱,`ss` 也一樣。

  • Linux
    redis-cli -h 127.0.0.1 -p 6379 ping

    同一個問題的應用層版本,也是把「有個 socket 開著」和「Redis 真的會回答你」分開的那一個。`PONG` 代表伺服器健康。`NOAUTH Authentication required.` 同樣代表健康——連接埠和網路都沒問題,只是少了帳密。`Could not connect to Redis at 127.0.0.1:6379: Connection refused` 代表那裡沒有人在聽。請把位址寫死,不要寫 `-h localhost`:在雙堆疊主機上那個名稱可能解析成 `::1`,而伺服器只綁了 IPv4,這時候的失敗看起來會和伺服器停掉一模一樣。

  • Windows
    netstat -ano | findstr :6379

    微軟對這些旗標的說明是:`-a`「顯示所有作用中的 TCP 連線,以及電腦正在監聽的 TCP 和 UDP 連接埠」,`-n` 以數字表示位址和連接埠號碼,`-o`「為每一條連線包含行程 ID(PID)」。欄位是 Proto、Local Address、Foreign Address、State、PID,所以第二欄是綁定位址、最後一欄是行程。用 `tasklist /fi "PID eq 1234"` 把 PID 換成名字——`PID` 是文件裡有的過濾名稱,`eq` 是它文件裡有的運算子。不過比對要小心:`findstr` 是在整行任何位置找子字串,所以一行 Foreign Address 結尾是 `:6379` 的紀錄——也就是一條對外的用戶端連線——同樣會命中。停掉任何東西之前,先確認 State 那一欄寫的是 LISTENING。

  • Windows
    Get-NetTCPConnection -LocalPort 6379 | Select-Object LocalAddress,LocalPort,State,OwningProcess

    PowerShell 這個寫法把連接埠當數字比對而不是文字,所以沒有任何子字串騙得了它,而且 `-LocalPort` 永遠不會撈到 6379 在遠端那一側的連線。把 `OwningProcess` 的值丟給 `Get-Process -Id` 就能拿到映像檔名稱。結果是空的、綁定卻還是失敗,那就是保留範圍的情況:`netsh interface ipv4 show excludedportrange protocol=tcp` 會列出 Hyper-V、WSL2 和 Docker Desktop 開機時搶下的動態連接埠區段,落在裡面的綁定會失敗,而且沒有行程可以怪。

從機器外面確認一次

`nmap -Pn -p 6379 cache.example.com` 回答的是離開這台主機之後唯一重要的那個問題。`-Pn` 把主機當成上線的、跳過探索,所以不理 ping 的機器照樣掃得到,而 `-p` 把掃描限制在你在意的那個連接埠。`open` 代表 TCP 交握完成:有東西在聽而且碰得到。`closed` 代表主機回了 reset,所以它活著、路由得到,但沒有人占著這個連接埠。`filtered` 代表什麼都沒回來——防火牆或雲端安全群組把封包丟掉而不是拒絕,而這個差別就是整個診斷。加 `--reason` 看實際發生的是三者中的哪一個;nmap 會在 open 的連接埠旁印 `syn-ack`,在 closed 的旁邊印 `conn-refused`。`-sV` 更進一步,它會探測連接埠以辨識服務和版本,對 Redis 通常會回傳版本字串——而這正是全網掃描器找到沒保護的執行個體的方法。只掃你自己負責的主機。

連不上 6379 的時候怎麼讀

你看到的訊息代表什麼
Could not connect to Redis at 127.0.0.1:6379: Connection refused(連線被拒絕)redis-cli 對 `ECONNREFUSED` 的說法:封包送到主機了,而核心回了一個 reset,因為沒有行程占著這個連接埠。Redis 停了、啟動途中死了,或是綁在一個不包含你撥過去那個位址的地方。在斷定它有起來過之前先讀它的紀錄檔——一台拿不到連接埠的伺服器會記下 `Failed listening on port 6379 (tcp), aborting.` 然後結束。
Warning: Could not create server TCP listening socket 127.0.0.1:6379: bind: Address already in use(6379 已經被占用)連接埠被占用時 Redis 自己的啟動訊息,後面會接 `Failed listening on port 6379 (tcp), aborting.` 然後結束。十次有九次是先前那個 `redis-server` 被丟到背景而不是真的停掉,再不然就是某個容器還在發布這個連接埠。用你系統對應的探測指令跑一次,把 PID 從裡面讀出來,不要用猜的。
(error) DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user.(受保護模式拒絕了連線)網路沒問題,Redis 也在跑。它拒絕你,是因為你從非回送位址進來,而這台伺服器沒有密碼、也沒有明確的 bind。錯誤訊息本身列了四條出路,挑那條設密碼或設 ACL 使用者的。在一台碰得到的伺服器上關掉 protected mode,正是那些執行個體被清空的方式。
(error) NOAUTH Authentication required.(需要先驗證)完全不是連接埠問題——連線成功了,而 `requirepass` 或某條 ACL 正在生效。先送 `AUTH <password>`,ACL 使用者則送 `AUTH <user> <password>`,或者把帳密放進連線 URL。在明文連接埠上,那個密碼是以明文穿過網路的。
用戶端卡了幾十秒,然後回報連線逾時`ETIMEDOUT`:什麼都沒回應。有個封包過濾器安靜地把 SYN 丟掉而不是拒絕——安全群組、主機上的防火牆,或你和快取之間的某條網路 ACL。被拒絕是瞬間的、被丟掉是慢的,所以光是這段延遲就告訴你現在看的是哪一種。
(error) MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk.(無法把 RDB 快照寫入磁碟)這也跟 6379 無關。連線是通的,而 Redis 拒絕寫入,是因為背景存檔失敗了,通常是磁碟滿了或某個目錄它寫不進去。整段期間讀取都還是正常的。去修磁碟,或者如果你接受丟掉那份快照,就改 `stop-writes-on-bgsave-error`。

連接埠 6379 上跑的是什麼

IANA 把 6379 登記給 TCP 上的 `redis`;同號碼的 UDP 那一列沒有服務名稱、標記為 Reserved,而且 Redis 沒有任何東西講 UDP,所以一篇關於 6379 的文章就是一篇只關於 TCP 的文章。這個號碼來自伺服器內附 `redis.conf` 裡的 `port 6379` 那一行,而 `redis-cli` 也用同一個值當自己的預設,這就是為什麼在本機安裝上 `redis-cli ping` 不用帶任何參數。混淆多半來自三個鄰居號碼。Redis Sentinel 有一份獨立的設定檔,它的 `port` 是 26379,所以 Sentinel 絕不會是 6379 上的那個東西。跑在 cluster 模式的節點會另外開一個監聽 socket 給 cluster bus,而 `redis.conf` 寫明在 `cluster-port` 維持預設值 0 時,bus 會綁到指令連接埠加 10000——預設節點就是 16379——所以一個 cluster 成員持有的是兩個連接埠,不是一個。至於 Redis 6 加進來的 TLS,是透過另一個 `tls-port` 設定的:在你刻意把 `port` 設成 0 之前,原本那個連接埠會繼續在旁邊講沒有加密的 RESP。最後這件事值得講兩次,因為它就是大家會弄錯的那一個:除非有人把明文連接埠關掉,否則連到 6379 的連線就是明文。

連接埠 6379 該不該對外開

永遠不要讓 6379 面向網際網路。Redis 在自己的安全性頁面上就把設計前提講清楚了——它「是設計來讓受信任環境裡的受信任用戶端存取的」——而且把兩個後果都寫出來了。任何碰得到這個連接埠的人,一個 `FLUSHALL` 就能毀掉整份資料集。更糟的是 `CONFIG` 指令讓用戶端可以改工作目錄和 dump 檔名,同一頁把這稱為一個資安問題,「可能導致系統被入侵,或以 Redis 執行身分的同一個使用者執行不受信任的程式碼」。這就是每一起大規模 Redis 攻擊背後的手法:把一個 dump 檔寫進作業系統稍後會讀回去的路徑。protected mode 有幫助,但它比大家以為的窄。從 3.2.0 起,Redis 會對非回送位址的用戶端回 `-DENIED` 錯誤,而文件對時機講得很精確:只有在伺服器跑著預設設定、綁在所有介面上、而且沒有設密碼的時候。為了讓伺服器連得到而加上一行明確的 `bind 0.0.0.0`,同時也拆掉了那道護欄,而那正是維運者在事故發生前不久做的那個編輯。內附的 `redis.conf` 綁的是 `127.0.0.1 -::1`;保持那樣,在它前面擺一個密碼或一個 ACL 使用者,遠端執行個體走 VPN 或 SSH 通道進去,並且記得在明文連接埠上,`AUTH` 本身也是明文送出去的。

服務
Redis
傳輸協定
TCP
登記狀態
IANA 有指派
分類
資料庫

站上可以搭配的工具

這些全都在你的瀏覽器裡跑,不會上傳任何東西。

相關連接埠

查 6379 的時候,通常也會順手看一下這幾個。

常見問題

明明就有東西在用,指令卻什麼都沒印出來?

幾乎都是權限問題。lsof 和 ss 會列出 socket,但別人的行程它不會顯示所有者,所以由系統帳號、容器執行環境或 launchd 啟動的服務,在你補上 sudo 之前就只是一個沒有主人的監聽項。Windows 則是反過來:netstat 什麼都沒有,綁定卻還是失敗,那代表這個號碼落在 Hyper-V、WSL2 或 Docker Desktop 開機時預留的範圍裡。

占著連接埠的那個行程可以直接砍掉嗎?

先看清楚它是什麼。沒收乾淨的開發伺服器砍掉沒事;正在寫入的資料庫不行,其他東西依賴的系統服務也不行。如果持有者是容器,請停容器,不要砍主機看到的那個行程——砍了執行環境只會把它拉起來。遇到真的不能動的,把自己的服務換一個連接埠反而更快。

為什麼本機連得到,別台機器就連不到?

因為它綁在 127.0.0.1 而不是 0.0.0.0。每一頁的指令之所以會把綁定位址跟行程名一起印出來,就是為了這件事:綁在回送位址上的服務,不管防火牆怎麼設,都只有這台機器自己連得到。現在不少框架是刻意這樣預設的,所以通常是一個參數的問題,不是 bug。如果已經是 0.0.0.0 還是不通,下一個要懷疑的就是主機防火牆或雲端的安全群組。

把服務換到冷門的連接埠會比較安全嗎?

幾乎沒有幫助。掃全網的機器持續在掃整段範圍,換號碼買到的是幾個小時,不是安全,代價卻是每個同事都得記住它。它確實能讓針對預設埠的無差別掃描少污染一點日誌,這算是實際但有限的好處。真正會改變結果的是認證、限制來源位址的防火牆,以及一開始就不要讓它對外。

連接埠 6379 還是卡住嗎?看完整的連接埠對照表,或是回到上面,從你實際看到的那行錯誤往回追。