0

The Setup

I currently have a server and a mongodb database running in the cloud (Oracle Cloud Infrastructure).

The Problem

My connection to the database is bound by a select number of static IP's. This means that I cannot connect to my database from every client.

Attempted Solution

Therefore, I want to use my server (which has a static IP) to stand-in as a reverse proxy for my mongodb traffic.

Based on a variety of stackoverflow posts, and namely this post about setting up nginx behind a reverse proxy and this post about forcing nginx to re-resolve requests.

I have been able to setup a config that should work.

  resolver 194.168.4.100 valid=15s;

server { set $mongo "<MY_OCID>.<MY_REGION>.oraclecloudapps.com:27017"; listen 27017 so_keepalive=on; listen 27017 udp; #listen to UDP just in case proxy_connect_timeout 2s; proxy_pass $mongo; proxy_timeout 10m; }

What is the Issue?

Using the proxied database does not work or connect.

I get the error: MongoNetworkError: Client network socket disconnected before secure TLS connection was established

After a lot of testing with trying to make requests mongosh and using tcpdump to access all the traffic, I have run into a roadblock.

Looking at the tcpdump logs, the only difference I can find the DNS resolution.

Without a proxy:

cache1.service.<service_provider>.net.domain > laptop.55079: [udp sum ok] 51937 q: A? 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. 3/0/1 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. A <IP>, 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. A <IP>, 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. A <IP>  ar: . OPT UDPsize=512 (145)

Which then resolves correctly and has a correct connection.

With a proxy:

cache1.service.<service_provider>.net.domain > laptop.39421: [udp sum ok] 62642 q: A? 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. 3/0/0 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. A <IP>, 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. A <IP>, 
<MY_OCID>.<MY_REGION>.oraclecloudapps.com. A <IP> (134)

This does not resolve. It is missing a single additional record.

All the IPs are resolved correctly though.

The Question

Does anyone know whether NGINX resolves the address differently than a normal request? I am unsure of if I will even be able to do this.

Additional Information

I know that Oracle Cloud requires TLS (optionally mTLS) authentication to work properly.

My errors, therefore, could be because my proxy is not connecting with an TLS connection, and merely passing the TCP data along. How would I go about setting up the right certificates with this setup? Is it possible?

  server {
    set $mongo "<MY_OCID>.<MY_REGION>.oraclecloudapps.com:27017";
    listen 27017 ssl so_keepalive=on;
    ssl_certificate /path/to/some/ssl/cert.pem
    ssl_certificate /path/to/some/ssl/cert.key
    proxy_connect_timeout 2s;
    proxy_pass    $mongo;
    proxy_timeout 10m;
  }

Could I self-sign a cert like this? or would I have to somehow acquire a cert from oracle?

  • Maybe you have to use proxy_ssl? – Alexey Ten Oct 08 '23 at 18:47
  • That's a good point. I will self sign a certificate quickly and try it out. – Samuel Cobb Oct 08 '23 at 20:31
  • Your problem is not DNS; when the answer section has A record(s) (or AAAA for v6) any additional record(s) are unnecessary and ignored. Moreover the error message clearly indicates the TCP connection succeeded and only(!) the TLS handshake did not. I'd expect TCP passthrough to work, but trying TCP+SSL doesn't hurt; to be clear this server block is within stream and NOT http? – dave_thompson_085 Oct 09 '23 at 01:30
  • @dave_thompson_085 yes this is in the stream block. Do you know if I would be able ensure TLS over the connection? I don't have direct access to the database machine, so I can't place a certificate on it or anything. I have been provided with an 'ewallet.pem' cert that is used for mTLS, however I don't think that this would be a valid key for SSL. – Samuel Cobb Oct 09 '23 at 09:19
  • @dave_thompson_085 additionally, can I have a path where we have client -> server without SSL. Server -> database with SSL?

    I know it's a stupid idea, and I will secure the client -> server eventually, I just want to verify whether my proxy is working.

    – Samuel Cobb Oct 09 '23 at 09:35
  • (1) mTLS is just an option in TLS, and at this level TLS is SSL; technically the actual SSL protocols are now broken and not used, but the same code implemented both SSL and TLS (now only TLS) and in many cases continues to use the SSL name for convenience; thus the ssl keyword actually implements TLS, the ssl_certificate is really TLS, etc. (2) if dbserver requires client-auth, often called mTLS, and you have nginx do 'ssl' (i.e. TLS) termination, you must configure the 'ewallet' data (must be cert and key) on nginx (with proxy_ssl_certificate[_key]). – dave_thompson_085 Oct 10 '23 at 02:55
  • (3) yes you can have client-nginx plaintext and nginx-dbserver SSL=TLS; use listen WITHOUT ssl but keep proxy_ssl on and related settings (like the proxy cert/key above). – dave_thompson_085 Oct 10 '23 at 02:58

0 Answers0