[GH-ISSUE #4558] [Feature Request] add support in frpc for demultiplexing (vhost) multiple HTTPS targets (based on SNI) #3604

Closed
opened 2026-05-05 14:18:53 -06:00 by gitea-mirror · 15 comments
Owner

Originally created by @ofirc on GitHub (Nov 25, 2024).
Original GitHub issue: https://github.com/fatedier/frp/issues/4558

Describe the feature request

Is there a way to implement SNI-based routing, that is to demultiplex a single connection onto different targets?

This is how I currently implement it with Caddy and Caddy L4 plugin:

{
   admin :2019
   debug
    layer4 {
        :4000 {
            @secure tls sni backend-a
            route @secure {
                proxy backend-a:6000
            }
            @secured tls sni backend-b
            route @secured {
                proxy backend-b:8000
            }
        }
    }
}

I put this in front of the backend servers and it allows to listen on a single port, 4000, and route it to the right backend by peeking at the SNI value.

I was wondering if there is an option to eliminate the Caddy reverse proxy altogether and implement it via the frpc.ini or frps.ini.

Thanks!

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 @ofirc on GitHub (Nov 25, 2024). Original GitHub issue: https://github.com/fatedier/frp/issues/4558 ### Describe the feature request Is there a way to implement SNI-based routing, that is to demultiplex a single connection onto different targets? This is how I currently implement it with [Caddy](https://caddyserver.com/) and [Caddy L4 plugin](github.com/mholt/caddy-l4): ``` { admin :2019 debug layer4 { :4000 { @secure tls sni backend-a route @secure { proxy backend-a:6000 } @secured tls sni backend-b route @secured { proxy backend-b:8000 } } } } ``` I put this in front of the backend servers and it allows to listen on a single port, 4000, and route it to the right backend by peeking at the SNI value. I was wondering if there is an option to eliminate the Caddy reverse proxy altogether and implement it via the frpc.ini or frps.ini. Thanks! ### Describe alternatives you've considered _No response_ ### Affected area - [ ] Docs - [ ] Installation - [ ] Performance and Scalability - [ ] Security - [X] User Experience - [ ] Test and Release - [ ] Developer Infrastructure - [X] Client Plugin - [ ] Server Plugin - [X] Extensions - [ ] Others
gitea-mirror 2026-05-05 14:18:53 -06:00
Author
Owner

@fatedier commented on GitHub (Nov 26, 2024):

Currently, frp does not support SNI-based routing to demultiplex a single connection to different targets. However, this is a valuable suggestion, and we plan to consider it in future updates.

Thank you for sharing your use case!

<!-- gh-comment-id:2499582045 --> @fatedier commented on GitHub (Nov 26, 2024): Currently, frp does not support SNI-based routing to demultiplex a single connection to different targets. However, this is a valuable suggestion, and we plan to consider it in future updates. Thank you for sharing your use case!
Author
Owner

@ofirc commented on GitHub (Dec 5, 2024):

Hi @fatedier thanks for the prompt response, appreciate that and will stay tuned!

<!-- gh-comment-id:2518801635 --> @ofirc commented on GitHub (Dec 5, 2024): Hi @fatedier thanks for the prompt response, appreciate that and will stay tuned!
Author
Owner

@github-actions[bot] commented on GitHub (Dec 20, 2024):

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

<!-- gh-comment-id:2556019794 --> @github-actions[bot] commented on GitHub (Dec 20, 2024): Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.
Author
Owner

@gregoiregentil commented on GitHub (Oct 14, 2025):

+1. I'm also interested to get such SNI-based feature. I do it in haproxy:

use_backend bckd if { req_ssl_sni -i a.example.com }
backend bckd
mode tcp
server frps IP:PORT_a

I don't need to do it for https as there is the option "vhostHTTPSPort".

Such implementation would be extremely valuable because it would allow to get rid of Caddy and/or HaProxy.

<!-- gh-comment-id:3403708042 --> @gregoiregentil commented on GitHub (Oct 14, 2025): +1. I'm also interested to get such SNI-based feature. I do it in haproxy: use_backend bckd if { req_ssl_sni -i a.example.com } backend bckd mode tcp server frps IP:PORT_a I don't need to do it for https as there is the option "vhostHTTPSPort". Such implementation would be extremely valuable because it would allow to get rid of Caddy and/or HaProxy.
Author
Owner

@fatedier commented on GitHub (Oct 15, 2025):

frp already supports SNI-based routing through the vhostHTTPSPort feature. You can configure multiple proxies with different domains, and frps will route traffic based on the SNI field in the TLS Client Hello.

This achieves the same SNI demultiplexing as your Caddy L4 setup.

Note: The proxy type name "https" is somewhat misleading - it performs SNI-based TLS passthrough rather than HTTPS termination. The actual TLS handshake happens at your backend servers. This naming may be refined in future versions to better reflect its behavior.

<!-- gh-comment-id:3404431124 --> @fatedier commented on GitHub (Oct 15, 2025): frp already supports SNI-based routing through the vhostHTTPSPort feature. You can configure multiple proxies with different domains, and frps will route traffic based on the SNI field in the TLS Client Hello. This achieves the same SNI demultiplexing as your Caddy L4 setup. Note: The proxy type name "https" is somewhat misleading - it performs SNI-based TLS passthrough rather than HTTPS termination. The actual TLS handshake happens at your backend servers. This naming may be refined in future versions to better reflect its behavior.
Author
Owner

@gregoiregentil commented on GitHub (Oct 15, 2025):

But this is only for port 443? I want to reroute pop3s (995), imap3s (993) and smtp (465) based on custom domain sent by frpc. Is there another way to do that right now? I have to use haproxy with some specific port for each domain and have frpc to use that specific port.

<!-- gh-comment-id:3404558317 --> @gregoiregentil commented on GitHub (Oct 15, 2025): But this is only for port 443? I want to reroute pop3s (995), imap3s (993) and smtp (465) based on custom domain sent by frpc. Is there another way to do that right now? I have to use haproxy with some specific port for each domain and have frpc to use that specific port.
Author
Owner

@fatedier commented on GitHub (Oct 15, 2025):

Multiple ports are not supported for now; vhostHTTPSPort can only be configured with a single port.

<!-- gh-comment-id:3404565414 --> @fatedier commented on GitHub (Oct 15, 2025): Multiple ports are not supported for now; vhostHTTPSPort can only be configured with a single port.
Author
Owner

@gregoiregentil commented on GitHub (Oct 15, 2025):

I have just tried vhostHTTPSPort on port 995 to transmit POP3s and it seems working with a custom domain setup from frpc! I'm positively surprised that it works because it's not a https transmission though a SSL one.

If it really works for any port on vhostHTTPSPort (which seems to be the case), is there a way to have/patch/get multiples vhostHTTPSPort independently? It would really be extremely beneficial to me because I could get rid of haproxy and to have to put certificates on the server side hosting frps (for haproxy).

As it seems to be working, it's more to tweak/patch the config backend, and have mutliple threads/whatever to handle multiple vhostHTTPSPort. What I'm trying to say is that there is no need to develop a complete new feature...

<!-- gh-comment-id:3405243699 --> @gregoiregentil commented on GitHub (Oct 15, 2025): I have just tried vhostHTTPSPort on port 995 to transmit POP3s and it seems working with a custom domain setup from frpc! I'm positively surprised that it works because it's not a https transmission though a SSL one. If it really works for any port on vhostHTTPSPort (which seems to be the case), is there a way to have/patch/get multiples vhostHTTPSPort independently? It would really be extremely beneficial to me because I could get rid of haproxy and to have to put certificates on the server side hosting frps (for haproxy). As it seems to be working, it's more to tweak/patch the config backend, and have mutliple threads/whatever to handle multiple vhostHTTPSPort. What I'm trying to say is that there is no need to develop a complete new feature...
Author
Owner

@shellus commented on GitHub (Oct 15, 2025):

@gregoiregentil This is not possible at the current stage, but you can use docker to run multiple frps instances

<!-- gh-comment-id:3405256444 --> @shellus commented on GitHub (Oct 15, 2025): @gregoiregentil This is not possible at the current stage, but you can use docker to run multiple frps instances
Author
Owner

@shellus commented on GitHub (Oct 15, 2025):

It's worth mentioning that I have also mapped my local https service in some public frps services, which allows me not to upload my https certificate. This is great.

This indicates that the https in frp configuration is actually sni, which indeed misleads the vast majority of people.

<!-- gh-comment-id:3405263200 --> @shellus commented on GitHub (Oct 15, 2025): It's worth mentioning that I have also mapped my local https service in some public frps services, which allows me not to upload my https certificate. This is great. This indicates that the https in frp configuration is actually sni, which indeed misleads the vast majority of people.
Author
Owner

@fatedier commented on GitHub (Oct 15, 2025):

As it seems to be working, it's more to tweak/patch the config backend, and have mutliple threads/whatever to handle multiple vhostHTTPSPort. What I'm trying to say is that there is no need to develop a complete new feature...

Functionally speaking, yes. However, from the perspective of the current overall architecture design, it is not a feature that can be added easily.
I can only say that it will be supported in the future, but not in the short term.

<!-- gh-comment-id:3405272478 --> @fatedier commented on GitHub (Oct 15, 2025): > As it seems to be working, it's more to tweak/patch the config backend, and have mutliple threads/whatever to handle multiple vhostHTTPSPort. What I'm trying to say is that there is no need to develop a complete new feature... Functionally speaking, yes. However, from the perspective of the current overall architecture design, it is not a feature that can be added easily. I can only say that it will be supported in the future, but not in the short term.
Author
Owner

@gregoiregentil commented on GitHub (Oct 15, 2025):

@shellus I'm not using docker and my experience is that frpc can connect only to one instance of frps at the same time.

<!-- gh-comment-id:3405318323 --> @gregoiregentil commented on GitHub (Oct 15, 2025): @shellus I'm not using docker and my experience is that frpc can connect only to one instance of frps at the same time.
Author
Owner

@gregoiregentil commented on GitHub (Oct 15, 2025):

I completely understand the whole story "not simple, not enough time in the short term". I'm almost willing to patch. Would you share some guidance what would be the very strict minimum (even hard-coding some port numbers) to modify? Or is that too complicated? I'm controlling both ends frps and frpc on my systems.

<!-- gh-comment-id:3405340375 --> @gregoiregentil commented on GitHub (Oct 15, 2025): I completely understand the whole story "not simple, not enough time in the short term". I'm almost willing to patch. Would you share some guidance what would be the very strict minimum (even hard-coding some port numbers) to modify? Or is that too complicated? I'm controlling both ends frps and frpc on my systems.
Author
Owner

@shellus commented on GitHub (Oct 15, 2025):

@shellus I'm not using docker and my experience is that frpc can connect only to one instance of frps at the same time.

I think you've already touched it. Yes, many parts of the system are designed to be unique. As you said, your single frpc can only connect to a single frps, and the same goes for the https port.

So I suggest you, like me, use docker compose to use multiple FRPCS and multiple frps

Trust me, it is very difficult to modify frp itself, but the way to switch and use it is very simple

<!-- gh-comment-id:3405357523 --> @shellus commented on GitHub (Oct 15, 2025): > [@shellus](https://github.com/shellus) I'm not using docker and my experience is that frpc can connect only to one instance of frps at the same time. I think you've already touched it. Yes, many parts of the system are designed to be unique. As you said, your single frpc can only connect to a single frps, and the same goes for the https port. So I suggest you, like me, use docker compose to use multiple FRPCS and multiple frps Trust me, it is very difficult to modify frp itself, but the way to switch and use it is very simple
Author
Owner

@gregoiregentil commented on GitHub (Oct 15, 2025):

Unfortunately, docker is not an option at all (too long to explain why...) If patching isn't possible, I would stay with haproxy. At least, it's on server side only.

<!-- gh-comment-id:3405372721 --> @gregoiregentil commented on GitHub (Oct 15, 2025): Unfortunately, docker is not an option at all (too long to explain why...) If patching isn't possible, I would stay with haproxy. At least, it's on server side only.
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#3604
No description provided.