Skip to content

How to override checkServerIdentity for ssl connection? #592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
levino opened this issue Oct 26, 2018 · 18 comments
Closed
1 task done

How to override checkServerIdentity for ssl connection? #592

levino opened this issue Oct 26, 2018 · 18 comments
Labels

Comments

@levino
Copy link

levino commented Oct 26, 2018

I'm submitting a...

  • Question

Current behavior

I can only connect to my google cloud psql instance with rejectUnauthorized: false.

Expected behavior

I can connect to my google cloud psql instance with rejectUnauthorized: true.

Minimal reproduction of the problem with instructions

Create a google cloud managed postgresql instance and switch on ssl/tls with the self signed CA. Then try to run migrations on the database from a remote system (like your local workstation).

What is the motivation / use case for changing the behavior?

Googles certificates are badly configured. They give you an ip to connect to, but the ip of the server is not in the list of altnames in the certificate the server provides. You will get this error message when attempting to connect with rejectUnauthorized: true:

[ERROR] Error: Hostname/IP doesn't match certificate's altnames: "IP: X.X.X.X is not in the cert's list: "

Now one could possibly work around this with implementing a custom checkServerIdentity function for the tls connection by node which should be more secure than just rejectUnauthorized: false. Alas db-migrate expects configuration via a database.json, not javacript so I cannot implement the checkServerIdentity function.

So now to the question: How to read the config for db-migrate from a javacript file?

Environment


yarn list v1.10.1
├─ [email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]
└─ [email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]
└─ pgpass@

Additional information:
- Node version: v8.12.0
- Platform:  Linux (Ubuntu 18.04)
@levino
Copy link
Author

levino commented Oct 26, 2018

I use amazons RDS now. All is working fine, no need for client certificates, which is even better, I find.

@stale
Copy link

stale bot commented Nov 29, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@olso
Copy link

olso commented Jun 3, 2020

in your database.json, you can

"dev": {
    "driver": "pg",
    "url": {
      "ENV": "DATABASE_URL"
    },
    "ssl": {
      "rejectUnauthorized": false
    }
  },

@levino
Copy link
Author

levino commented Jun 4, 2020

in your database.json, you can

"dev": {
    "driver": "pg",
    "url": {
      "ENV": "DATABASE_URL"
    },
    "ssl": {
      "rejectUnauthorized": false
    }
  },

Are you serious? This flag should never be false because the check prevents a MITM-attack on the Server-to-Database-Connection!

For everyone else: Do not switch this check off. Not even in a development setting. Just use AWS as suggested above.

@levino
Copy link
Author

levino commented Jun 4, 2020

@olso If you read my OP carefully you can see that I considered and rejected the idea of doing what you suggest right from the beginning.

@olso
Copy link

olso commented Jun 4, 2020

@levino I know its wrong, but I'm using Heroku... https://help.heroku.com/MDM23G46/why-am-i-getting-an-error-when-i-upgrade-to-pg-8

@levino
Copy link
Author

levino commented Jun 4, 2020

Their guide is just wrong. They are crazy fools. Stop using them if they work on this poor level. This kind of advice should be illegal and punished.

@levino
Copy link
Author

levino commented Jun 4, 2020

Jesus, if I understand it right until recently node-postgres silently disabled cert checking and only enabled it now. I am flubberghasted! They write unbelievable bulls**t like this:

This means your connection attempt may fail if you are using a self-signed cert.

Of course this must fail because a self-signed cert is insecure ffs! Do not use self signed certs, ever!

@levino
Copy link
Author

levino commented Jun 4, 2020

No offense intended @olso but if you are confused here you should read up a bit about encryption and best practices for secure remote connections.

@olso
Copy link

olso commented Jun 4, 2020

It's fine, I get the issue. I'm talking to Heroku support for more info.

Just found out that 😕 means confused, going to change my reaction

@wzrdtales
Copy link
Member

self signed is not a bad thing when it is intended to be a managed PKI which is quite a normal thing for databases in enterprises. of course those PKIs are mildly more secure than just a common people self signed cert, but is equally the same thing. I am agreeing that rejectUnauthorized is horribly bad idea except maybe for your local dev environment, but supplying a CA cert of the signing PKI is always the actual option. You @levino could ask heroku if there is a CA cert that they can supply to you.

@wzrdtales
Copy link
Member

for reference, quick google gives this https://devcenter.heroku.com/articles/heroku-postgres-via-mtls, so they offer something in that regards.

@levino
Copy link
Author

levino commented Jun 5, 2020

Of course if you set up your own CA and install the root certificate on the client machine as trustworthy, you can secure your setup even with certificates signed by your own CA (which is something else than "self-signed" where the cert is signed by itself, is it not? Could not find a proper definition of "self-signed"). But still you need to reject any unauthorized connection to the database. And managing your own CA securely is hard and cumbersome. I do not recommend it.

@wzrdtales
Copy link
Member

well managing the trust in the case of auth by cert in a database environment wouldn't be very healthy to be done by a public CA. it would be too slow, too cumbersome to validate new certs and in the end also too expensive and insecure. public CAs are the way to go in general for the validity of user facing certificates of all kinds. System services have different requirements and you certainly don't want anyone else to be able to sign your auth certificates for your services other than you. So you need a PKI infrastructure at that point. And you never install those root CAs on the machine, as they're single purpose and are supplied to such systems (as in this case a database) directly as a configuration param.

and no providing a CA yourself is nothing else than "self-signed". In fact self-signed means you generate a CA adhoc to sign the cert with.

managing your own CA is a piece of cake, everyone can do it. Securing it, is a different tier, but also not essentially hard. In the end it is as secure as the password for the root account is if it is really strong. If the user who has access to it gets compromised, the whole system is compromised. This can be circumvented with zero trust topologies, however rarely implemented, not even by big hairy monkey companies.

@levino
Copy link
Author

levino commented Jun 8, 2020

I get your point. But even with all that you still want "unauthorized" connection attempts to be refused.

@mattbbc
Copy link

mattbbc commented Jul 19, 2023

I use amazons RDS now. All is working fine, no need for client certificates, which is even better, I find.

I'm just starting to use db-migrate and I'm interested to know how you connect it to an AWS RDS instance safely - is your database public?

@levino
Copy link
Author

levino commented Jul 19, 2023

Hey @mattbbc that's an oldy here.

First of all I feel a little ashamed of the strong and harsh language I used here. I would like to apologize to all people whose feelings I might have hurt, for example @olso . I am sorry. That was unnecessary. I have changed a bit since then (at least I hope so). I thought about deleting some of the comments but will leave them for transparency reasons.

On your question: Maybe I exposed the database to the internet, I do not remember. I think you can limit the IP range which is allowed to connect to it. But if you use TLS and a strong password, the database is safe. Maybe it could be ddoses, but that is it. Another possibility is a server in the same VPN as the database which exposes an ssh server with cert only authentication (not password). You then can tunnel the connection through this server to your database via ssh. That is what I would recommend today.

@Zambonilli
Copy link

This is one of the top results in duckduckgo for connecting to a GCP Cloud SQL postgres w/self signed certs. After spending a day bashing my head against the wall like @levino did, I can say the only solution right now is to not verify the self signed cert at all via setting the rejectUnauthorized to false when using GCP Cloud SQL postgres with a private IP. The node-postgres package that most of the postgres packages are using does not support the verify-ca ssl mode which would assert the CA but not fail on the CN not matching.

brianc/node-postgres#2934 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants