Skip to content
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

fixed ssl mode #84

Merged
merged 17 commits into from
Jun 7, 2022
Merged

fixed ssl mode #84

merged 17 commits into from
Jun 7, 2022

Conversation

kikkupico
Copy link
Contributor

@kikkupico kikkupico commented May 11, 2022

fixes #82

Description

With the existing preview apps actions, it's not possible to use Postgres in SSL mode even if the user provides a connection string ending with ?sslmode=require. This happens because of a peculiar behaviour of the node-postgres client that we use. Paraphrasing the node-postgres documentation ( https://node-postgres.com/features/ssl ) -

If you plan to use a combination of a database connection string from the environment and SSL settings in the config object directly, then you must avoid including any of sslcert, sslkey, sslrootcert, or sslmode in the connection string. If any of these options are used then the ssl object is replaced and any additional options provided there will be lost.

So, when a user provides a connection URI ending with ?sslmode=require , unauthorised clients are automatically rejected. Our Postgres client used in the GitHub Actions is unauthorised and hence is rejected. Thus the preview apps flow ends at the DB connection stage with an error similar to the error below

FATAL: no pg_hba.conf entry for host "172.17.0.1", user "ram", database "postgres"

To fix this issue, we explored a few alternatives -

  • Always use the option rejectUnauthorized: false in the node-pg client's connection function. This breaks the ability to use DBs without SSL as providing this parameter to the connect function will enable SSL by default.
  • Ask the user to provide additional parameters in the preview apps YAML to configure Postgres connection. Eg: SSL_VERIFY=false. This is a non-standard approach and will likely confuse the users who are used to providing ssl mode info in the connection URI.
  • Allow the user to provide connection URIs ending with ?sslmode=require but parse the connection URI and set the pgclient's connection options differently. If sslmode=require is found, set the option rejectUnauthorized=false always. Otherwise, don't enable SSL. This appeared to the best option and has been implemented in this PR.

Limitations

  1. By using this fix, it is possible to connect to Heroku Postgres. But still we end up with a different error because Heroku does not allow users to create/drop DBs in the free plan. From the documentation ( https://devcenter.heroku.com/articles/connecting-to-heroku-postgres-databases-from-outside-of-heroku ) it is not clear whether the user will be able to create/drop DBs using a paid plan. Changing the action itself to not use drop/re-create DBs is out of the scope of this PR and will be handled later if required.

  2. We have to confirm if the error reported here ( https://hasurahq.slack.com/archives/C01KZ6JPPCM/p1654034722372949?thread_ts=1654001877.882759&cid=C01KZ6JPPCM ) is somehow caused by allowing the user to set ?sslmode=require in the connection URI.

Tests

Connection to Heroku from node was tested using this sample script -

const { Client } = require('pg');

const client = new Client({
  connectionString: process.env.PG_URL,
  ssl: {
    rejectUnauthorized: false
  }
});

client.connect();

client.query('SELECT table_schema,table_name FROM information_schema.tables;', (err, res) => {
  if (err) throw err;
  for (let row of res.rows) {
    console.log(JSON.stringify(row));
  }
  client.end();
});

It is observed that removing the ssl option in fact leads to the original error we observed with Heroku PG.

The entire preview apps flow was tested using a sample repo. The following tests were done -

@kikkupico kikkupico marked this pull request as ready for review May 12, 2022 13:51
@kikkupico kikkupico requested a review from wawhal May 12, 2022 13:51
@kikkupico kikkupico requested a review from shraddhaag May 24, 2022 07:12
Copy link
Member

@shraddhaag shraddhaag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality LGTM. Tested the following cases:

  1. Non Heroku Postgres server with no SSL issue: ✅ succeeded as expected (run here)
  2. Heroku Postgres server with SSL param not given in the connection URI: ❌ failed as expected (run here) error message can be improved here.
  3. Heroku Postgres with SSL param in the connection URI: ✅ failed at DB creation step as expected.

We should properly update the documentation to reflect this change as well as update the previews apps YAML generator which this check in the input incase folks are giving the connection URI directly instead of through an ENV var/secrets.

I'd also like to test this with a paid heroku account to see the db creation go through as well. @wawhal could you please help with appropriate accesss here?

Edit: I tried the same workflow with Heroku postgres on paid plan Hobby Basic and getting the same error. Not sure if Heroku allows creating dbs. (run here)

@meetzaveri
Copy link
Member

@shraddhaag @kikkupico

Quoting one of the lines from the last comment

Edit: I tried the same workflow with Heroku postgres on paid plan Hobby Basic and getting the same error. Not sure if Heroku allows creating dbs.

On this particular scenario, I have experienced similar issue with Heroku specifically. But when I tried creating DB cluster on DigitalOcean and used it instead of Heroku, there was no such issue that I faced on heroku( like having problem creating ephemeral database(s) )

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

Successfully merging this pull request may close these issues.

have an opinionated SSL policy
3 participants