Skip to content

Commit

Permalink
Add Envoy proxy support to postgres and all-in-one images
Browse files Browse the repository at this point in the history
  • Loading branch information
thebengeu committed Dec 1, 2023
1 parent fa1c67c commit cdae803
Show file tree
Hide file tree
Showing 18 changed files with 528 additions and 7 deletions.
1 change: 1 addition & 0 deletions ansible/files/adminapi.sudoers.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Cmnd_Alias KONG = /bin/systemctl start envoy.service, /bin/systemctl stop envoy.service, /bin/systemctl restart envoy.service, /bin/systemctl disable envoy.service, /bin/systemctl enable envoy.service, /bin/systemctl reload envoy.service
Cmnd_Alias KONG = /bin/systemctl start kong.service, /bin/systemctl stop kong.service, /bin/systemctl restart kong.service, /bin/systemctl disable kong.service, /bin/systemctl enable kong.service, /bin/systemctl reload kong.service
Cmnd_Alias POSTGREST = /bin/systemctl start postgrest.service, /bin/systemctl stop postgrest.service, /bin/systemctl restart postgrest.service, /bin/systemctl disable postgrest.service, /bin/systemctl enable postgrest.service
Cmnd_Alias GOTRUE = /bin/systemctl start gotrue.service, /bin/systemctl stop gotrue.service, /bin/systemctl restart gotrue.service, /bin/systemctl disable gotrue.service, /bin/systemctl enable gotrue.service
Expand Down
24 changes: 24 additions & 0 deletions ansible/files/envoy.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[Unit]
Description=Envoy
After=postgrest.service gotrue.service adminapi.service
Wants=postgrest.service gotrue.service adminapi.service
Conflicts=kong.service

[Service]
Type=simple
ExecStart=/opt/envoy-hot-restarter.py /opt/start-envoy.sh
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
User=envoy
Slice=services.slice
Restart=always
RestartSec=3
LimitNOFILE=100000

# The envoy user is unpriviledged and thus not permited to bind on ports < 1024
# Via systemd we grant the process a set of priviledges to bind to 80/443
# See http://archive.vn/36zJU
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
12 changes: 12 additions & 0 deletions ansible/files/envoy_config/basic_auth.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function envoy_on_request(request_handle)
local authorization = request_handle:headers():get("authorization")

if authorization and authorization:find("^[Bb][Aa][Ss][Ii][Cc] " .. request_handle:metadata():get("credentials")) then
return
end

request_handle:respond({
[":status"] = "401",
["WWW-Authenticate"] = "Basic realm=\"Unknown\""
}, "Unauthorized")
end
51 changes: 51 additions & 0 deletions ansible/files/envoy_config/cds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
resources:
- '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
name: admin-api
load_assignment:
cluster_name: admin-api
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8085
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
- '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
name: gotrue
load_assignment:
cluster_name: gotrue
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 9999
- '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
name: postgrest
load_assignment:
cluster_name: postgrest
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 3000
- '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
name: postgrest-admin
load_assignment:
cluster_name: postgrest-admin
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 3001

23 changes: 23 additions & 0 deletions ansible/files/envoy_config/envoy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dynamic_resources:
cds_config:
path_config_source:
path: /etc/envoy/cds.yaml
resource_api_version: V3
lds_config:
path_config_source:
path: /etc/envoy/lds.yaml
resource_api_version: V3
node:
cluster: cluster_0
id: node_0
overload_manager:
resource_monitors:
- name: envoy.resource_monitors.global_downstream_max_connections
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
max_active_downstream_connections: 500000
stats_config:
stats_matcher:
reject_all: true

265 changes: 265 additions & 0 deletions ansible/files/envoy_config/lds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
resources:
- '@type': type.googleapis.com/envoy.config.listener.v3.Listener
name: http_listener
address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters: &ref_1
- name: envoy.filters.network.http_connection_manager
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
generate_request_id: false
http_filters:
- name: envoy.filters.http.cors
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.rbac
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: DENY
policies:
api_key_missing:
permissions:
- any: true
principals:
- not_id:
or_ids:
ids:
- header:
name: apikey
present_match: true
- header:
name: ':path'
string_match:
contains: apikey=
api_key_not_valid:
permissions:
- any: true
principals:
- not_id:
or_ids:
ids:
- header:
name: apikey
string_match:
exact: anon_key
- header:
name: apikey
string_match:
exact: service_key
- header:
name: apikey
string_match:
exact: supabase_admin_key
- header:
name: ':path'
string_match:
contains: apikey=anon_key
- header:
name: ':path'
string_match:
contains: apikey=service_key
- header:
name: ':path'
string_match:
contains: apikey=supabase_admin_key
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
source_codes:
basic_auth:
filename: /etc/envoy/basic_auth.lua
remove_apikey_query_parameter:
filename: /etc/envoy/remove_apikey_query_parameter.lua
- name: envoy.filters.http.router
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
dynamic_stats: false
local_reply_config:
mappers:
- filter:
and_filter:
filters:
- status_code_filter:
comparison:
value:
default_value: 403
runtime_key: unused
- header_filter:
header:
name: ':path'
string_match:
prefix: /metrics/aggregated
invert_match: true
status_code: 401
body_format_override:
json_format:
message: >-
`apikey` request header or query parameter is either
missing or invalid. Double check your Supabase `anon`
or `service_role` API key.
hint: '%RESPONSE_CODE_DETAILS%'
json_format_options:
sort_properties: false
route_config:
name: route_config_0
virtual_hosts:
- name: virtual_host_0
domains:
- '*'
typed_per_filter_config:
envoy.filters.http.cors:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy
allow_origin_string_match:
- safe_regex:
regex: \*
allow_methods: GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT
allow_headers: apikey,authorization,x-client-info
max_age: '3600'
routes:
- match:
safe_regex:
regex: >-
/auth/v1/(verify|callback|authorize|sso/saml/(acs|metadata|slo))
route:
cluster: gotrue
regex_rewrite:
pattern:
regex: ^/auth/v1
substitution: ''
retry_policy:
num_retries: 3
retry_on: 5xx
typed_per_filter_config:
envoy.filters.http.rbac: &ref_0
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
- match:
prefix: /auth/v1/
route:
cluster: gotrue
prefix_rewrite: /
- match:
prefix: /rest/v1/
query_parameters:
- name: apikey
present_match: true
request_headers_to_remove:
- apikey
route:
cluster: postgrest
prefix_rewrite: /
typed_per_filter_config:
envoy.filters.http.lua:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
name: remove_apikey_query_parameter
- match:
prefix: /rest/v1/
request_headers_to_remove:
- apikey
route:
cluster: postgrest
prefix_rewrite: /
- match:
prefix: /rest-admin/v1/
query_parameters:
- name: apikey
present_match: true
request_headers_to_remove:
- apikey
route:
cluster: postgrest-admin
prefix_rewrite: /
typed_per_filter_config:
envoy.filters.http.lua:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
name: remove_apikey_query_parameter
- match:
prefix: /rest-admin/v1/
request_headers_to_remove:
- apikey
route:
cluster: postgrest-admin
prefix_rewrite: /
- match:
path: /graphql/v1
request_headers_to_add:
header:
key: Content-Profile
value: graphql_public
route:
cluster: postgrest
prefix_rewrite: /rpc/graphql
- match:
prefix: /admin/v1/
route:
cluster: admin-api
prefix_rewrite: /
- match:
prefix: /customer/v1/privileged/
route:
cluster: admin-api
prefix_rewrite: /privileged/
typed_per_filter_config:
envoy.filters.http.lua:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
name: basic_auth
envoy.filters.http.rbac: *ref_0
metadata:
filter_metadata:
envoy.filters.http.lua:
credentials: c2VydmljZV9yb2xlOnNlcnZpY2Vfa2V5
- match:
prefix: /metrics/aggregated
route:
cluster: admin-api
prefix_rewrite: /supabase-internal/metrics
typed_per_filter_config:
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: DENY
policies:
not_private_ip:
permissions:
- any: true
principals:
- not_id:
direct_remote_ip:
address_prefix: 10.0.0.0
prefix_len: 8
stat_prefix: ingress_http
- '@type': type.googleapis.com/envoy.config.listener.v3.Listener
name: https_listener
address:
socket_address:
address: 0.0.0.0
port_value: 443
filter_chains:
- filters: *ref_1
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain:
filename: /etc/envoy/fullChain.pem
private_key:
filename: /etc/envoy/privKey.pem

5 changes: 5 additions & 0 deletions ansible/files/envoy_config/remove_apikey_query_parameter.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function envoy_on_request(request_handle)
local path = request_handle:headers():get(":path")

request_handle:headers():replace(":path", path:gsub("([&?])apikey=[^&]+&?", "%1"):gsub("&$", ""))
end
1 change: 1 addition & 0 deletions ansible/files/kong_config/kong.service.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Description=Kong server
After=postgrest.service gotrue.service adminapi.service
Wants=postgrest.service gotrue.service adminapi.service
Conflicts=envoy.service

[Service]
Type=forking
Expand Down
Loading

0 comments on commit cdae803

Please sign in to comment.