On mån, 2012-01-02 at 06:32 +0200, Peter Eisentraut wrote:
> I think I would like to have a set of GUC parameters to control the
> location of the server-side SSL files.
Here is the patch for this.
One thing that is perhaps worth thinking about: Currently, we just
ignore missing root.crt and root.crl files. With this patch, we still
do this, even if the user has given a specific nondefault location.
That seems a bit odd, but I can't think of a simple way to do it better.
diff --git i/doc/src/sgml/config.sgml w/doc/src/sgml/config.sgml
index 0cc3296..519715f 100644
--- i/doc/src/sgml/config.sgml
+++ w/doc/src/sgml/config.sgml
@@ -668,6 +668,66 @@ SET ENABLE_SEQSCAN TO OFF;
</listitem>
</varlistentry>
+ <varlistentry id="guc-ssl-ca-file" xreflabel="ssl_ca_file">
+ <term><varname>ssl_ca_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_ca_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate
+ authority. The default is <filename>root.crt</filename>. Relative
+ paths are relative to the data directory. This parameter can only be
+ set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-cert-file" xreflabel="ssl_cert_file">
+ <term><varname>ssl_cert_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_cert_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate.
+ The default is <filename>server.crt</filename>. Relative paths are
+ relative to the data directory. This parameter can only be set at
+ server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-crl-file" xreflabel="ssl_crl_file">
+ <term><varname>ssl_crl_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_crl_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate
+ revocation list. The default is <filename>root.crl</filename>.
+ Relative paths are relative to the data directory. This parameter can
+ only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-key-file" xreflabel="ssl_key_file">
+ <term><varname>ssl_key_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_key_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server private key.
+ The default is <filename>server.key</filename>. Relative paths are
+ relative to the data directory. This parameter can only be set at
+ server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-ssl-renegotiation-limit" xreflabel="ssl_renegotiation_limit">
<term><varname>ssl_renegotiation_limit</varname> (<type>integer</type>)</term>
<indexterm>
diff --git i/doc/src/sgml/runtime.sgml w/doc/src/sgml/runtime.sgml
index 1c3a9c8..a855279 100644
--- i/doc/src/sgml/runtime.sgml
+++ w/doc/src/sgml/runtime.sgml
@@ -1831,10 +1831,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
SSL certificates and make sure that clients check the server's certificate.
To do that, the server
must be configured to accept only <literal>hostssl</> connections (<xref
- linkend="auth-pg-hba-conf">) and have SSL
- <filename>server.key</filename> (key) and
- <filename>server.crt</filename> (certificate) files (<xref
- linkend="ssl-tcp">). The TCP client must connect using
+ linkend="auth-pg-hba-conf">) and have SSL key and certificate files
+ (<xref linkend="ssl-tcp">). The TCP client must connect using
<literal>sslmode=verify-ca</> or
<literal>verify-full</> and have the appropriate root certificate
file installed (<xref linkend="libpq-connect">).
@@ -2053,10 +2051,12 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
</note>
<para>
- To start in <acronym>SSL</> mode, the files <filename>server.crt</>
- and <filename>server.key</> must exist in the server's data directory.
- These files should contain the server certificate and private key,
- respectively.
+ To start in <acronym>SSL</> mode, files containing the server certificate
+ and private key must exist. By default, these files are expected to be
+ named <filename>server.crt</> and <filename>server.key</>, respectively, in
+ the server's data directory, but other names and locations can be specified
+ using the configuration parameters <xref linkend="guc-ssl-cert-file">
+ and <xref linkend="guc-ssl-key-file">.
On Unix systems, the permissions on <filename>server.key</filename> must
disallow any access to world or group; achieve this by the command
<command>chmod 0600 server.key</command>.
@@ -2144,27 +2144,27 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
<tbody>
<row>
- <entry><filename>$PGDATA/server.crt</></entry>
+ <entry><xref linkend="guc-ssl-cert-file"> (<filename>$PGDATA/server.crt</>)</entry>
<entry>server certificate</entry>
<entry>sent to client to indicate server's identity</entry>
</row>
<row>
- <entry><filename>$PGDATA/server.key</></entry>
+ <entry><xref linkend="guc-ssl-key-file"> (<filename>$PGDATA/server.key</>)</entry>
<entry>server private key</entry>
<entry>proves server certificate was sent by the owner; does not indicate
certificate owner is trustworthy</entry>
</row>
<row>
- <entry><filename>$PGDATA/root.crt</></entry>
+ <entry><xref linkend="guc-ssl-ca-file"> (<filename>$PGDATA/root.crt</>)</entry>
<entry>trusted certificate authorities</entry>
<entry>checks that client certificate is
signed by a trusted certificate authority</entry>
</row>
<row>
- <entry><filename>$PGDATA/root.crl</></entry>
+ <entry><xref linkend="guc-ssl-crl-file"> (<filename>$PGDATA/root.crl</>)</entry>
<entry>certificates revoked by certificate authorities</entry>
<entry>client certificate must not be on this list</entry>
</row>
@@ -2176,6 +2176,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
<para>
The files <filename>server.key</>, <filename>server.crt</>,
<filename>root.crt</filename>, and <filename>root.crl</filename>
+ (or their configured alternative names)
are only examined during server start; so you must restart
the server for changes in them to take effect.
</para>
diff --git i/src/backend/libpq/be-secure.c w/src/backend/libpq/be-secure.c
index e35df73..1e34e56 100644
--- i/src/backend/libpq/be-secure.c
+++ w/src/backend/libpq/be-secure.c
@@ -77,10 +77,10 @@
#ifdef USE_SSL
-#define ROOT_CERT_FILE "root.crt"
-#define ROOT_CRL_FILE "root.crl"
-#define SERVER_CERT_FILE "server.crt"
-#define SERVER_PRIVATE_KEY_FILE "server.key"
+char *ssl_cert_file;
+char *ssl_key_file;
+char *ssl_ca_file;
+char *ssl_crl_file;
static DH *load_dh_file(int keylength);
static DH *load_dh_buffer(const char *, size_t);
@@ -746,17 +746,17 @@ initialize_SSL(void)
* Load and verify server's certificate and private key
*/
if (SSL_CTX_use_certificate_chain_file(SSL_context,
- SERVER_CERT_FILE) != 1)
+ ssl_cert_file) != 1)
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not load server certificate file \"%s\": %s",
- SERVER_CERT_FILE, SSLerrmessage())));
+ ssl_cert_file, SSLerrmessage())));
- if (stat(SERVER_PRIVATE_KEY_FILE, &buf) != 0)
+ if (stat(ssl_key_file, &buf) != 0)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not access private key file \"%s\": %m",
- SERVER_PRIVATE_KEY_FILE)));
+ ssl_key_file)));
/*
* Require no public access to key file.
@@ -771,16 +771,16 @@ initialize_SSL(void)
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("private key file \"%s\" has group or world access",
- SERVER_PRIVATE_KEY_FILE),
+ ssl_key_file),
errdetail("Permissions should be u=rw (0600) or less.")));
#endif
if (SSL_CTX_use_PrivateKey_file(SSL_context,
- SERVER_PRIVATE_KEY_FILE,
+ ssl_key_file,
SSL_FILETYPE_PEM) != 1)
ereport(FATAL,
(errmsg("could not load private key file \"%s\": %s",
- SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
+ ssl_key_file, SSLerrmessage())));
if (SSL_CTX_check_private_key(SSL_context) != 1)
ereport(FATAL,
@@ -802,7 +802,7 @@ initialize_SSL(void)
*/
ssl_loaded_verify_locations = false;
- if (access(ROOT_CERT_FILE, R_OK) != 0)
+ if (access(ssl_ca_file, R_OK) != 0)
{
/*
* If root certificate file simply not found, don't log an error here,
@@ -813,10 +813,10 @@ initialize_SSL(void)
if (errno != ENOENT)
ereport(FATAL,
(errmsg("could not access root certificate file \"%s\": %m",
- ROOT_CERT_FILE)));
+ ssl_ca_file)));
}
- else if (SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL) != 1 ||
- (root_cert_list = SSL_load_client_CA_file(ROOT_CERT_FILE)) == NULL)
+ else if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
+ (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
{
/*
* File was there, but we could not load it. This means the file is
@@ -824,7 +824,7 @@ initialize_SSL(void)
*/
ereport(FATAL,
(errmsg("could not load root certificate file \"%s\": %s",
- ROOT_CERT_FILE, SSLerrmessage())));
+ ssl_ca_file, SSLerrmessage())));
}
else
{
@@ -838,7 +838,7 @@ initialize_SSL(void)
if (cvstore)
{
/* Set the flags to check against the complete CRL chain */
- if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) == 1)
+ if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
{
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
#ifdef X509_V_FLAG_CRL_CHECK
@@ -847,7 +847,7 @@ initialize_SSL(void)
#else
ereport(LOG,
(errmsg("SSL certificate revocation list file \"%s\" ignored",
- ROOT_CRL_FILE),
+ ssl_crl_file),
errdetail("SSL library does not support certificate revocation lists.")));
#endif
}
@@ -856,7 +856,7 @@ initialize_SSL(void)
/* Not fatal - we do not require CRL */
ereport(LOG,
(errmsg("SSL certificate revocation list file \"%s\" not found, skipping: %s",
- ROOT_CRL_FILE, SSLerrmessage()),
+ ssl_crl_file, SSLerrmessage()),
errdetail("Certificates will not be checked against revocation list.")));
}
diff --git i/src/backend/utils/misc/guc.c w/src/backend/utils/misc/guc.c
index 5c910dd..11006ea 100644
--- i/src/backend/utils/misc/guc.c
+++ w/src/backend/utils/misc/guc.c
@@ -39,6 +39,7 @@
#include "funcapi.h"
#include "libpq/auth.h"
#include "libpq/be-fsstubs.h"
+#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
@@ -2961,6 +2962,46 @@ static struct config_string ConfigureNamesString[] =
},
{
+ {"ssl_cert_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL server certificate file."),
+ NULL
+ },
+ &ssl_cert_file,
+ "server.crt",
+ NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_key_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL server private key file."),
+ NULL
+ },
+ &ssl_key_file,
+ "server.key",
+ NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_ca_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL certificate authority file."),
+ NULL
+ },
+ &ssl_ca_file,
+ "root.crt",
+ NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_crl_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL certificate revocation list file."),
+ NULL
+ },
+ &ssl_crl_file,
+ "root.crl",
+ NULL, NULL, NULL
+ },
+
+ {
{"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR,
gettext_noop("Writes temporary statistics files to the specified directory."),
NULL,
diff --git i/src/backend/utils/misc/postgresql.conf.sample w/src/backend/utils/misc/postgresql.conf.sample
index 315db46..658c293 100644
--- i/src/backend/utils/misc/postgresql.conf.sample
+++ w/src/backend/utils/misc/postgresql.conf.sample
@@ -81,6 +81,10 @@
#ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
# (change requires restart)
#ssl_renegotiation_limit = 512MB # amount of data between renegotiations
+#ssl_cert_file = 'server.crt' # (change requires restart)
+#ssl_key_file = 'server.key' # (change requires restart)
+#ssl_ca_file = 'root.crt' # (change requires restart)
+#ssl_crl_file = 'root.crl' # (change requires restart)
#password_encryption = on
#db_user_namespace = off
diff --git i/src/include/libpq/libpq.h w/src/include/libpq/libpq.h
index a4ef7b3..7083cd8 100644
--- i/src/include/libpq/libpq.h
+++ w/src/include/libpq/libpq.h
@@ -70,6 +70,11 @@ extern void pq_endcopyout(bool errorAbort);
/*
* prototypes for functions in be-secure.c
*/
+extern char *ssl_cert_file;
+extern char *ssl_key_file;
+extern char *ssl_ca_file;
+extern char *ssl_crl_file;
+
extern int secure_initialize(void);
extern bool secure_loaded_verify_locations(void);
extern void secure_destroy(void);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers