How to use Python requests to connect to a server through proxy when both requires different client certificate - python-requests

I want to connect to a https server using python requests library through a proxy. The code roughly looks like
response = requests.get(SERVER_ENDPOINT, proxies=PROXIES, cert=??)
My problem is, both server and proxy requires client authentication, and unfortunately different CA is used to authenticate server and proxy. Is there a way to pass two CAs when making a request? The documentation doesn't seem to be very clear on this scenario.
Any help is greatly appreciated:)
Method Tried:
Tried the method as suggested in another link Python requests - how to add multiple own certificates, and bundle certs and keys into separate pem files using the code below:
response = requests.get(SERVER_ENDPOINT, proxies=PROXIES, cert=(CERT_BUNDLE, KEY_BUNDLE))
It seems that only the 1st cert and key is used, so I am able to pass client auth at proxy server, but failed auth at destination server.

Related

Need Certificate chain (on the incoming interface) from Nginx

I am using a setup wherein a chain certificate(Root CA Cert-> Intermediate CA Cert -> Client Cert) is being sent to the Nginx. I need to configure Nginx in such a way that it forwards the entire certificate chain to the middleware. Right now, it is just sending the leaf certificate i.e. client certificate.
I found the following options from the Nginx's documentation (http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate)
1- $ssl_client_escaped_cert
2- $ssl_client_cert
None of the above returns the full certificate chain.
Is anyone aware if there is such an option available ?
This seems to be impossible by design - see https://serverfault.com/questions/576965/nginx-proxy-pass-with-a-backend-requesting-client-certificates
The usage of $ssl_client_escaped_cert (as explained in https://clairekeum.wordpress.com/2018/12/05/passing-client-cert-through-nginx-to-the-backend/) seems to be your only option.
This may not be a complete answer, but thought I'd post some resources that may give you a couple of ideas.
If you want the client cert details downstream, then one option is to avoid terminating Mutual TLS in nginx by using the stream module. Here is an example:
Mutual TLS Secured API Blog Post .
NGINX Config
In this setup there are 2 Mutual TLS connections being routed via nginx:
To authenticate with an Authorization Server - where Mutual TLS is not handled by nginx
To call an API with a certificate bound access token - where nginx terminates TLS
Note that this uses a LUA plugin and the ssl_client_raw_cert property to do the extra work of calculating a SHA256 thumbprint, which NGINX itself does not support.
Generally though it makes sense to externalise Mutual TLS plumbing from application level components, as in the above example. Eg you can forward ssl_client_eacaped_cert to your middleware, but perhaps nginx should do the more detailed work of checking issuers.

Nginx confg issue - couldn't connect to S3 compatible storage from NodeJS test program

This is my first quetion on StackOverflow.
I have a requirement to provision LB, and proxy layer in DMZ for the clients to reach a backend S3 compatible storage to read buckets. I am using multiple instances of Nginx for this: one instance for LB (node 1), and two instances (node 2,3) as reverse proxy. LB (node 1) listens on https 443 and has a CA signed cert, and is visible on internet. Node 2,3 are listening on http 80, and will fwd requests to backend S3 compatible storage listens on https with self-signed certs.
When I use a test NodeJS program, from with in DMZ layer, to directly connect to the S3 compatible storage, I could read and list buckets using AWS client, with accessKeyId and secretAccessKey.
But when I use the same test NodeJS program, from internet, with same accessKeyId and secretAccessKey, and trying to connect to node 1 (eventually reach backend S3 compatile storage), I am getting the following error:
{"message":"The request signature we calculated does not match the signature you provided.
Check your AWS Secret Access Key and signing method.
For more information, see REST Authentication and SOAP Authentication for details.",
"code":"SignatureDoesNotMatch",
"region":null,
"time":"2018-12-18T12:34:28.313Z",
"requestId":"2899219037",
"statusCode":403,"retryable":false,
"retryDelay":14.04655267301651}
I tried multiple ways to understand and solve this. It looks like my Nginx config is not passing http headers correctly. But I didn't explicitly config anything to hide http headers, and my understanding is that, all headers will pass through unless we explicitly block them.
Other than reaching to S3 compatible backend storage, the calls are going through Nginx. I have even tested to reach another host instead of S3 compatible storage (with self-signed cert), it worked well.
Pl suggest any solution. Let me know any info I may need to add to this question.
srinivas
Resolved.
In my case what fixed the issue is setting up Host as header.
location /something {
...
proxy_set_header Host $http_host;
...
}
My understanding is, Host is used as part of signature generation / verification. It is stripped by Nginx by default, and setting this up explicitly resolved it.

Is it possible to have client certificates with HTTP (not HTTPS)?

I have an application set up like this:
There is a server, with a reverseproxy/load balancer that acts as the HTTPS termination (this is the one that has a server certificate), and several applications behind it(*)
However, some applications require authentication of the client with a certificate. Authentication cannot happen in the reverse proxy. Will the application be able to see the user certificate, or will it be jettisoned by the HTTPS->HTTP transfer?
(*) OK, so this is a Kubernetes ingress, and containers/pods.
It will be lost. I think you need to extract it in the reverse proxy (i.e. Nginx) and pass it in as a HTTP header if you really must. See for example https://serverfault.com/questions/788895/nginx-reverse-proxy-pass-through-client-certificate. Not very secure as the cert is passed in the clear!
I don't know if we have that level of control over the ingress, personally I'm using a normal Nginx server for incoming traffic instead.

Web app with out SSL integration intercepted by Proxy

My application is based on Spring framework and is used to transmit very confidential data.During testing of the application with with proxy tools like Fiddler, Paros Proxy etc. it was found that these tools are intercepting the request data, and data is easily modified before reaching the server.
My application is not currently not integrated with SSL . We will implement SSL /HTTPS. but is this because SSL has not been integrated ?
Is it normal for Proxy tools to intercept the data from a web application with out HTTPS ?
There are two things here.
1) If you don't use SSL the communication is not encrypted, which means that anybody who is able to intercept the traffic, will be able to see the content. You don't necessarily need a proxy for that.
2) With an intercepting HTTP proxy you can see SSL encrypted traffic as well. What the proxy does is building two separate SSL tunnels one between the server and the proxy and one between the client and the proxy. This way the proxy itself can see the whole traffic. Of course the proxy can only provide a fake SSL certificate which will trigger a notification in the browser for the user, but he will probably ignore it.
Yes. If you don't use https, Proxy see everything that the application send or received.
To prevent that, you must use https.
To prevent sslstrip you must use HSTS.

HTTPS key negotiation and tunneling over HTTP using Javascript

HTTPS is widely used for security online. It offers security and integrity, but not authentication. To ensure the client is not talking to a man-in-the-middle, we have digital certificates and the PKI. It all works very well, except in the situation where the following criteria apply:
The server and client do not share a common, trusted root CA, therefore they cannot validate each other's certificates
Circumstances (eg. firewall, permissions, etc) do not permit the use of regular HTTPS protocol
The question is: can we still send secure, authenticated messages between the client and server, perhaps using Javascript?
Something along the lines of:
Client sends regular HTTP request to server
Server responds with page containing Javascript code
Client's Javascript asynchronously sends data to the server used to negotiate
Server runs some sort of script (eg. PHP) to establish the tunnel
Client and server communicate over the encrypted tunnel
I can see it being possible to send messages with security and integrity in this manner, but is it possible to authenticate without making use of the PKI, perhaps by exploiting the fact that the server can dynamically rewrite the Javascript sent to the client?
There is an issue in your step 2 - Server responds with page containing Javascript code :
how do you know someone sitting on wire is not modifying this Javascript since it is being transferred in plaintext? Basically, when X wants to authenticate Y, X should know something about Y- it could be public information such as public key/certificate or shared secret that it could verify

Resources