[GH-ISSUE #5096] [Feature Request] 通过SRV或302重定向支持frps部署在内网 #4001

Closed
opened 2026-05-05 14:32:37 -06:00 by gitea-mirror · 1 comment
Owner

Originally created by @wukan1986 on GitHub (Dec 14, 2025).
Original GitHub issue: https://github.com/fatedier/frp/issues/5096

Describe the feature request

安装Lucky等STUN内网穿透工具,就能将7000暴露到公网了。这样可以实现不借助公网服务器,一个子网访问另一个子网提供的各种网络服务。

其他frpc就可以连接到动态的serverPort和serverAddr,只要编辑frpc.toml即可。

Lucky可以配置将STUN端口通过WebHook更新到Cloudflare。有两种方案

  1. DNS SRV记录(也支持其他DNS服务商)
  2. Cloudflare 规则 302重定向

这两种方案都可以传递新域名(IP)和端口,然后用脚本来更新toml

SRV记录

# pip install dnspython
import dns.rdatatype
import dns.rdtypes.IN.SRV
import dns.resolver


def query_srv_record(service, protocol, domain):
    """
    查询SRV记录
    格式: _service._protocol.domain
    例如: _sip._tcp.example.com
    """
    srv_domain = f"_{service}._{protocol}.{domain}"

    try:
        resolver = dns.resolver.Resolver()

        # 设置DNS服务器(可选)
        # resolver.nameservers = ['8.8.8.8']

        # 查询SRV记录
        answer = resolver.resolve(srv_domain, 'SRV')

        results = []
        for rdata in answer:
            # SRV记录包含:优先级、权重、端口、目标主机
            srv_info = {
                'priority': rdata.priority,
                'weight': rdata.weight,
                'port': rdata.port,
                'target': rdata.target.to_text().rstrip('.')
            }
            results.append(srv_info)

        # 按优先级和权重排序
        results.sort(key=lambda x: (x['priority'], -x['weight']))
        return results

    except dns.resolver.NoAnswer:
        print(f"没有找到SRV记录: {srv_domain}")
        return []
    except dns.resolver.NXDOMAIN:
        print(f"域名不存在: {srv_domain}")
        return []
    except Exception as e:
        print(f"查询失败: {e}")
        return []


# 使用示例
srv_records = query_srv_record('frp', 'tcp', 'frp.example.com')
for record in srv_records:
    print(f"目标: {record['target']}:{record['port']} (优先级: {record['priority']}, 权重: {record['weight']})")

toml = """
serverAddr = "{target}"
serverPort = {port}
auth.token = "frp.example.com"

[[proxies]]
name = "test"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 7001

"""

toml = toml.format(target=srv_records[0]['target'], port=srv_records[0]['port'])
print(toml)

with open("frpc.toml", 'w', encoding='utf-8') as f:
    f.write(toml)

302重定向

from urllib.parse import urlparse

import requests

response = requests.get("https://www.baidu.com", allow_redirects=True)
# 获取最终的 URL(可能经过重定向)
final_url = response.url
parsed_url = urlparse(final_url)
port = parsed_url.port or (443 if parsed_url.scheme == 'https' else 80)
print(parsed_url.hostname, port)

toml = """
serverAddr = "{target}"
serverPort = {port}
auth.token = "frp.example.com"

[[proxies]]
name = "aaaa"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 7001

"""

toml = toml.format(target=parsed_url.hostname, port=port)
print(toml)

with open("frpc.toml", 'w', encoding='utf-8') as f:
    f.write(toml)

这两种办法的局限是都需要在启动frpc前更新toml,如果中途STUN重新打洞,需要重新启动脚本获取新端口,并重启frpc

如果frp原生支持这两种模式,那么可以省去重新更新端口的步骤,那就非常棒了

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 @wukan1986 on GitHub (Dec 14, 2025). Original GitHub issue: https://github.com/fatedier/frp/issues/5096 ### Describe the feature request 安装Lucky等STUN内网穿透工具,就能将7000暴露到公网了。这样可以实现不借助公网服务器,一个子网访问另一个子网提供的各种网络服务。 其他frpc就可以连接到动态的serverPort和serverAddr,只要编辑frpc.toml即可。 Lucky可以配置将STUN端口通过WebHook更新到Cloudflare。有两种方案 1. DNS SRV记录(也支持其他DNS服务商) 2. Cloudflare 规则 302重定向 这两种方案都可以传递新域名(IP)和端口,然后用脚本来更新toml ## SRV记录 ```python # pip install dnspython import dns.rdatatype import dns.rdtypes.IN.SRV import dns.resolver def query_srv_record(service, protocol, domain): """ 查询SRV记录 格式: _service._protocol.domain 例如: _sip._tcp.example.com """ srv_domain = f"_{service}._{protocol}.{domain}" try: resolver = dns.resolver.Resolver() # 设置DNS服务器(可选) # resolver.nameservers = ['8.8.8.8'] # 查询SRV记录 answer = resolver.resolve(srv_domain, 'SRV') results = [] for rdata in answer: # SRV记录包含:优先级、权重、端口、目标主机 srv_info = { 'priority': rdata.priority, 'weight': rdata.weight, 'port': rdata.port, 'target': rdata.target.to_text().rstrip('.') } results.append(srv_info) # 按优先级和权重排序 results.sort(key=lambda x: (x['priority'], -x['weight'])) return results except dns.resolver.NoAnswer: print(f"没有找到SRV记录: {srv_domain}") return [] except dns.resolver.NXDOMAIN: print(f"域名不存在: {srv_domain}") return [] except Exception as e: print(f"查询失败: {e}") return [] # 使用示例 srv_records = query_srv_record('frp', 'tcp', 'frp.example.com') for record in srv_records: print(f"目标: {record['target']}:{record['port']} (优先级: {record['priority']}, 权重: {record['weight']})") toml = """ serverAddr = "{target}" serverPort = {port} auth.token = "frp.example.com" [[proxies]] name = "test" type = "tcp" localIP = "127.0.0.1" localPort = 8080 remotePort = 7001 """ toml = toml.format(target=srv_records[0]['target'], port=srv_records[0]['port']) print(toml) with open("frpc.toml", 'w', encoding='utf-8') as f: f.write(toml) ``` ## 302重定向 ```python from urllib.parse import urlparse import requests response = requests.get("https://www.baidu.com", allow_redirects=True) # 获取最终的 URL(可能经过重定向) final_url = response.url parsed_url = urlparse(final_url) port = parsed_url.port or (443 if parsed_url.scheme == 'https' else 80) print(parsed_url.hostname, port) toml = """ serverAddr = "{target}" serverPort = {port} auth.token = "frp.example.com" [[proxies]] name = "aaaa" type = "tcp" localIP = "127.0.0.1" localPort = 8080 remotePort = 7001 """ toml = toml.format(target=parsed_url.hostname, port=port) print(toml) with open("frpc.toml", 'w', encoding='utf-8') as f: f.write(toml) ``` 这两种办法的局限是都需要在启动frpc前更新toml,如果中途STUN重新打洞,需要重新启动脚本获取新端口,并重启frpc 如果frp原生支持这两种模式,那么可以省去重新更新端口的步骤,那就非常棒了 ### 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
gitea-mirror 2026-05-05 14:32:37 -06:00
Author
Owner

@github-actions[bot] commented on GitHub (Dec 29, 2025):

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

<!-- gh-comment-id:3695193412 --> @github-actions[bot] commented on GitHub (Dec 29, 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#4001
No description provided.