Skip to content

Commit 004e5e8

Browse files
committed
Change default sslmode from "require" to "prefer"
Now that sslmode=prefer is supported, we can use that as the default. "prefer" is the default used by libpq, pgx, and pretty much anything else connecting to PostgreSQL. I can't really find anything else that uses "require" as a default. You could argue that "require" is a better default, but: 1. "require" doesn't actually verify the certificates and accepts any certificate. I wouldn't say it's completely useless for production systems, but it does seem useless-adjacent. If you want SSL, you almost always want "verify-ca" or "verify-full". 2. Copy/pasting a connection string used by pq to something else will mean you silently drop the ssl so it's a very brittle default. 3. It's an annoying default because copy pasting a connection string from anything else to pq doesn't work. pq has used "require" as a default for a long time, but because it's such a brittle default that's easy to lose by using $anything_else I think it's okay to change. I will leave this open for a bit before merging, so if anyone objects it can be re-considered.
1 parent 54c6056 commit 004e5e8

8 files changed

Lines changed: 38 additions & 22 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
unreleased
22
----------
33

4+
- As announced in the release notes for v1.12.0, this release changes the
5+
default `sslmode` from `require` to `prefer`, which is the default used by
6+
libpq and the rest of the PostgreSQL ecosystem ([#1271]).
7+
8+
- pq now requires Go 1.23.
9+
10+
### Features
11+
12+
### Fixes
13+
14+
- Add Redshift-specific OID mappings ([#1291], [#1317]).
15+
16+
[#1291]: https://github.com/lib/pq/pull/1291
17+
[#1317]: https://github.com/lib/pq/pull/1317
18+
419

520
v1.12.3 (2026-04-03)
621
--------------------

conn.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ restartAll:
261261
)
262262
for _, cfg := range c.cfg.hosts() {
263263
mode := cfg.SSLMode
264+
if mode == "" {
265+
mode = SSLModePrefer
266+
}
264267
restartHost:
265268
if debugProto {
266269
fmt.Fprintln(os.Stderr, "CONNECT ", cfg.string())

connector.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ func newConfig(dsn string, env []string) (Config, error) {
545545
Host: "localhost",
546546
Port: 5432,
547547
SSLSNI: true,
548+
SSLMode: SSLModePrefer,
548549
MinProtocolVersion: "3.0",
549550
MaxProtocolVersion: "3.0",
550551
}
@@ -1030,7 +1031,7 @@ func (cfg Config) string() string {
10301031
switch k {
10311032
case "datestyle", "client_encoding":
10321033
continue
1033-
case "host", "port", "user", "sslsni", "min_protocol_version", "max_protocol_version":
1034+
case "host", "port", "user", "sslsni", "sslmode", "min_protocol_version", "max_protocol_version":
10341035
if !cfg.isset(k) {
10351036
continue
10361037
}

connector_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,14 @@ func TestNewConfig(t *testing.T) {
333333
}{
334334
// Override defaults
335335
{"", nil, "", ""},
336-
{"user=u port=1 host=example.com", nil,
337-
"host=example.com port=1 user=u", ""},
338-
{"", []string{"PGUSER=u", "PGPORT=1", "PGHOST=example.com"},
339-
"host=example.com port=1 user=u", ""},
336+
{"user=u port=1 host=example.com sslmode=verify-ca", nil,
337+
"host=example.com port=1 sslmode=verify-ca user=u", ""},
338+
{"", []string{"PGUSER=u", "PGPORT=1", "PGHOST=example.com", "PGSSLMODE=verify-ca"},
339+
"host=example.com port=1 sslmode=verify-ca user=u", ""},
340340

341341
// Socket
342-
{"host=/var/run/psql", nil, "host=/var/run/psql sslmode=disable", ""},
343-
{"host=@/var/run/psql", nil, "host=@/var/run/psql sslmode=disable", ""},
342+
{"host=/var/run/psql", nil, "host=/var/run/psql", ""},
343+
{"host=@/var/run/psql", nil, "host=@/var/run/psql", ""},
344344
{"host=/var/run/psql sslmode=require", nil, "host=/var/run/psql sslmode=disable", ""},
345345

346346
// Empty value, value with space, and value with escaped \'
@@ -903,16 +903,16 @@ func TestService(t *testing.T) {
903903
wantErr string
904904
}{
905905
{"service=doesntexist", nil, ``, `definition of service "doesntexist" not found`},
906-
{"service=svc1", nil, `connect_timeout=20 dbname=xyz host=firsthost port=1234 service=svc1 sslmode=disable user=pqgo`, ``},
907-
{"service=svc2", nil, `connect_timeout=20 dbname='with space' host=localhost service=svc2 sslmode=disable user=''`, ``},
906+
{"service=svc1", nil, `connect_timeout=20 dbname=xyz host=firsthost port=1234 service=svc1 user=pqgo`, ``},
907+
{"service=svc2", nil, `connect_timeout=20 dbname='with space' host=localhost service=svc2 user=''`, ``},
908908
{"service=svc3", nil, ``, `pq: unknown setting "unknown" in service file for service "svc3"`},
909-
{"service=svc4", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc4 sslmode=disable user=pqgo`, ``},
910-
{"service=svc5", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc5 sslmode=disable user=pqgo`, ``},
909+
{"service=svc4", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc4 user=pqgo`, ``},
910+
{"service=svc5", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc5 user=pqgo`, ``},
911911

912912
{"service=svc5", map[string]string{"PGSERVICEFILE": "none"}, ``, `service file "none" not found`},
913913
{"service=svc1", map[string]string{"PGSERVICEFILE": filepath.Join(h, "other")}, ``, `definition of service "svc1" not found`},
914914
{"service=other", map[string]string{"PGSERVICEFILE": filepath.Join(h, "other")},
915-
`connect_timeout=20 dbname=other host=localhost service=other sslmode=disable user=pqgo`, ``},
915+
`connect_timeout=20 dbname=other host=localhost service=other user=pqgo`, ``},
916916
}
917917

918918
pqtest.Write(t, []byte("[other]\ndbname=other"), h, "other")

error_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func TestRetryError(t *testing.T) {
253253
}
254254

255255
func TestNetworkError(t *testing.T) {
256-
c, err := NewConnector("")
256+
c, err := NewConnector("sslmode=disable")
257257
if err != nil {
258258
t.Fatal(err)
259259
}

internal/pqtest/pqtest.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ func DSN(conninfo string) string {
8585
defaultTo("PGHOST", "localhost")
8686
defaultTo("PGDATABASE", "pqgo")
8787
defaultTo("PGUSER", "pqgo")
88-
defaultTo("PGSSLMODE", "disable")
8988
defaultTo("PGCONNECT_TIMEOUT", "20")
9089
os.Setenv("PGAPPNAME", "pqgo")
9190
})

ssl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func ssl(cfg Config, mode SSLMode) (func(net.Conn) (net.Conn, error), error) {
8282
case mode == SSLModeDisable || mode == SSLModeAllow:
8383
return nil, nil
8484

85-
case mode == "" || mode == SSLModeRequire || mode == SSLModePrefer:
85+
case mode == SSLModeRequire || mode == SSLModePrefer:
8686
// Skip TLS's own verification since it requires full verification.
8787
tlsConf.InsecureSkipVerify = true
8888

ssl_test.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"fmt"
1010
"io"
1111
"net"
12-
"os"
1312
"testing"
1413
"time"
1514

@@ -52,6 +51,10 @@ func TestSSLMode(t *testing.T) {
5251
connect string
5352
wantErr string
5453
}{
54+
// Default (prefer) should work both with and without ssl.
55+
{"user=pqgossl", ""},
56+
{f.DSN(), ""},
57+
5558
// sslmode=require: require SSL, but don't verify certificate.
5659
{"sslmode=require user=pqgossl", ""},
5760
{"sslmode=require " + f.DSN(), "pq: SSL is not enabled on the server"},
@@ -384,12 +387,7 @@ func TestSSLDefaults(t *testing.T) {
384387
func TestSSLRootCA(t *testing.T) {
385388
startSSLTest(t, "pqgossl")
386389

387-
// TODO: can remove this once https://github.com/lib/pq/pull/1271 is merged.
388-
os.Unsetenv("PGSSLMODE")
389-
t.Cleanup(func() {
390-
os.Setenv("PGSSLMODE", "disable")
391-
testSystemRoots = nil
392-
})
390+
t.Cleanup(func() { testSystemRoots = nil })
393391
testSystemRoots = x509.NewCertPool()
394392
if !testSystemRoots.AppendCertsFromPEM(pqtest.Read(t, "testdata/ssl/root.crt")) {
395393
t.Fatal()

0 commit comments

Comments
 (0)