[GH-ISSUE #4640] FRPS日志中有没有可能记录得到请求头传递的地址 #3666

Closed
opened 2026-05-05 14:21:06 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @somnifex on GitHub (Jan 16, 2025).
Original GitHub issue: https://github.com/fatedier/frp/issues/4640

Describe the feature request

我在FRPS服务后套nginx反代端口,这种情况下frps日志中获取的访问ip是127.0.0.1,我想构建一套统一基于frps.log的fail2ban规则,想请问一下frps中有没有可能在日志中获取真实访问ip。(这是一个求助issus,不是功能请求,因为我知道这种fail2ban的用法不符合一般的规范,只是我的个人情况,合理的方案应该是对nginx日志进行分析从而执行ip ban)

Describe alternatives you've considered

No response

Affected area

  • Docs
  • Installation
  • Performance and Scalability
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
Originally created by @somnifex on GitHub (Jan 16, 2025). Original GitHub issue: https://github.com/fatedier/frp/issues/4640 ### Describe the feature request 我在FRPS服务后套nginx反代端口,这种情况下frps日志中获取的访问ip是127.0.0.1,我想构建一套统一基于frps.log的fail2ban规则,想请问一下frps中有没有可能在日志中获取真实访问ip。(这是一个求助issus,不是功能请求,因为我知道这种fail2ban的用法不符合一般的规范,只是我的个人情况,合理的方案应该是对nginx日志进行分析从而执行ip ban) ### Describe alternatives you've considered _No response_ ### Affected area - [ ] Docs - [ ] Installation - [ ] Performance and Scalability - [ ] Security - [ ] User Experience - [ ] Test and Release - [ ] Developer Infrastructure - [ ] Client Plugin - [ ] Server Plugin - [ ] Extensions - [X] Others
gitea-mirror 2026-05-05 14:21:06 -06:00
Author
Owner

@potoo0 commented on GitHub (Jan 17, 2025):

单纯讨论 http 代理的话,是能获取到的。代码这里 req 就是客户端请求,header / path / queryparams 等都可以在这里获取到。一般来说 http(s) 代理会通过 header(X-Forwarded-For / X-Real-IP) 传递真实 ip,所以这里可以 req.Header.Get("X-Forwarded-For")

而对于 tcp 连接,debug 日志已经包含了,userConn.RemoteAddr()


我现在的方案是:

  1. frpc 端获取到真实 ip (ssh 可以参考 issue#2470 的方案 Proxy Protocol and go-mmproxy)
  2. 通过 fail2ban 自定义的 action (比如名称叫 remote) 将待封禁的 ip 在 frps 机器上执行 ban

自定义的 action:

# write to dir action.d/remote.local
# send ban ip to remote
[Definition]
actionstart =
actionstop =
timeout =

# test
# actionban = echo 'ban <ip>. matches=<matches> ' >> /var/log/fail2ban.log
# actionunban = echo unban <ip> >> /var/log/fail2ban.log
actionban = ssh ali 'fail2ban-client set sshd banip <ip>'
actionunban = ssh ali 'fail2ban-client unban <ip>'

然后在目标 jail 里配置: banaction = remote,如:

[sshd]
enabled = true
banaction = remote

[jupyter]
enabled = true
backend = systemd[journalflags=1]
banaction = remote
<!-- gh-comment-id:2598365391 --> @potoo0 commented on GitHub (Jan 17, 2025): 单纯讨论 http 代理的话,是能获取到的。[代码这里 req](https://github.com/fatedier/frp/blob/450b8393bc5a06fd1182690b967e8deb0c20b606/pkg/util/vhost/http.go#L65) 就是客户端请求,header / path / queryparams 等都可以在这里获取到。一般来说 http(s) 代理会通过 header(`X-Forwarded-For` / `X-Real-IP`) 传递真实 ip,所以这里可以 `req.Header.Get("X-Forwarded-For")`。 而对于 tcp 连接,debug 日志已经包含了,[userConn.RemoteAddr()](https://github.com/fatedier/frp/blob/450b8393bc5a06fd1182690b967e8deb0c20b606/server/proxy/proxy.go#L261)。 --- 我现在的方案是: 1. frpc 端获取到真实 ip (ssh 可以参考 issue#2470 的方案 [Proxy Protocol and go-mmproxy](https://github.com/fatedier/frp/issues/2470#issuecomment-878131408)) 2. 通过 fail2ban 自定义的 action (比如名称叫 *remote*) 将待封禁的 ip 在 frps 机器上执行 ban 自定义的 action: ```ini # write to dir action.d/remote.local # send ban ip to remote [Definition] actionstart = actionstop = timeout = # test # actionban = echo 'ban <ip>. matches=<matches> ' >> /var/log/fail2ban.log # actionunban = echo unban <ip> >> /var/log/fail2ban.log actionban = ssh ali 'fail2ban-client set sshd banip <ip>' actionunban = ssh ali 'fail2ban-client unban <ip>' ``` 然后在目标 jail 里配置: `banaction = remote`,如: ```ini [sshd] enabled = true banaction = remote [jupyter] enabled = true backend = systemd[journalflags=1] banaction = remote ```
Author
Owner

@somnifex commented on GitHub (Jan 17, 2025):

单纯讨论 http 代理的话,是能获取到的。代码这里 req 就是客户端请求,header / path / queryparams 等都可以在这里获取到。一般来说 http(s) 代理会通过 header(X-Forwarded-For / X-Real-IP) 传递真实 ip,所以这里可以 req.Header.Get("X-Forwarded-For")

而对于 tcp 连接,debug 日志已经包含了,userConn.RemoteAddr()


我现在的方案是:

  1. frpc 端获取到真实 ip (ssh 可以参考 issue#2470 的方案 Proxy Protocol and go-mmproxy)
  2. 通过 fail2ban 自定义的 action (比如名称叫 remote) 将待封禁的 ip 在 frps 机器上执行 ban

自定义的 action:

# write to dir action.d/remote.local
# send ban ip to remote
[Definition]
actionstart =
actionstop =
timeout =

# test
# actionban = echo 'ban <ip>. matches=<matches> ' >> /var/log/fail2ban.log
# actionunban = echo unban <ip> >> /var/log/fail2ban.log
actionban = ssh ali 'fail2ban-client set sshd banip <ip>'
actionunban = ssh ali 'fail2ban-client unban <ip>'

然后在目标 jail 里配置: banaction = remote,如:

[sshd]
enabled = true
banaction = remote

[jupyter]
enabled = true
backend = systemd[journalflags=1]
banaction = remote

看起来是一种解决方案,俺研究一下

<!-- gh-comment-id:2598371956 --> @somnifex commented on GitHub (Jan 17, 2025): > 单纯讨论 http 代理的话,是能获取到的。[代码这里 req](https://github.com/fatedier/frp/blob/450b8393bc5a06fd1182690b967e8deb0c20b606/pkg/util/vhost/http.go#L65) 就是客户端请求,header / path / queryparams 等都可以在这里获取到。一般来说 http(s) 代理会通过 header(`X-Forwarded-For` / `X-Real-IP`) 传递真实 ip,所以这里可以 `req.Header.Get("X-Forwarded-For")`。 > > 而对于 tcp 连接,debug 日志已经包含了,[userConn.RemoteAddr()](https://github.com/fatedier/frp/blob/450b8393bc5a06fd1182690b967e8deb0c20b606/server/proxy/proxy.go#L261)。 > > --- > 我现在的方案是: > 1. frpc 端获取到真实 ip (ssh 可以参考 issue#2470 的方案 [Proxy Protocol and go-mmproxy](https://github.com/fatedier/frp/issues/2470#issuecomment-878131408)) > 2. 通过 fail2ban 自定义的 action (比如名称叫 *remote*) 将待封禁的 ip 在 frps 机器上执行 ban > > 自定义的 action: > ```ini > # write to dir action.d/remote.local > # send ban ip to remote > [Definition] > actionstart = > actionstop = > timeout = > > # test > # actionban = echo 'ban <ip>. matches=<matches> ' >> /var/log/fail2ban.log > # actionunban = echo unban <ip> >> /var/log/fail2ban.log > actionban = ssh ali 'fail2ban-client set sshd banip <ip>' > actionunban = ssh ali 'fail2ban-client unban <ip>' > ``` > > 然后在目标 jail 里配置: `banaction = remote`,如: > ```ini > [sshd] > enabled = true > banaction = remote > > [jupyter] > enabled = true > backend = systemd[journalflags=1] > banaction = remote > ``` > 看起来是一种解决方案,俺研究一下
Author
Owner

@potoo0 commented on GitHub (Jan 17, 2025):

单纯讨论 http 代理的话,是能获取到的。代码这里 req 就是客户端请求,header / path / queryparams 等都可以在这里获取到。一般来说 http(s) 代理会通过 header(X-Forwarded-For / X-Real-IP) 传递真实 ip,所以这里可以 req.Header.Get("X-Forwarded-For")
...
看起来是一种解决方案,俺研究一下

fail2ban-client 的文档

<!-- gh-comment-id:2598385088 --> @potoo0 commented on GitHub (Jan 17, 2025): > > 单纯讨论 http 代理的话,是能获取到的。[代码这里 req](https://github.com/fatedier/frp/blob/450b8393bc5a06fd1182690b967e8deb0c20b606/pkg/util/vhost/http.go#L65) 就是客户端请求,header / path / queryparams 等都可以在这里获取到。一般来说 http(s) 代理会通过 header(`X-Forwarded-For` / `X-Real-IP`) 传递真实 ip,所以这里可以 `req.Header.Get("X-Forwarded-For")`。 > > ... > 看起来是一种解决方案,俺研究一下 [fail2ban-client 的文档](https://man.archlinux.org/man/fail2ban-client.1#set~26)
Author
Owner

@github-actions[bot] commented on GitHub (Feb 1, 2025):

Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.

<!-- gh-comment-id:2628622198 --> @github-actions[bot] commented on GitHub (Feb 1, 2025): Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.
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#3666
No description provided.