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

docs(sdb): add new frameworks to SSL/TLS MTA-4594 #3286

Merged
merged 7 commits into from
Jun 11, 2024
118 changes: 108 additions & 10 deletions serverless/sql-databases/api-cli/secure-connection-ssl-tls.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ dates:
This documentation will guide you through SSL/TLS configuration in your PostgreSQL-compatible client to ensure your traffic with Scaleway's Serverless SQL Databases is encrypted.

Configuration examples for languages, frameworks and tools:
- [Python](#pythonpsycopg2)
- [Python](#pythondjango)
- [Node.js](#nodejsnode-postgres)
- [Node.js](#nodejspostgresjs)
- [Node.js](#javajdbc)
- [Python/psycopg2](#pythonpsycopg2)
- [Python/Django](#pythondjango)
- [Python/asyncpg](#pythonasyncpg)
- [Node.js/node-postgres](#nodejsnode-postgres)
- [Node.js/Postgres.js](#nodejspostgresjs)
- [Node.js/Prisma](##nodejsprisma)
- [Go/pq](#gopq)
- [Go/pgx](#gopgx)
- [PHP/pgsql](#phppgsql)
- [Java/JDBC](#javajdbc)
- [C#/.NET/Npgsql](#cnetnpgsql)
- [Rust/rust-postgres](#rust)
- [psql](#psql)

## Generic configuration settings
Expand Down Expand Up @@ -73,8 +80,8 @@ DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': {databasename},
'USER': {username}, #IAM principal ID of the user or application your are connecting with
'PASSWORD': {password}, #IAM Secret Key of the user or application your are connecting with
'USER': {username}, #IAM principal ID of the user or application you are connecting with
'PASSWORD': {password}, #IAM Secret Key of the user or application you are connecting with
'HOST': {host}, #Host formated as {database-id}.pg.sdb.{region}.scw.cloud
'PORT': {port}, #Default port for PostgreSQL is supported: 5432
'OPTIONS': {
Expand All @@ -85,9 +92,24 @@ DATABASES = {
}
```

### Python/asyncpg

[asyncpg](https://github.com/MagicStack/asyncpg) supports `sslmode=verify-full`, but does not support the `sslrootcert=system` option yet.

To make sure SSL/TLS is enforced, and the server certificate is valid, edit your connection parameters to set the `sslmode=verify-full` parameter, download the [Let's Encrypt ISRG Root X1 (pem format)](https://letsencrypt.org/certs/isrgrootx1.pem), rename it `root.crt`, and store it in `~/.postgresql/root.crt`:
```python
conn = await asyncpg.connect("postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=verify-full")
```

Alternatively, you can add the `sslrootcert=full/path/to/certificate/isrgrootx1.pem` property to specify the full path to the certificate without renaming it `root.crt`:

```python
conn = await asyncpg.connect("postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=verify-full&sslrootcert=full/path/to/certificate/isrgrootx1.pem")
```

### Node.js/node-postgres

[node-postgres](https://node-postgres.com/) doesn't support `sslmode=verify-full` and `sslrootcert=system`, but either the default connection string option `sslmode=require` or the driver-specific parameter `ssl:true` option checks for certificate validity.
[node-postgres](https://node-postgres.com/) does not support `sslmode=verify-full` and `sslrootcert=system`, but both the default connection string option `sslmode=require` and the driver-specific parameter `ssl:true` option check for certificate validity. You can use either one of them.

To ensure SSL/TLS is enforced and your server certificate is valid, add `ssl:true` to your connection parameters:
```js
Expand All @@ -103,7 +125,7 @@ const client = new Client({

### Node.js/Postgres.js

[Postgres.js](https://github.com/porsager/postgres) doesn't support `sslmode=verify-full` and `sslrootcert=system`, but either the default connection string option `sslmode=require` or the driver-specific parameter `ssl:true` option checks for certificate validity.
[Postgres.js](https://github.com/porsager/postgres) does not support `sslmode=verify-full` and `sslrootcert=system`, but either the default connection string option `sslmode=require` or the driver-specific parameter `ssl:true` option checks for certificate validity.

To ensure SSL/TLS is enforced and the server certificate is valid, edit your connection parameters to add `ssl:true` parameters:

Expand All @@ -122,14 +144,46 @@ const sql = postgres({

You can use several drivers with [Prisma](https://www.prisma.io/docs/orm/overview/databases/postgresql#configuring-an-ssl-connection), refer to their official documentation for more information on how to configure SSL/TLS.

By default, Prisma uses its built-in PostgreSQL driver which doesn't support `sslmode=verify-full` and `sslrootcert=system`, but can perform certificate validity checks by using the `sslmode=require` and `sslaccept=strict` parameters.
By default, Prisma uses its built-in PostgreSQL driver which does not support `sslmode=verify-full` and `sslrootcert=system`, but can perform certificate validity checks by using the `sslmode=require` and `sslaccept=strict` parameters.

To ensure SSL/TLS is enforced and the server certificate is valid, add these two parameters to your connection string in your `.env` file:

```sh
DATABASE_URL=postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=require&sslaccept=strict
```

### Go/pq

[pq](https://github.com/lib/pq) supports the `sslmode=verify-full` option, but not `sslrootcert=system`. However, when using `sslmode=verify-full`, checks will also be made against the default certification authority certificates trusted by your operating system, as if `sslrootcert=system` parameter was set.

To ensure SSL/TLS is enforced and the server certificate is valid, add `sslmode=verify-full` to your connection parameters:

```go
connString := "postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=verify-full"
conn, err := pgx.Connect(context.Background(), connString)
```

### Go/pgx

[pgx](https://github.com/jackc/pgx) supports the `sslmode=verify-full` option, but not `sslrootcert=system`. However, when using `sslmode=verify-full`, checks will also be made against default certification authority certificates trusted by your operating system, as if the `sslrootcert=system` parameter was set.

To ensure SSL/TLS is enforced and the server certificate is valid, add `sslmode=verify-full` to your connection parameters:

```go
connString := "postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=verify-full"
db, err := sql.Open("postgres", connString)
```

### PHP/pgsql

As the default PostgreSQL driver bundled with PHP, [pgsql](https://www.php.net/manual/en/book.pgsql.php) uses [libpq](https://www.postgresql.org/docs/current/libpq.html). The same official PostgreSQL parameter can therefore be used.

To ensure SSL/TLS is enforced and the server certificate is valid, add `sslmode=verify-full` and `sslrootcert=system` to your connection parameters:

```php
$dbconn = pg_connect("host={host} port={port} dbname={databasename} user={username} password={password} sslmode=verify-full sslrootcert=system")
```

### Java/JDBC

JDBC driver does not support the `sslrootcert=system` option, but supports the `ssl=true` option which, when enabled, performs certificate checks by default against the certificate named `root.crt` stored in `~/.postgresql`.
Expand Down Expand Up @@ -157,6 +211,50 @@ Alternatively, you can add the property `"sslrootcert=full/path/to/certificate/i
Connection conn = DriverManager.getConnection(url,props);
```

### C#/.NET/Npgsql

[Npgsql](https://www.npgsql.org/) supports the `sslmode=verify-full` option, but not `sslrootcert=system`. However, when using `sslmode=verify-full`, checks will also be made against default certification authority certificates trusted by your operating system, as if the `sslrootcert=system` parameter was set.

To ensure SSL/TLS is enforced and the server certificate is valid, add `sslmode=verify-full` to your connection parameters:

```cs
var connString = "Host={host};Username={username};Password={password};Database={databasename};Port=5432;SSL Mode=VerifyFull;";
var dataSourceBuilder = new NpgsqlDataSourceBuilder(connString);
```

### Rust

[rust-postgresql](https://github.com/sfackler/rust-postgres) does not support the `sslmode=verify-full` and `sslrootcert=system` options. However, when using `sslmode=require`, you can pass a `TlsConnector` object to perform the certificate verification.

Also, when using the standard [rust-openssl](https://github.com/sfackler/rust-openssl) library, checks will also be made against default certification authority certificates trusted by your operating system as if the `sslrootcert=system` parameter was set.

To ensure SSL/TLS is enforced and the server certificate is valid, add `sslmode=require` to your connection parameters:
```rust
use postgres::{Client};
use openssl::ssl::{SslConnector, SslMethod};
use postgres_openssl::{MakeTlsConnector};

fn main() {
let builder = SslConnector::builder(SslMethod::tls()).expect("unable to create sslconnector builder");
let connector = MakeTlsConnector::new(builder.build());
let mut client = Client::connect("postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=require", connector).expect("Connection failed");
}
```

Alternatively, you can download the [Let's Encrypt ISRG Root X1 (pem format)](https://letsencrypt.org/certs/isrgrootx1.pem), store it in `~/.postgresql/isrgrootx1.pem`, and directly specify the certificate:
```rust
use postgres::{Client};
use openssl::ssl::{SslConnector, SslMethod};
use postgres_openssl::{MakeTlsConnector};

fn main() {
let mut builder = SslConnector::builder(SslMethod::tls()).expect("unable to create sslconnector builder");
builder.set_ca_file("full/path/to/certificate/isrgrootx1.pem").expect("unable to locate certificate file");
let connector = MakeTlsConnector::new(builder.build());
let mut client = Client::connect("postgresql://{username}:{password}@{host}:{port}/{databasename}?sslmode=require", connector).expect("Connection failed");
}
```

## Examples for SQL Client tools

### psql
Expand Down