mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-10 07:37:33 +02:00
add support for TCP routes (#1695)
This commit is contained in:
parent
64816720c8
commit
ad828c6e84
7 changed files with 86 additions and 13 deletions
|
@ -153,7 +153,7 @@ allowed_route_regex(input_url_obj, policy) {
|
|||
|
||||
parse_url(str) = { "scheme": scheme, "host": host, "path": path } {
|
||||
[_, scheme, host, rawpath] = regex.find_all_string_submatch_n(
|
||||
`(?:(http[s]?)://)?([^/]+)([^?#]*)`,
|
||||
`(?:((?:tcp[+])?http[s]?)://)?([^/]+)([^?#]*)`,
|
||||
str, 1)[0]
|
||||
path = normalize_url_path(rawpath)
|
||||
}
|
||||
|
|
|
@ -301,6 +301,13 @@ test_parse_url {
|
|||
url.path == "/some/path"
|
||||
}
|
||||
|
||||
test_parse_tcp_url {
|
||||
url := parse_url("tcp+http://example.com/some/path?qs")
|
||||
url.scheme == "tcp+http"
|
||||
url.host == "example.com"
|
||||
url.path == "/some/path"
|
||||
}
|
||||
|
||||
test_allowed_route_source {
|
||||
allowed_route("http://example.com", {"source": "example.com"})
|
||||
allowed_route("http://example.com", {"source": "http://example.com"})
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -257,7 +257,7 @@ func (p *Policy) Validate() error {
|
|||
}
|
||||
|
||||
// Make sure there's no path set on the from url
|
||||
if !(source.Path == "" || source.Path == "/") {
|
||||
if (source.Scheme == "http" || source.Scheme == "https") && !(source.Path == "" || source.Path == "/") {
|
||||
return fmt.Errorf("config: policy source url (%s) contains a path, but it should be set using the path field instead",
|
||||
source.String())
|
||||
}
|
||||
|
|
|
@ -192,20 +192,29 @@ func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_r
|
|||
routeTimeout := getRouteTimeout(options, &policy)
|
||||
prefixRewrite, regexRewrite := getRewriteOptions(&policy)
|
||||
|
||||
upgradeConfigs := []*envoy_config_route_v3.RouteAction_UpgradeConfig{
|
||||
{
|
||||
UpgradeType: "websocket",
|
||||
Enabled: &wrappers.BoolValue{Value: policy.AllowWebsockets},
|
||||
},
|
||||
{
|
||||
UpgradeType: "spdy/3.1",
|
||||
Enabled: &wrappers.BoolValue{Value: policy.AllowSPDY},
|
||||
},
|
||||
}
|
||||
if urlutil.IsTCP(policy.Source.URL) {
|
||||
upgradeConfigs = append(upgradeConfigs, &envoy_config_route_v3.RouteAction_UpgradeConfig{
|
||||
UpgradeType: "CONNECT",
|
||||
Enabled: &wrappers.BoolValue{Value: true},
|
||||
ConnectConfig: &envoy_config_route_v3.RouteAction_UpgradeConfig_ConnectConfig{},
|
||||
})
|
||||
}
|
||||
|
||||
routeAction := &envoy_config_route_v3.RouteAction{
|
||||
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
|
||||
Cluster: clusterName,
|
||||
},
|
||||
UpgradeConfigs: []*envoy_config_route_v3.RouteAction_UpgradeConfig{
|
||||
{
|
||||
UpgradeType: "websocket",
|
||||
Enabled: &wrappers.BoolValue{Value: policy.AllowWebsockets},
|
||||
},
|
||||
{
|
||||
UpgradeType: "spdy/3.1",
|
||||
Enabled: &wrappers.BoolValue{Value: policy.AllowSPDY},
|
||||
},
|
||||
},
|
||||
UpgradeConfigs: upgradeConfigs,
|
||||
HostRewriteSpecifier: &envoy_config_route_v3.RouteAction_AutoHostRewrite{
|
||||
AutoHostRewrite: &wrappers.BoolValue{Value: !policy.PreserveHostHeader},
|
||||
},
|
||||
|
@ -271,6 +280,10 @@ func toEnvoyHeaders(headers map[string]string) []*envoy_config_core_v3.HeaderVal
|
|||
func mkRouteMatch(policy *config.Policy) *envoy_config_route_v3.RouteMatch {
|
||||
match := &envoy_config_route_v3.RouteMatch{}
|
||||
switch {
|
||||
case urlutil.IsTCP(policy.Source.URL):
|
||||
match.PathSpecifier = &envoy_config_route_v3.RouteMatch_ConnectMatcher_{
|
||||
ConnectMatcher: &envoy_config_route_v3.RouteMatch_ConnectMatcher{},
|
||||
}
|
||||
case policy.Regex != "":
|
||||
match.PathSpecifier = &envoy_config_route_v3.RouteMatch_SafeRegex{
|
||||
SafeRegex: &envoy_type_matcher_v3.RegexMatcher{
|
||||
|
|
|
@ -464,6 +464,50 @@ func Test_buildPolicyRoutes(t *testing.T) {
|
|||
}
|
||||
]
|
||||
`, routes)
|
||||
|
||||
t.Run("tcp", func(t *testing.T) {
|
||||
routes = buildPolicyRoutes(&config.Options{
|
||||
CookieName: "pomerium",
|
||||
DefaultUpstreamTimeout: time.Second * 3,
|
||||
Policies: []config.Policy{
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("tcp+https://example.com:22")},
|
||||
PassIdentityHeaders: true,
|
||||
},
|
||||
},
|
||||
}, "example.com:22")
|
||||
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
[
|
||||
{
|
||||
"name": "policy-0",
|
||||
"match": {
|
||||
"connectMatcher": {}
|
||||
},
|
||||
"metadata": {
|
||||
"filterMetadata": {
|
||||
"envoy.filters.http.lua": {
|
||||
"remove_impersonate_headers": false,
|
||||
"remove_pomerium_authorization": true,
|
||||
"remove_pomerium_cookie": "pomerium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"route": {
|
||||
"autoHostRewrite": true,
|
||||
"cluster": "policy-9",
|
||||
"timeout": "3s",
|
||||
"upgradeConfigs": [
|
||||
{ "enabled": false, "upgradeType": "websocket"},
|
||||
{ "enabled": false, "upgradeType": "spdy/3.1"},
|
||||
{ "enabled": true, "upgradeType": "CONNECT", "connectConfig": {} }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
`, routes)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// Make sure default Headers are set for response.
|
||||
|
|
|
@ -84,6 +84,10 @@ func GetAbsoluteURL(r *http.Request) *url.URL {
|
|||
// For standard HTTP (80)/HTTPS (443) ports, it returns `example.com` and `example.com:<port>`.
|
||||
// Otherwise, return the URL.Host value.
|
||||
func GetDomainsForURL(u *url.URL) []string {
|
||||
if IsTCP(u) {
|
||||
return []string{u.Host}
|
||||
}
|
||||
|
||||
var defaultPort string
|
||||
if u.Scheme == "http" {
|
||||
defaultPort = "80"
|
||||
|
@ -102,6 +106,11 @@ func GetDomainsForURL(u *url.URL) []string {
|
|||
return []string{u.Hostname(), net.JoinHostPort(u.Hostname(), defaultPort)}
|
||||
}
|
||||
|
||||
// IsTCP returns whether or not the given URL is for TCP via HTTP Connect.
|
||||
func IsTCP(u *url.URL) bool {
|
||||
return u.Scheme == "tcp+http" || u.Scheme == "tcp+https"
|
||||
}
|
||||
|
||||
// ParseEnvoyQueryParams returns a new URL with queryparams parsed from envoy format.
|
||||
func ParseEnvoyQueryParams(u *url.URL) *url.URL {
|
||||
nu := &url.URL{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue