Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b0b39f7

Browse files
committed
GSSAPI encryption support
On both the frontend and backend, prepare for GSSAPI encryption support by moving common code for error handling into a separate file. Fix a TODO for handling multiple status messages in the process. Eliminate the OIDs, which have not been needed for some time. Add frontend and backend encryption support functions. Keep the context initiation for authentication-only separate on both the frontend and backend in order to avoid concerns about changing the requested flags to include encryption support. In postmaster, pull GSSAPI authorization checking into a shared function. Also share the initiator name between the encryption and non-encryption codepaths. For HBA, add "hostgssenc" and "hostnogssenc" entries that behave similarly to their SSL counterparts. "hostgssenc" requires either "gss", "trust", or "reject" for its authentication. Similarly, add a "gssencmode" parameter to libpq. Supported values are "disable", "require", and "prefer". Notably, negotiation will only be attempted if credentials can be acquired. Move credential acquisition into its own function to support this behavior. Add a simple pg_stat_gssapi view similar to pg_stat_ssl, for monitoring if GSSAPI authentication was used, what principal was used, and if encryption is being used on the connection. Finally, add documentation for everything new, and update existing documentation on connection security. Thanks to Michael Paquier for the Windows fixes. Author: Robbie Harwood, with changes to the read/write functions by me. Reviewed in various forms and at different times by: Michael Paquier, Andres Freund, David Steele. Discussion: https://www.postgresql.org/message-id/flat/jlg1tgq1ktm.fsf@thriss.redhat.com
1 parent 5f6fc34 commit b0b39f7

35 files changed

+2575
-197
lines changed

doc/src/sgml/client-auth.sgml

+62-16
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
108108
host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
109109
hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
110110
hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
111+
hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
112+
hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
111113
</synopsis>
112114
The meaning of the fields is as follows:
113115

@@ -128,9 +130,10 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
128130
<listitem>
129131
<para>
130132
This record matches connection attempts made using TCP/IP.
131-
<literal>host</literal> records match either
133+
<literal>host</literal> records match
132134
<acronym>SSL</acronym> or non-<acronym>SSL</acronym> connection
133-
attempts.
135+
attempts as well as <acronym>GSSAPI</acronym> encrypted or
136+
non-<acronym>GSSAPI</acronym> encrypted connection attempts.
134137
</para>
135138
<note>
136139
<para>
@@ -176,6 +179,42 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
176179
</listitem>
177180
</varlistentry>
178181

182+
<varlistentry>
183+
<term><literal>hostgssenc</literal></term>
184+
<listitem>
185+
<para>
186+
This record matches connection attempts made using TCP/IP,
187+
but only when the connection is made with <acronym>GSSAPI</acronym>
188+
encryption.
189+
</para>
190+
191+
<para>
192+
To make use of this option the server must be built with
193+
<acronym>GSSAPI</acronym> support. Otherwise,
194+
the <literal>hostgssenc</literal> record is ignored except for logging
195+
a warning that it cannot match any connections.
196+
</para>
197+
198+
<para>
199+
Note that the only supported <xref linkend="auth-methods"/> for use
200+
with <acronym>GSSAPI</acronym> encryption
201+
are <literal>gss</literal>, <literal>reject</literal>,
202+
and <literal>trust</literal>.
203+
</para>
204+
</listitem>
205+
</varlistentry>
206+
207+
<varlistentry>
208+
<term><literal>hostnogssenc</literal></term>
209+
<listitem>
210+
<para>
211+
This record type has the opposite behavior of <literal>hostgssenc</literal>;
212+
it only matches connection attempts made over
213+
TCP/IP that do not use <acronym>GSSAPI</acronym> encryption.
214+
</para>
215+
</listitem>
216+
</varlistentry>
217+
179218
<varlistentry>
180219
<term><replaceable>database</replaceable></term>
181220
<listitem>
@@ -450,8 +489,9 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
450489
<listitem>
451490
<para>
452491
Use GSSAPI to authenticate the user. This is only
453-
available for TCP/IP connections. See <xref
454-
linkend="gssapi-auth"/> for details.
492+
available for TCP/IP connections . See <xref
493+
linkend="gssapi-auth"/> for details. It can be used in conjunction
494+
with GSSAPI encryption.
455495
</para>
456496
</listitem>
457497
</varlistentry>
@@ -703,15 +743,18 @@ host postgres all 192.168.12.10/32 scram-sha-256
703743
host all mike .example.com md5
704744
host all all .example.com scram-sha-256
705745

706-
# In the absence of preceding "host" lines, these two lines will
746+
# In the absence of preceding "host" lines, these three lines will
707747
# reject all connections from 192.168.54.1 (since that entry will be
708-
# matched first), but allow GSSAPI connections from anywhere else
709-
# on the Internet. The zero mask causes no bits of the host IP
710-
# address to be considered, so it matches any host.
748+
# matched first), but allow GSSAPI-encrypted connections from anywhere else
749+
# on the Internet. The zero mask causes no bits of the host IP address to
750+
# be considered, so it matches any host. Unencrypted GSSAPI connections
751+
# (which "fall through" to the third line since "hostgssenc" only matches
752+
# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10.
711753
#
712754
# TYPE DATABASE USER ADDRESS METHOD
713755
host all all 192.168.54.1/32 reject
714-
host all all 0.0.0.0/0 gss
756+
hostgssenc all all 0.0.0.0/0 gss
757+
host all all 192.168.12.10/32 gss
715758

716759
# Allow users from 192.168.x.x hosts to connect to any database, if
717760
# they pass the ident check. If, for example, ident says the user is
@@ -1058,13 +1101,16 @@ omicron bryanh guest1
10581101
<para>
10591102
<productname>GSSAPI</productname> is an industry-standard protocol
10601103
for secure authentication defined in RFC 2743.
1061-
<productname>PostgreSQL</productname> supports
1062-
<productname>GSSAPI</productname> with <productname>Kerberos</productname>
1063-
authentication according to RFC 1964. <productname>GSSAPI</productname>
1064-
provides automatic authentication (single sign-on) for systems
1065-
that support it. The authentication itself is secure, but the
1066-
data sent over the database connection will be sent unencrypted unless
1067-
<acronym>SSL</acronym> is used.
1104+
1105+
<productname>PostgreSQL</productname>
1106+
supports <productname>GSSAPI</productname> for use as either an encrypted,
1107+
authenticated layer, or for authentication only.
1108+
<productname>GSSAPI</productname> provides automatic authentication
1109+
(single sign-on) for systems that support it. The authentication itself is
1110+
secure. If <productname>GSSAPI</productname> encryption
1111+
(see <literal>hostgssenc</literal>) or <acronym>SSL</acronym> encryption are
1112+
used, the data sent along the database connection will be encrypted;
1113+
otherwise, it will not.
10681114
</para>
10691115

10701116
<para>

doc/src/sgml/libpq.sgml

+58-1
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,63 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
13161316
</listitem>
13171317
</varlistentry>
13181318

1319+
<varlistentry id="libpq-connect-gssencmode" xreflabel="gssencmode">
1320+
<term><literal>gssencmode</literal></term>
1321+
<listitem>
1322+
<para>
1323+
This option determines whether or with what priority a secure
1324+
<acronym>GSS</acronym> TCP/IP connection will be negotiated with the
1325+
server. There are three modes:
1326+
1327+
<variablelist>
1328+
<varlistentry>
1329+
<term><literal>disable</literal></term>
1330+
<listitem>
1331+
<para>
1332+
only try a non-<acronym>GSSAPI</acronym>-encrypted connection
1333+
</para>
1334+
</listitem>
1335+
</varlistentry>
1336+
1337+
<varlistentry>
1338+
<term><literal>prefer</literal> (default)</term>
1339+
<listitem>
1340+
<para>
1341+
if there are <acronym>GSSAPI</acronym> credentials present (i.e.,
1342+
in a credentials cache), first try
1343+
a <acronym>GSSAPI</acronym>-encrypted connection; if that fails or
1344+
there are no credentials, try a
1345+
non-<acronym>GSSAPI</acronym>-encrypted connection. This is the
1346+
default when <productname>PostgreSQL</productname> has been
1347+
compiled with <acronym>GSSAPI</acronym> support.
1348+
</para>
1349+
</listitem>
1350+
</varlistentry>
1351+
1352+
<varlistentry>
1353+
<term><literal>require</literal></term>
1354+
<listitem>
1355+
<para>
1356+
only try a <acronym>GSSAPI</acronym>-encrypted connection
1357+
</para>
1358+
</listitem>
1359+
</varlistentry>
1360+
</variablelist>
1361+
</para>
1362+
1363+
<para>
1364+
<literal>gssencmode</literal> is ignored for Unix domain socket
1365+
communication. If <productname>PostgreSQL</productname> is compiled
1366+
without GSSAPI support, using the <literal>require</literal> option
1367+
will cause an error, while <literal>prefer</literal> will be accepted
1368+
but <application>libpq</application> will not actually attempt
1369+
a <acronym>GSSAPI</acronym>-encrypted
1370+
connection.<indexterm><primary>GSSAPI</primary><secondary sortas="libpq">with
1371+
libpq</secondary></indexterm>
1372+
</para>
1373+
</listitem>
1374+
</varlistentry>
1375+
13191376
<varlistentry id="libpq-connect-sslmode" xreflabel="sslmode">
13201377
<term><literal>sslmode</literal></term>
13211378
<listitem>
@@ -7948,7 +8005,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
79488005
</para>
79498006

79508007
<para>
7951-
For a connection to be known secure, SSL usage must be configured
8008+
For a connection to be known SSL-secured, SSL usage must be configured
79528009
on <emphasis>both the client and the server</emphasis> before the connection
79538010
is made. If it is only configured on the server, the client may end up
79548011
sending sensitive information (e.g. passwords) before

doc/src/sgml/monitoring.sgml

+57
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
336336
</entry>
337337
</row>
338338

339+
<row>
340+
<entry><structname>pg_stat_gssapi</structname><indexterm><primary>pg_stat_gssapi</primary></indexterm></entry>
341+
<entry>One row per connection (regular and replication), showing information about
342+
GSSAPI authentication and encryption used on this connection.
343+
See <xref linkend="pg-stat-gssapi-view"/> for details.
344+
</entry>
345+
</row>
346+
339347
<row>
340348
<entry><structname>pg_stat_progress_create_index</structname><indexterm><primary>pg_stat_progress_create_index</primary></indexterm></entry>
341349
<entry>One row for each backend running <command>CREATE INDEX</command>, showing
@@ -2281,6 +2289,55 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
22812289
connection.
22822290
</para>
22832291

2292+
<table id="pg-stat-gssapi-view" xreflabel="pg_stat_gssapi">
2293+
<title><structname>pg_stat_gssapi</structname> View</title>
2294+
<tgroup cols="3">
2295+
<thead>
2296+
<row>
2297+
<entry>Column</entry>
2298+
<entry>Type</entry>
2299+
<entry>Description</entry>
2300+
</row>
2301+
</thead>
2302+
2303+
<tbody>
2304+
<row>
2305+
<entry><structfield>pid</structfield></entry>
2306+
<entry><type>integer</type></entry>
2307+
<entry>Process ID of a backend</entry>
2308+
</row>
2309+
<row>
2310+
<entry><structfield>gss_authenticated</structfield></entry>
2311+
<entry><type>boolean</type></entry>
2312+
<entry>True if GSSAPI authentication was used for this connection</entry>
2313+
</row>
2314+
<row>
2315+
<entry><structfield>principal</structfield></entry>
2316+
<entry><type>text</type></entry>
2317+
<entry>Principal used to authenticate this connection, or NULL
2318+
if GSSAPI was not used to authenticate this connection. This
2319+
field is truncated if the principal is longer than
2320+
<symbol>NAMEDATALEN</symbol> (64 characters in a standard build).
2321+
</entry>
2322+
</row>
2323+
<row>
2324+
<entry><structfield>encrypted</structfield></entry>
2325+
<entry><type>boolean</type></entry>
2326+
<entry>True if GSSAPI encryption is in use on this connection</entry>
2327+
</row>
2328+
</tbody>
2329+
</tgroup>
2330+
</table>
2331+
2332+
<para>
2333+
The <structname>pg_stat_gssapi</structname> view will contain one row per
2334+
backend, showing information about GSSAPI usage on this connection. It can
2335+
be joined to <structname>pg_stat_activity</structname> or
2336+
<structname>pg_stat_replication</structname> on the
2337+
<structfield>pid</structfield> column to get more details about the
2338+
connection.
2339+
</para>
2340+
22842341

22852342
<table id="pg-stat-archiver-view" xreflabel="pg_stat_archiver">
22862343
<title><structname>pg_stat_archiver</structname> View</title>

doc/src/sgml/runtime.sgml

+72-5
Original file line numberDiff line numberDiff line change
@@ -2037,16 +2037,28 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
20372037
</para>
20382038

20392039
<para>
2040-
To prevent spoofing on TCP connections, the best solution is to use
2041-
SSL certificates and make sure that clients check the server's certificate.
2042-
To do that, the server
2040+
To prevent spoofing on TCP connections, either use
2041+
SSL certificates and make sure that clients check the server's certificate,
2042+
or use GSSAPI encryption (or both, if they're on separate connections).
2043+
</para>
2044+
2045+
<para>
2046+
To prevent spoofing with SSL, the server
20432047
must be configured to accept only <literal>hostssl</literal> connections (<xref
20442048
linkend="auth-pg-hba-conf"/>) and have SSL key and certificate files
20452049
(<xref linkend="ssl-tcp"/>). The TCP client must connect using
20462050
<literal>sslmode=verify-ca</literal> or
20472051
<literal>verify-full</literal> and have the appropriate root certificate
20482052
file installed (<xref linkend="libq-ssl-certificates"/>).
20492053
</para>
2054+
2055+
<para>
2056+
To prevent spoofing with GSSAPI, the server must be configured to accept
2057+
only <literal>hostgssenc</literal> connections
2058+
(<xref linkend="auth-pg-hba-conf"/>) and use <literal>gss</literal>
2059+
authentication with them. The TCP client must connect
2060+
using <literal>gssencmode=require</literal>.
2061+
</para>
20502062
</sect1>
20512063

20522064
<sect1 id="encryption-options">
@@ -2143,8 +2155,24 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
21432155
which hosts can use non-encrypted connections (<literal>host</literal>)
21442156
and which require SSL-encrypted connections
21452157
(<literal>hostssl</literal>). Also, clients can specify that they
2146-
connect to servers only via SSL. <application>Stunnel</application> or
2147-
<application>SSH</application> can also be used to encrypt transmissions.
2158+
connect to servers only via SSL.
2159+
</para>
2160+
2161+
<para>
2162+
GSSAPI-encrypted connections encrypt all data sent across the network,
2163+
including queries and data returned. (No password is sent across the
2164+
network.) The <filename>pg_hba.conf</filename> file allows
2165+
administrators to specify which hosts can use non-encrypted connections
2166+
(<literal>host</literal>) and which require GSSAPI-encrypted connections
2167+
(<literal>hostgssenc</literal>). Also, clients can specify that they
2168+
connect to servers only on GSSAPI-encrypted connections
2169+
(<literal>gssencmode=require</literal>).
2170+
</para>
2171+
2172+
<para>
2173+
<application>Stunnel</application> or
2174+
<application>SSH</application> can also be used to encrypt
2175+
transmissions.
21482176
</para>
21492177
</listitem>
21502178
</varlistentry>
@@ -2561,6 +2589,45 @@ openssl x509 -req -in server.csr -text -days 365 \
25612589

25622590
</sect1>
25632591

2592+
<sect1 id="gssapi-enc">
2593+
<title>Secure TCP/IP Connections with GSSAPI encryption</title>
2594+
2595+
<indexterm zone="gssapi-enc">
2596+
<primary>gssapi</primary>
2597+
</indexterm>
2598+
2599+
<para>
2600+
<productname>PostgreSQL</productname> also has native support for
2601+
using <acronym>GSSAPI</acronym> to encrypt client/server communications for
2602+
increased security. Support requires that a <acronym>GSSAPI</acronym>
2603+
implementation (such as MIT krb5) is installed on both client and server
2604+
systems, and that support in <productname>PostgreSQL</productname> is
2605+
enabled at build time (see <xref linkend="installation"/>).
2606+
</para>
2607+
2608+
<sect2 id="gssapi-setup">
2609+
<title>Basic Setup</title>
2610+
2611+
<para>
2612+
The <productname>PostgreSQL</productname> server will listen for both
2613+
normal and <acronym>GSSAPI</acronym>-encrypted connections on the same TCP
2614+
port, and will negotiate with any connecting client on whether to
2615+
use <acronym>GSSAPI</acronym> for encryption (and for authentication). By
2616+
default, this decision is up to the client (which means it can be
2617+
downgraded by an attacker); see <xref linkend="auth-pg-hba-conf"/> about
2618+
setting up the server to require the use of <acronym>GSSAPI</acronym> for
2619+
some or all conections.
2620+
</para>
2621+
2622+
<para>
2623+
Other than configuration of the negotiation
2624+
behavior, <acronym>GSSAPI</acronym> encryption requires no setup beyond
2625+
that which is necessary for GSSAPI authentication. (For more information
2626+
on configuring that, see <xref linkend="gssapi-auth"/>.)
2627+
</para>
2628+
</sect2>
2629+
</sect1>
2630+
25642631
<sect1 id="ssh-tunnels">
25652632
<title>Secure TCP/IP Connections with <application>SSH</application> Tunnels</title>
25662633

src/backend/catalog/system_views.sql

+8
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,14 @@ CREATE VIEW pg_stat_ssl AS
787787
S.ssl_issuer_dn AS issuer_dn
788788
FROM pg_stat_get_activity(NULL) AS S;
789789

790+
CREATE VIEW pg_stat_gssapi AS
791+
SELECT
792+
S.pid,
793+
S.gss_auth AS gss_authenticated,
794+
S.gss_princ AS principal,
795+
S.gss_enc AS encrypted
796+
FROM pg_stat_get_activity(NULL) AS S;
797+
790798
CREATE VIEW pg_replication_slots AS
791799
SELECT
792800
L.slot_name,

src/backend/libpq/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@ ifeq ($(with_openssl),yes)
2121
OBJS += be-secure-openssl.o
2222
endif
2323

24+
ifeq ($(with_gssapi),yes)
25+
OBJS += be-gssapi-common.o be-secure-gssapi.o
26+
endif
27+
2428
include $(top_srcdir)/src/backend/common.mk

0 commit comments

Comments
 (0)