This is what i want to reach with envoy as proxy for https traffic:
I got the certificate (p12) from the java developer to load it with envoy, then make developer happy by hitting envoy without certificate (on port 8080). Check diagram above also.
In order to do that this is my envoy.yaml
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: app
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: api-example-https
http_filters:
- name: envoy.filters.http.router
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: api-example-https
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: api-example-https
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api.example.com
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_certificates:
- pkcs12:
filename: /etc/cert.p12
Unfortunately, i am getting this error:
[2022-11-01 22:17:48.788][1][critical][main] [source/server/server.cc:117] error initializing configuration '/etc/envoy.yaml': Failed to load pkcs12 from /etc/cert.p12
[2022-11-01 22:17:48.788][1][info][main] [source/server/server.cc:961] exiting
Failed to load pkcs12 from /etc/cert.p12
What am i missing ? 3 hours troubleshooting but no way :(
It turns out that the certificate has to be used alongside a password.
And i verified that by using curl on the external service directly:
curl --cert-type P12 --cert 'cert.p12:MyPass' https://api.example.com
This means that envoy.yaml must include the configuration of a password.
Hence, the config file should looks like:
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: app
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: api-example-https
http_filters:
- name: envoy.filters.http.router
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: api-example-https
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: api-example-https
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api.example.com
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_certificates:
- pkcs12:
filename: /etc/cert.p1
password:
inline_string: MyPass ### 🔴🔴 Fixed By adding this 🔴🔴
REF: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlscertificate-pkcs12
Use password to specify the password to unprotect the PKCS12 data, if necessary.
I'm using the grpc_http1_reverse_bridge_filter from Envoy to convert my gRPC requests to HTTP1.1. The HTTP1.1 requests will be served by Hoverfly which will have simulations uploaded beforehand.
gRPC ---> Envoy (grpc ~~ HTTPS) ---> Hoverfly [HTTP(S)]
But, it doesn't seem like Envoy is correctly translating my request to HTTP1.1. From the server-proxy logs I see:
invalid http2: Remote peer returned unexpected data while we expected SETTINGS frame. Perhaps, peer does not support HTTP/2 properly
Is there something I'm missing in my Envoy config?
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9901
layered_runtime:
layers:
- name: disable_apple_dns
static_layer:
envoy.restart_features.use_apple_api_for_dns_lookups: false
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 8811
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"#type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
route_config:
name: local_route
virtual_hosts:
- name: local_service #backend
domains:
- "*"
routes:
- match:
prefix: "/"
#grpc: {}
route:
host_rewrite_literal: hoverfly
cluster: backend_http_service_hoverfly
timeout: 60.00s
http_filters: # use the reverse bridge filter
- name: envoy.filters.http.grpc_http1_reverse_bridge
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfig
content_type: application/json #application/grpc+proto
withhold_grpc_frames: true
- name: envoy.filters.http.router
clusters:
- name: backend_http_service_hoverfly
type: STRICT_DNS
lb_policy: ROUND_ROBIN
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"#type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: backend_http_service_hoverfly
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: # Re-route to hoverfly (this is docker alias)
address: hoverfly #127.0.0.1 #kv-backend-service
port_value: 8500 #8081
I have an nginx.conf with basic auth like this:
location / {
auth_basic "Prometheus";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:9090/;
}
Is it possible to create an basic auth config for envoy like in nginx?
This is my envoy.yaml:
admin:
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 9901
static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: service_envoyproxy_io
http_filters:
- name: envoy.filters.http.router
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_2
tls_maximum_protocol_version: TLSv1_3
cipher_suites: "[ECDHE-RSA-AES256-GCM-SHA384|ECDHE-RSA-AES128-GCM-SHA256]"
tls_certificates:
- certificate_chain: { filename: "/etc/ssl/prometheus.crt" }
private_key: { filename: "/etc/ssl/prometheus.key" }
clusters:
- name: service_envoyproxy_io
connect_timeout: 30s
type: STATIC
# Comment out the following line to test on v6 networks
# dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_envoyproxy_io
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 0.0.0.0
port_value: 9090
I found basic_auth module in envoy-Doku: Envoy Basic Auth Module, but the strings are hardcoded....not the best way in my opinion!
Many thanks for help!
I have a GRPC Web client and a GRPC Server and I am using envoy proxy from the conversion of HTTP 1.1 to HTTP2.
My server creation Logic uses TLS. The code is as follows:
var opts []grpc.ServerOption
creds, err := credentials.NewServerTLSFromFile("cert/server.crt", "cert/server.key")
if err != nil {
log.Fatalf("Failed to generate credentials %v", err)
}
opts = []grpc.ServerOption{grpc.Creds(creds)}
server := grpc.NewServer(opts...)
I am calling the From my react client as follows:
const client = new LiveClient('http://localhost:8080')
const request = new GetLiveRequest()
request.setApi(1)
request.setTrackkey(trackKey)
// on success response
const stream = client.getLive(request, {})
stream.on('data', response => {
console.log(response);
}
The envoy.yaml is as follows:
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: greeter_service
max_grpc_timeout: 0s
cors:
allow_origin:
- "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.grpc_web
- name: envoy.cors
- name: envoy.router
tls_context:
common_tls_context:
alpn_protocols: "h2"
tls_certificates:
- certificate_chain:
filename: "/etc/server.crt"
private_key:
filename: "/etc/server.key"
clusters:
- name: greeter_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts: [{ socket_address: { address: app, port_value: 3000 }}]
The Dockerfile for envoy is as follows:
FROM envoyproxy/envoy:36f39c746eb7d03b762099b206403935b11972d8
COPY ./envoy.yaml /etc/envoy/envoy.yaml
ADD ./cert/server.crt /etc/server.crt
ADD ./cert/server.key /etc/server.key
ADD ./cert/server.csr /etc/server.csr
WORKDIR /etc/envoy
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml
I am getting the following error when:
{code: 2, message: "Http response at 400 or 500 level"}
But when I remove the SSL authentication from backend server. It is working fine. I have also created a grpc client and TLS is working fine with it.
I am unable to find what is going wrong in my envoy configuration for TLS.
On further investigation in am getting following in envoy logs.
TLS error: 268435703:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER
The TLS certificates are working fine if I use it with envoy by directly using a GRPC client.
Your backend is already talking HTTPS through. So you don't need to configure tls_context in the envoy's config. And you have to use tcp_proxy instead of http_connection_manager Here. You also need to configure transport_socket for the proxy of your TLS backend Here.
static_resources:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#extensions-filters-network-http-connection-manager-v3-httpconnectionmanager
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
access_log:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/access_loggers/file/v3/file.proto
#
# You can also configure this extension with the qualified
# name envoy.access_loggers.http_grpc
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/access_loggers/grpc/v3/als.proto
- name: envoy.access_loggers.file
typed_config:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/access_loggers/file/v3/file.proto#extensions-access-loggers-file-v3-fileaccesslog
"#type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
# Console output
path: /dev/stdout
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: /
grpc:
route:
cluster: greeter_service
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
# custom-header-1 is just an example. the grpc-web
# repository was missing grpc-status-details-bin header
# which used in a richer error model.
# https://grpc.io/docs/guides/error/#richer-error-model
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,grpc-status-details-bin,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout,authorization
expose_headers: grpc-status-details-bin,grpc-status,grpc-message,authorization
max_age: "1728000"
http_filters:
- name: envoy.filters.http.grpc_web
# This line is optional, but adds clarity to the configuration.
typed_config:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/filters/http/grpc_web/v3/grpc_web.proto
"#type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.cors
typed_config:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/filters/http/cors/v3/cors.proto
"#type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/filters/http/router/v3/router.proto
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/extensions/transport_sockets/tls/v3/tls.proto#extensions-transport-sockets-tls-v3-downstreamtlscontext
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain:
# Certificate must be PEM-encoded
filename: /etc/fullchain.pem
private_key:
filename: /etc/privkey.pem
clusters:
# https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster
- name: greeter_service
type: LOGICAL_DNS
connect_timeout: 0.25s
lb_policy: round_robin
load_assignment:
cluster_name: greeter_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: app
port_value: 3000
http2_protocol_options: {} # Force HTTP/2
# Your grpc server communicates over TLS. You must configure the transport
# socket. If you care about the overhead, you should configure the grpc
# server to listen without TLS. If you need to listen to grpc-web and grpc
# over HTTP/2 both you can also proxy your TCP traffic with the envoy.
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
Have you tried calling HTTPS from client?
const client = new LiveClient('https://localhost:8080')
Without this I'm getting Http response at 400 or 500 level as well.
I am trying to call from vue app via grpc to the go app as the follows:
Between them, it is an envoy proxy and is neccessary as described here https://github.com/grpc/grpc-web#2-run-the-server-and-proxy. The envoy proxy is running in the docker container, the vue and go app on localhost. The problem is, the vue app can not reach the go app, because I think, the envoy is running on different network than the go app.
Envoy is configured as follows:
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 9000 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: identity_service
max_grpc_timeout: 0s
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.grpc_web
- name: envoy.cors
- name: envoy.router
clusters:
- name: identity_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts: [{ socket_address: { address: 0.0.0.0, port_value: 9090 }}]
What is wrong with the envoy configuration?