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

feat(pg): support SSL certs #7175

Merged
merged 15 commits into from
Dec 13, 2022
Merged

feat(pg): support SSL certs #7175

merged 15 commits into from
Dec 13, 2022

Conversation

mattkrick
Copy link
Member

@mattkrick mattkrick commented Sep 13, 2022

Signed-off-by: Matt Krick [email protected]

Description

Fixes #7174

Demo

N/A

Testing scenarios

@rafaelromcar-parabol could I ask you to test this? I think you can probably self sign a cert faster than me 🙂

@sonarcloud
Copy link

sonarcloud bot commented Sep 13, 2022

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@rafaelromcar-parabol
Copy link
Contributor

Just in case, I'm taking this but not yet.. Review is coming soon.

@rafaelromcar-parabol
Copy link
Contributor

Why is the folder __PROJECT_ROOT__/packages/server/postgres not taken from an environment variable? That folder could be the default value if a parameter named PGSSLPATH is empty.

That would allow much more flexibility and remove the data from the application folder.

@rafaelromcar-parabol
Copy link
Contributor

IMHO this PR should have documentation on how to enable SSL for PostgreSQL.

A md file or in the general README.md with the instructions and parameters describing how to configure it. Like what should be in each one of the files root.crt, postgresql.key, postgresql.crt, in which folder those files should be and anything else that could help.

@mattkrick
Copy link
Member Author

documentation added! ready to merge as soon as tests pass

const ca = readFileSync(path.join(PG_CERT_DIR, 'root.crt'))
const key = readFileSync(path.join(PG_CERT_DIR, 'postgresql.key'))
const cert = readFileSync(path.join(PG_CERT_DIR, 'postgresql.crt'))
return {ca, key, cert, rejectUnauthorized: false}
Copy link
Contributor

Choose a reason for hiding this comment

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

I changed rejectUnauthorized: true to false because the certificate provided by GCP CloudSQL only has a as name of the server the one used by the CloudSQL Proxy (we are going to use it in the future). You can see other similar cases on internet like this one.

IMHO, this could be improved using a parameter PG_SSL_REJECT_UNAUTHORIZED. We could set it to true or false depending on the use case. If you think we should do it that way, please add that to the PR. If not, it is working!

Copy link
Contributor

Choose a reason for hiding this comment

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

Forgot to share the error I saw

node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: postgresql.test-instance-6.parabol.local. is not cert's CN: parabol-proving-ground:test-instance-6-postgresql-1b252b94
    at new NodeError (node:internal/errors:372:5)
    at Object.checkServerIdentity (node:tls:346:12)
    at TLSSocket.onConnectSecure (node:_tls_wrap:1542:27)
    at TLSSocket.emit (node:events:527:28)
    at TLSSocket.emit (node:domain:475:12)
    at TLSSocket._finishInit (node:_tls_wrap:946:8)
    at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:727:12) {
  reason: "Host: postgresql.test-instance-6.parabol.local. is not cert's CN: parabol-proving-ground:test-instance-6-postgresql-1b252b94",
  host: 'postgresql.test-instance-6.parabol.local',

IT GOES AND GOES with more stuff that are less relevant

Copy link
Contributor

Choose a reason for hiding this comment

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

-1 I don't know. To me it seems to be a setup issue on our side and I would rather fix that than disabling this check. Basing this solely on this comment: GoogleCloudPlatform/nodejs-docs-samples#1735 (comment)

const ca = readFileSync(path.join(PG_CERT_DIR, 'root.crt'))
const key = readFileSync(path.join(PG_CERT_DIR, 'postgresql.key'))
const cert = readFileSync(path.join(PG_CERT_DIR, 'postgresql.crt'))
return {ca, key, cert, rejectUnauthorized: false}
Copy link
Contributor

Choose a reason for hiding this comment

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

-1 I don't know. To me it seems to be a setup issue on our side and I would rather fix that than disabling this check. Basing this solely on this comment: GoogleCloudPlatform/nodejs-docs-samples#1735 (comment)

@rafaelromcar-parabol
Copy link
Contributor

Problem found when running migrations. It shows an error

yarn run v1.22.19
$ node scripts/migrate.js
[migrate-rethinkdb] No new migrations
Done in 0.40s.
yarn run v1.22.19
$ node-pg-migrate -f ./packages/server/postgres/pgmConfig.js up
could not connect to postgres: error: pg_hba.conf rejects connection for host "10.0.85.23", user "parabol-admin", database "parabol", SSL off
    at Parser.parseErrorMessage (/home/node/parabol/node_modules/pg-protocol/src/parser.ts:369:69)
    at Parser.handlePacket (/home/node/parabol/node_modules/pg-protocol/src/parser.ts:188:21)
    at Parser.parse (/home/node/parabol/node_modules/pg-protocol/src/parser.ts:103:30)
    at Socket.<anonymous> (/home/node/parabol/node_modules/pg-protocol/src/index.ts:7:48)
    at Socket.emit (node:events:527:28)
    at Socket.emit (node:domain:475:12)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
    at Socket.Readable.push (node:internal/streams/readable:228:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  length: 166,
  severity: 'FATAL',
  code: '28000',
  detail: undefined,
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'auth.c',
  line: '445',
  routine: 'ClientAuthentication'
}
[...] 
error Command failed with exit code 1.

The PG migrations are using the file ./packages/server/postgres/pgmConfig.js as config, which does not have any SSL configuration there. Can you add it as in packages/server/postgres/getPgConfig.ts?

@rafaelromcar-parabol
Copy link
Contributor

rafaelromcar-parabol commented Dec 12, 2022

Suggestion: change all variables here from PGXXX to POSTGRES_SSL_XXX to follow the same format.

Current variables

POSTGRES_PASSWORD=''
POSTGRES_USER=''
POSTGRES_PASSWORD=''
POSTGRES_USER=''
POSTGRES_DB=''
POSTGRES_HOST=''
POSTGRES_PORT=''
PGADMIN_DEFAULT_EMAIL=''
PGADMIN_DEFAULT_PASSWORD=''

Added in the PR so far:

PGSSLMODE=""
PG_SSL_REJECT_UNAUTHORIZED=""
PG_CERT_DIR=""

Proposed:

POSTGRES_SSL_MODE=""
POSTGRES_SSL_REJECT_UNAUTHORIZED=""
POSTGRES_SSL_CERT_DIR=""
""

@mattkrick mattkrick merged commit 619ebf2 into master Dec 13, 2022
@mattkrick mattkrick deleted the devops/pg-ssl branch December 13, 2022 00:50
@mattkrick mattkrick mentioned this pull request Dec 15, 2022
23 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DevOps: Support CA for PG: PGSSLCERT, PGSSLKEY, PGSSLROOTCERT
3 participants