Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use layer4 as a listener wrapper OR pipe layer4 connection to http FOR ocserv multiplexing #6439

Closed
vnxme opened this issue Jul 5, 2024 · 5 comments
Labels
help wanted 🆘 Extra attention is needed question ❔ Help is being requested

Comments

@vnxme
Copy link
Contributor

vnxme commented Jul 5, 2024

Hi,

My intention is to multiplex ocserv (OpenConnect VPN server, it could be treated as a TLS-capable non-HTTP application) and caddy on a single port. What I would like to achieve is the following logic: caddy listens on :443, if it receives a TLS connection with SNI ocserv.example.com, it passes it through without terminating TLS to another host where ocserv runs, otherwise it terminates TLS on its own and serves example.com and its subdomains other than ocserv.example.com. An additional point is I would like to use caddyfile adapter to configure caddy for both layer4 and http/tls, but I understand that's another issue.

It's possible (as of caddy@v2.8.4 and caddy-l4@ca3e2f3) to make the layer4 app listen on :443 and the http app listen on another port (e.g. :444), and proxy non-ocserv.example.com from :443 to :444. For reference, see below the relevant part of autosave.json. However, given both layer4 and http apps are inside caddy, I would like to find a way to do the same more efficiently without proxying.

autosave.json, layer4 proxy, working
"layer4": {
    "servers": {
  	  "example": {
  		  "listen": [":443"],
  		  "routes": [
  			  {
  				  "match": [
  					  {
  						  "tls": {"sni": ["ocserv.example.com"]}
  					  }
  				  ],
  				  "handle": [
  					  {
  						  "handler": "proxy",
  						  "upstreams": [
  							  {"dial": ["ocserv.address.local:443"]}
  						  ]
  					  }
  				  ]
  			  },
  			  {
  				  "match": [
  					  {
  						  "not": [
  							  {
  								  "tls": {"sni": ["ocserv.example.com"]}
  							  }
  						  ]
  					  }
  				  ],
  				  "handle": [
  					  {
  						  "handler": "proxy",
  						  "upstreams": [
  							  {"dial": ["localhost:444"]}
  						  ]
  					  }
  				  ]
  			  }
  		  ]
  	  }
    }
},

As far as I understand, this is a topic which has been discussed a few times so far, and there are a number of relevant issues/PRs:

Thus, my question is whether there is any way to make ocserv multiplexing work without proxying other subdomains (any mistake in layer4 listener wrapper config above?) or implement such a functionality in caddy and/or caddy-l4?

Regards,

@vnxme
Copy link
Contributor Author

vnxme commented Jul 5, 2024

Seems like there is a related PR battle between mholt/caddy-l4#208 and mholt/caddy-l4#210. Hope they will soon find a mutually acceptable solution to restore the old behaviour (fallback next handler), and the layer4 listener wrapper config above will probably work.

Nevertheless, it would be great if #5040 could be finalised and some documentation/examples provided. Generally it might be an even better solution than listen wrappers.

@mholt mholt added the question ❔ Help is being requested label Jul 5, 2024
@mholt
Copy link
Member

mholt commented Jul 5, 2024

Yeah, layer4 plugin is currently undergoing some revisions.

To serve TLS without terminating it, you'll need the layer4 module. Caddy's HTTP server can only terminate TLS. Generally speaking, any and all protocol multiplexing will need the layer4 module.

@vnxme
Copy link
Contributor Author

vnxme commented Jul 5, 2024

Following @ydylla's config samples, namely the one named "listener-wrapper-matcher-with-no-handler.json" (see mholt/caddy-l4#209), I've managed to make my layer4 listener wrapper config work using the suggested workaround.

autosave.json, layer4 listener wrapper, working
"listener_wrappers": [
  {
  	"wrapper": "layer4",
  	"routes": [
  		{
  			"match": [
  				{
  					"tls": {"sni": ["ocserv.example.com"]}
  				}
  			],
  			"handle": [
  				{
  					"handler": "proxy",
  					"upstreams": [
  						{"dial": ["ocserv.address.local:443"]}
  					]
  				}
  			]
  		},
  		{
  			"match": [
  				{
  					"not": [
  						{
  							"tls": {"sni": ["ocserv.example.com"]}
  						}
  					]
  				}
  			]
  		}
  	]
  },
  {
  	"wrapper": "tls"
  }
],

@vnxme
Copy link
Contributor Author

vnxme commented Jul 5, 2024

@mholt Thank you for responding. The layer4 module is absolutely amazing! Really appreciate your time and effort spent on it.

Do you have any plans to merge it into caddy core? Or at least make it configurable the way caddy works? I mean the caddyfile adapter.

And what do you actually think about #5040?

@mholt
Copy link
Member

mholt commented Jul 5, 2024

Do you have any plans to merge it into caddy core? Or at least make it configurable the way caddy works? I mean the caddyfile adapter.

We've talked about it. We need to resolve some of the glaring issues with it first, obviously. But it's a good candidate as it seems to be getting quite popular / in higher demand as time goes on. It'll be a lot of work, especially that Caddyfile support.

And what do you actually think about #5040?

I like that change still, but I have yet to find time to test it end-to-end. If someone who is savvy with Go wants to try wiring up the Layer4 module to support the exported Pipe() method, then we can probably make some progress on it sooner. I've just been very behind 😅

@mholt mholt added the help wanted 🆘 Extra attention is needed label Jul 5, 2024
@vnxme vnxme closed this as completed Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted 🆘 Extra attention is needed question ❔ Help is being requested
Projects
None yet
Development

No branches or pull requests

2 participants