[PR #2467] [MERGED] Fix server-side proxy inappropriate quit when met accept: too many open files error #4581

Closed
opened 2026-05-05 14:44:48 -06:00 by gitea-mirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/fatedier/frp/pull/2467
Author: @leiless
Created: 7/2/2021
Status: Merged
Merged: 7/5/2021
Merged by: @fatedier

Base: devHead: dev


📝 Commits (6)

  • afffbb5 proxy.go: Don't close listener when met 'accept: too many open files' error
  • 0ab00c8 frpc@.service: Rectify systemd run type from idle to simple
  • 2cfba84 systemd: Set ulimit -n to 1048576 by default
  • c5be960 conf/systemd/: Remove unnecessary comments
  • a41824b proxy.go: Adopt proper error handling from net/mux/mux.go#Serve()
  • f01f36e proxy.go: Minor cleanup due to PR feedbacks

📊 Changes

5 files changed (+23 additions, -2 deletions)

View changed files

📝 conf/systemd/frpc.service (+1 -0)
📝 conf/systemd/frpc@.service (+2 -1)
📝 conf/systemd/frps.service (+1 -0)
📝 conf/systemd/frps@.service (+1 -0)
📝 server/proxy/proxy.go (+18 -1)

📄 Description

How this happen

When the frps have massive concurrent connection establishments(especially for long-lived connections, e.g. http2, WebSocket), frps will use many file descriptors(expected behaviours), and eventually reach the ulimit -n limit.

After that the frps proxy listener simply log and quit, and the whole frps is refused to accepting any further connections.

Which is prone to DDOS attacks.

How to reproduce this bug

frps

No config file required, just use the defaults.

frpc

client.ini

[common]
server_addr = 127.0.0.1
server_port = 7000

[too-many-open-files-test]
type = tcp
remote_port = 1053
# Change to yours
local_ip = 192.168.200.1
local_port = 53

Why use DNS for test: simply because it's relative long-lived, anything else would be ok.

concurrent-conn.sh

#!/bin/bash

while :; do
    # Fire and forget(reach `ulimit -n` quickly)
    dig @127.0.0.1 -p1053 dns.google +tcp +short > /dev/null &
done

Reproduce procedures

Env: Ubuntu 20.04.2 LTS x86_64

  • ./frps
  • ./frpc -c client.ini
  • prlimit --pid $(pidof frps) --nofile=128:128
    Explicitly decrease nofile limit of frps to reach ulimit -n quickly
  • prlimit --pid $(pidof frpc) --nofile=102400:102400
    Explicitly increase nofile limit of frpc so frpc won't be the bottleneck
  • ./concurrent-conn.sh

frps output

2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:46129]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:50013]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:40547]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:42587]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:54785]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:49519]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:60873]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:42663]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:51231]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:58995]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:48041]
2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:43217]
2021/07/02 20:25:05 [W] [proxy.go:158] [fad8fd4213b57280] [too-many-open-files-test] listener is closed: *net.OpError accept tcp [::]:1053: accept4: too many open files

Verification taken from concurrent-conn.sh

After that the frps proxy listener simply log and quit, and the whole frps is refused to accepting any further connections.

# Check after we met 'accept: too many open files'
$ dig @127.0.0.1 -p1053 dns.google +tcp +short

; <<>> DiG 9.16.1-Ubuntu <<>> @127.0.0.1 -p1053 dns.google +tcp +short
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/fatedier/frp/pull/2467 **Author:** [@leiless](https://github.com/leiless) **Created:** 7/2/2021 **Status:** ✅ Merged **Merged:** 7/5/2021 **Merged by:** [@fatedier](https://github.com/fatedier) **Base:** `dev` ← **Head:** `dev` --- ### 📝 Commits (6) - [`afffbb5`](https://github.com/fatedier/frp/commit/afffbb5aa9e753cd16f3cbbe296bd3de9b8404fd) proxy.go: Don't close listener when met 'accept: too many open files' error - [`0ab00c8`](https://github.com/fatedier/frp/commit/0ab00c867e9034a87820f2f4f7899395b3c6f16b) frpc@.service: Rectify systemd run type from idle to simple - [`2cfba84`](https://github.com/fatedier/frp/commit/2cfba84e472c1de3e556049081fb24b5ffcc45a4) systemd: Set `ulimit -n` to 1048576 by default - [`c5be960`](https://github.com/fatedier/frp/commit/c5be960659b85e6b66dc8d16cdd90bb92c13888e) conf/systemd/: Remove unnecessary comments - [`a41824b`](https://github.com/fatedier/frp/commit/a41824b45433730cd993d8a2aa4d58001a0df7c2) proxy.go: Adopt proper error handling from net/mux/mux.go#Serve() - [`f01f36e`](https://github.com/fatedier/frp/commit/f01f36edd1b74efae436d6a4ad67e3a0add0130a) proxy.go: Minor cleanup due to PR feedbacks ### 📊 Changes **5 files changed** (+23 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `conf/systemd/frpc.service` (+1 -0) 📝 `conf/systemd/frpc@.service` (+2 -1) 📝 `conf/systemd/frps.service` (+1 -0) 📝 `conf/systemd/frps@.service` (+1 -0) 📝 `server/proxy/proxy.go` (+18 -1) </details> ### 📄 Description # How this happen When the `frps` have massive concurrent connection establishments(especially for long-lived connections, e.g. http2, WebSocket), `frps` will use many file descriptors(expected behaviours), and eventually reach the `ulimit -n` limit. After that the `frps` proxy listener simply log and quit, and the whole `frps` is refused to accepting any further connections. Which is prone to DDOS attacks. # How to reproduce this bug ## `frps` No config file required, just use the defaults. ## `frpc` ### `client.ini` ```ini [common] server_addr = 127.0.0.1 server_port = 7000 [too-many-open-files-test] type = tcp remote_port = 1053 # Change to yours local_ip = 192.168.200.1 local_port = 53 ``` Why use DNS for test: simply because it's relative long-lived, anything else would be ok. ## `concurrent-conn.sh` ```bash #!/bin/bash while :; do # Fire and forget(reach `ulimit -n` quickly) dig @127.0.0.1 -p1053 dns.google +tcp +short > /dev/null & done ``` # Reproduce procedures Env: Ubuntu 20.04.2 LTS x86_64 * `./frps` * `./frpc -c client.ini` * `prlimit --pid $(pidof frps) --nofile=128:128` Explicitly decrease nofile limit of `frps` to reach `ulimit -n` quickly * `prlimit --pid $(pidof frpc) --nofile=102400:102400` Explicitly increase nofile limit of `frpc` so `frpc` won't be the bottleneck * `./concurrent-conn.sh` # `frps` output ``` 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:46129] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:50013] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:40547] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:42587] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:54785] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:49519] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:60873] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:42663] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:51231] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:58995] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:48041] 2021/07/02 20:25:05 [I] [proxy.go:165] [fad8fd4213b57280] [too-many-open-files-test] get a user connection [127.0.0.1:43217] 2021/07/02 20:25:05 [W] [proxy.go:158] [fad8fd4213b57280] [too-many-open-files-test] listener is closed: *net.OpError accept tcp [::]:1053: accept4: too many open files ``` # Verification taken from `concurrent-conn.sh` > After that the `frps` proxy listener simply log and quit, and the whole `frps` is refused to accepting any further connections. ``` # Check after we met 'accept: too many open files' $ dig @127.0.0.1 -p1053 dns.google +tcp +short ; <<>> DiG 9.16.1-Ubuntu <<>> @127.0.0.1 -p1053 dns.google +tcp +short ; (1 server found) ;; global options: +cmd ;; connection timed out; no servers could be reached ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
gitea-mirror 2026-05-05 14:44:48 -06:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/frp#4581
No description provided.