Envoy proxy server : how to preserve socket options? - istio

So, I need to set DSCP byte for HTTP/2 traffic on client side, which is an IP header. This is easily done using setsockopt IP_TOS on the socket sending the HTTP POST request.
But, we are using istio in our project, hence all traffic goes through envoy proxy, and I verified that the envoy proxy is stripping away all IP headers when proxying.
Ie, client sends http post to envoy with DSCP set -> envoy sends HTTP post to the actual recipient, but all IP headers set by setsockopt is gone.
Looking at envoy documentation, it seems that the solution is to use a 'tcp filter', and envoy already has a selection of filters inbuilt: https://github.com/envoyproxy/envoy/tree/main/source/extensions/transport_sockets
But, sadly, the documentation is quite cryptic. But this must be a common requirement, so does anyone know how to get envoy to preserve IP headers set by setsockopt?
Thank you for any advice!

I think you can try config CLUSTER’s upstream_bind_config by using istio envoyfilter API, the related doc are here. I did not try it, but seems it is what you need.
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto.html?highlight=bindconfig
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#envoy-v3-api-msg-config-core-v3-bindconfig
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/socket_option.proto#envoy-v3-api-msg-config-core-v3-socketoption

Related

wso2 - how to get TLS certificate details in sequence

In my integration scenario I need to veryfy some data of TLS certificate.
Is there a way to get details of TLS certificate (eg. subject name) in sequence?
No, you can do that in wso2. In any of wso2 scopes (Axis2/Axis2-Client/Transport/Operation/Synapse), you don't have access / information to used TLS certificate in request.
Some workaround, could be use reverse proxy, for example HAProxy to add information in request header, like described here: SSL Client Certificate Information in HTTP Headers and read in sequence from header. In nginix I belive that is also possible.
Last way, I think, is to modify source code, or implement own TransportReceiver for https requests.

Why forwarding a Host Header from the previous request with mTLS in Istio returns 500?

So I had a working mTLS service mesh until one of the services got updated with some header manipulation logic. This logic was getting the headers from the request the service got, and then adding those headers to the request this service was making to another one.
With this logic in place, mTLS was broken between this service and the next one, and if I activate PERMISSIVE mode, connection works as usual.
So then I went to this service’s container and did a curl request to the next service but without the Host Header and the request came through.
So, same request, just that without Host header mtls works, and with host header it doesn’t.
I would like to know the reason why this happens. Is it related with mTLS and how both services are trusting each other?
Thanks
I think that the best way to approach this issue would be to analyze the differences between services' versions before and after the header manipulation logic.
In order to dump headers' request you can use the helper httbin server from Istio official doc here.
You can find more info regarding how to use it here.
Please let me know if that helped.

can proxy server set cookie?

can the proxy server intercept my https request and set cookies before actually sending the request?
I'm going a GET on an url from chrome browser. In the development tools, under "Network", I noticed that the first request, the one that I made, has cookies set. but I did not set any cookies.
any thoughts?
No it can't. To proxy HTTPS requests your browser issues HTTP CONNECT command (https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT). Proxy then creates a tunnel between the browser and a target server.
A conventional proxy can neither view nor manipulate a TLS-encrypted data stream, so a CONNECT request simply asks the proxy to open a pipe between the client and server. The proxy here is just a facilitator - it blindly forwards data in both directions without knowing anything about the contents. The negotiation of the TLS connection happens over this pipe, and the subsequent flow of requests and responses are completely opaque to the proxy.
It cannot modify or see what is being transferred as it is protected by TLS encryption.
The only way to modify HTTPS conenctions on the fly is if you install some external CA certificates on your computer. This is known as MITM Attack.

Boost ASIO with OpenSSL Can't Read HTTP Headers

I'm attempting to write a simple HTTP/HTTPS proxy using Boost ASIO. HTTP is working fine, but I'm having some issues with HTTPS. For the record this is a local proxy. Anyway so here is an example of how a transaction works with my setup.
Browser asks for Google.com
I lie to the browser and tell it to go to 127.0.0.1:443
Browser socket connects to my local server on 443I attempt to read the headers so I can do a real host lookup and open a second upstream socket so I can simply forward out the requests.
This is where things fail immediately. When I try to print out the headers of the incoming socket, it appears that they are already encrypted by the browser making the request. I thought at first that perhaps the jumbled console output was just that the headers were compressed, but after some thorough testing this is not the case.
So I'm wondering if anyone can point me in the right direction, perhaps to some reading material where I can better understand what is happening here. Why are the headers immediately encrypted before the connection to the "server" (my proxy) even completes and has a chance to communicate with the client? Is it a temp key? Do I need to ignore the initial headers and send some command back telling the client what temporary key to use or not to compress/encrypt at all? Thanks so much in advance for any help, I've been stuck on this for a while.
HTTPS passes all HTTP traffic, headers and all, over a secure SSL connection. This is by design to prevent exactly what you're trying to do which is essentially a man-in-the-middle attack. In order to succeed, you'll have to come up with a way to defeat SSL security.
One way to do this is to provide an SSL certificate that the browser will accept. There are a couple common reasons the browser complains about a certificate: (1) the certificate is not signed by an authority that the browser trusts and (2) the certificate common name (CN) does not match the URL host.
As long as you control the browser environment then (1) is easily fixed by creating your own certificate authority (CA) and installing its certificate as trusted in your operating system and/or browser. Then in your proxy you supply a certificate signed by your CA. You're basically telling the browser that it's okay to trust certificates that your proxy provides.
(2) will be more difficult because you have to supply the certificate with the correct CN before you can read the HTTP headers to determine the host the browser was trying to reach. Furthermore, unless you already know the hosts that might be requested you will have to generate (and sign) a matching certificate dynamically. Perhaps you could use a pool of IP addresses for your proxy and coordinate with your spoofing DNS service so that you know which certificate should be presented on which connection.
Generally HTTPS proxies are not a good idea. I would discourage it because you'll really be working against the grain of browser security.
I liked this book as a SSL/TLS reference. You can use a tool like OpenSSL to create and sign your own certificates.

How to ignore certain socket requests

I'm currently working on a TCP socket server in C++; and I'm trying to figure out how I can ignore all browser connections made to my server. Any idea's?
Thanks.
Need more details to give good feedback.
Are you going to be listening on port 80 but want to avoid all HTTP traffic? Or will your protocol be HTTP-based? Do you need to listen on 80 or can you pick any port?
If it's your own custom protocol (HTTP or not) you could just look at the first line sent up and if it's not to your liking just close() the socket.
EDIT:
Since you're going to be listening on a custom port, you probably won't get any browser traffic anyhow. Further, since you're going to be writing your own protocol, just require a handshake which establishes your client speaks your custom protocol and then ignore (close()) everything else.
Bonus points: depending on your goal, send back an HTTP error message which can be displayed to the user.
You can't stop a web-browser initiated tcp-session from connecting to your tcp server. You can (as stated above) close the connection once you've detected the client is trying to talk http to you (or any other unwanted application-layer protocol).
Just look at the differences between valid connection requests and invalid ones (i.e. dump both request types to examine each request), in your specific case, you'll want to look at the HTTP request header to ignore all such requests (assuming that valid requests do not make use of HTTP).