]> granicus.if.org Git - postgresql/commitdiff
Improve SSL-related documentation. Explain how to deal with certificate
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 26 May 2010 23:49:19 +0000 (23:49 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 26 May 2010 23:49:19 +0000 (23:49 +0000)
chains, do assorted wordsmithing.

doc/src/sgml/client-auth.sgml
doc/src/sgml/config.sgml
doc/src/sgml/libpq.sgml
doc/src/sgml/runtime.sgml

index d2f30a47c4eed8f70b6f5b48389b1937fcb86c63..1c145b578a49a0153d0efba7c27ccedd5baf98ec 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.137 2010/04/21 03:32:53 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.138 2010/05/26 23:49:18 tgl Exp $ -->
 
 <chapter id="client-authentication">
  <title>Client Authentication</title>
@@ -314,9 +314,9 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
         <listitem>
          <para>
           Reject the connection unconditionally. This is useful for
-          <quote>filtering out</> certain hosts from a group, e.g. a
-          <literal>reject</> line blocks a specific host from connecting,
-          but a later line allows the remaining hosts in a specific
+          <quote>filtering out</> certain hosts from a group, for example a
+          <literal>reject</> line could block a specific host from connecting,
+          while a later line allows the remaining hosts in a specific
           network to connect.
          </para>
         </listitem>
@@ -446,7 +446,7 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
        After the <replaceable>auth-method</> field, there can be field(s) of
        the form <replaceable>name</><literal>=</><replaceable>value</> that
        specify options for the authentication method. Details about which
-       options are available for which authentication method appear below.
+       options are available for which authentication methods appear below.
       </para>
      </listitem>
     </varlistentry>
@@ -624,17 +624,15 @@ local   db1,db2,@demodbs  all                                   md5
    in a map should be thought of as meaning <quote>this operating system
    user is allowed to connect as this database user</quote>, rather than
    implying that they are equivalent.  The connection will be allowed if
-   there is any map entry that matches the user name obtained from the
-   external authentication system to the database user name that the
+   there is any map entry that pairs the user name obtained from the
+   external authentication system with the database user name that the
    user has requested to connect as.
   </para>
   <para>
    If the <replaceable>system-username</> field starts with a slash (<literal>/</>),
    the remainder of the field is treated as a regular expression.
    (See <xref linkend="posix-syntax-details"> for details of
-   <productname>PostgreSQL</>'s regular expression syntax.
-   Regular expressions in username maps are always treated as being
-   <quote>advanced</> flavor.)  The regular
+   <productname>PostgreSQL</>'s regular expression syntax.)  The regular
    expression can include a single capture, or parenthesized subexpression,
    which can then be referenced in the <replaceable>database-username</>
    field as <literal>\1</> (backslash-one).  This allows the mapping of
@@ -768,7 +766,7 @@ omicron         bryanh                  guest1
     The password-based authentication methods are <literal>md5</>
     and <literal>password</>. These methods operate
     similarly except for the way that the password is sent across the
-    connection, i.e. respectively, MD5-hashed and clear-text.
+    connection, namely MD5-hashed and clear-text respectively.
    </para>
 
    <para>
@@ -811,7 +809,7 @@ omicron         bryanh                  guest1
     authentication according to RFC 1964. <productname>GSSAPI</productname>
     provides automatic authentication (single sign-on) for systems
     that support it. The authentication itself is secure, but the
-    data sent over the database connection will be send unencrypted unless
+    data sent over the database connection will be sent unencrypted unless
     <acronym>SSL</acronym> is used.
    </para>
 
@@ -821,6 +819,9 @@ omicron         bryanh                  guest1
     in the format
     <literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>. For information about the parts of the principal, and
     how to set up the required keys, see <xref linkend="kerberos-auth">.
+   </para>
+
+   <para>
     GSSAPI support has to be enabled when <productname>PostgreSQL</> is built;
     see <xref linkend="installation"> for more information.
    </para>
@@ -845,7 +846,7 @@ omicron         bryanh                  guest1
       <listitem>
        <para>
         Allows for mapping between system and database usernames. See
-        <xref linkend="auth-username-maps"> for details. For a Kerboros
+        <xref linkend="auth-username-maps"> for details. For a Kerberos
         principal <literal>username/hostbased@EXAMPLE.COM</literal>, the
         username used for mapping is <literal>username/hostbased</literal>
         if <literal>include_realm</literal> is disabled, and
@@ -948,7 +949,7 @@ omicron         bryanh                  guest1
      Native Kerberos authentication has been deprecated and should be used
      only for backward compatibility. New and upgraded installations are
      encouraged to use the industry-standard <productname>GSSAPI</productname>
-     authentication (see <xref linkend="gssapi-auth">) instead.
+     authentication method (see <xref linkend="gssapi-auth">) instead.
     </para>
    </note>
 
@@ -1040,7 +1041,7 @@ omicron         bryanh                  guest1
     principal matching the requested database user name. For example, for
     database user name <literal>fred</>, principal
     <literal>fred@EXAMPLE.COM</> would be able to connect. To also allow
-    principle <literal>fred/users.example.com@EXAMPLE.COM</>, use a username
+    principal <literal>fred/users.example.com@EXAMPLE.COM</>, use a username
     map, as described in <xref linkend="auth-username-maps">.
    </para>
 
@@ -1121,7 +1122,7 @@ omicron         bryanh                  guest1
     name (with an optional username mapping).
     The determination of the client's
     user name is the security-critical point, and it works differently
-    depending on the connection type.
+    depending on the connection type, as described below.
    </para>
 
    <para>
@@ -1195,7 +1196,10 @@ omicron         bryanh                  guest1
     class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
     <systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
     <systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>), ident authentication can also
-    be applied to local connections. In this case, no security risk is added by
+    be applied to local connections.
+    <productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
+    the operating system name of the connected client process.
+    In this case, no security risk is added by
     using ident authentication; indeed it is a preferable choice for
     local connections on such systems.
    </para>
@@ -1272,7 +1276,7 @@ omicron         bryanh                  guest1
       <listitem>
        <para>
         Port number on LDAP server to connect to. If no port is specified,
-        the default port in the LDAP library will be used.
+        the LDAP library's default port setting will be used.
        </para>
       </listitem>
      </varlistentry>
@@ -1309,7 +1313,7 @@ omicron         bryanh                  guest1
       <term><literal>ldapbasedn</literal></term>
       <listitem>
        <para>
-        DN to root the search for the user in, when doing search+bind
+        Root DN to begin the search for the user in, when doing search+bind
         authentication.
        </para>
       </listitem>
@@ -1403,7 +1407,7 @@ ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
         <para>
          The shared secret used when talking securely to the RADIUS
          server. This must have exactly the same value on the PostgreSQL
-         and RADIUS servers. It is recommended that this is a string of
+         and RADIUS servers. It is recommended that this be a string of
          at least 16 characters. This parameter is required.
          <note>
          <para>
@@ -1434,7 +1438,7 @@ ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
         <para>
          The string used as <literal>NAS Identifier</> in the RADIUS
          requests. This parameter can be used as a second parameter
-         identifying for example which database the user is attempting
+         identifying for example which database user the user is attempting
          to authenticate as, which can be used for policy matching on
          the RADIUS server. If no identifier is specified, the default
          <literal>postgresql</> will be used.
@@ -1458,7 +1462,8 @@ ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
     authentication. It is therefore only available for SSL connections.
     When using this authentication method, the server will require that
     the client provide a valid certificate. No password prompt will be sent
-    to the client. The <literal>cn</literal> attribute of the certificate
+    to the client. The <literal>cn</literal> (Common Name) attribute of the
+    certificate
     will be compared to the requested database username, and if they match
     the login will be allowed.  Username mapping can be used to allow
     <literal>cn</literal> to be different from the database username.
@@ -1548,7 +1553,7 @@ FATAL:  no pg_hba.conf entry for host "123.123.123.123", user "andym", database
 
    <para>
 <programlisting>
-FATAL:  Password authentication failed for user "andym"
+FATAL:  password authentication failed for user "andym"
 </programlisting>
     Messages like this indicate that you contacted the server, and it is
     willing to talk to you, but not until you pass the authorization
index 6fe27541cf290bfde200c8779f31405de962db29..faf858f04c98bb67778e037b5b1922e99ba0bdae 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.278 2010/05/20 20:32:27 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.279 2010/05/26 23:49:18 tgl Exp $ -->
 
 <chapter Id="runtime-config">
   <title>Server Configuration</title>
@@ -590,7 +590,7 @@ SET ENABLE_SEQSCAN TO OFF;
        </para>
       </listitem>
      </varlistentry>
-     
+
      <varlistentry id="guc-ssl" xreflabel="ssl">
       <term><varname>ssl</varname> (<type>boolean</type>)</term>
       <indexterm>
@@ -614,20 +614,22 @@ SET ENABLE_SEQSCAN TO OFF;
       </indexterm>
       <listitem>
        <para>
-        Specifies how much data can flow over an <acronym>SSL</> encrypted connection
-        before renegotiation of the session will take place. Renegotiation of the
-        session decreases the chance of doing cryptanalysis when large amounts of data
-        are sent, but it also carries a large performance penalty. The sum of
-        sent and received traffic is used to check the limit. If the parameter is
-        set to 0, renegotiation is disabled. The default is <literal>512MB</>.
+        Specifies how much data can flow over an <acronym>SSL</>-encrypted
+        connection before renegotiation of the session keys will take
+        place. Renegotiation decreases an attacker's chances of doing
+        cryptanalysis when large amounts of traffic can be examined, but it
+        also carries a large performance penalty. The sum of sent and received
+        traffic is used to check the limit. If this parameter is set to 0,
+        renegotiation is disabled. The default is <literal>512MB</>.
        </para>
        <note>
         <para>
          SSL libraries from before November 2009 are insecure when using SSL
-         renegotiation, due to a vulnerability in the SSL protocol. As a stop-gap fix
-         for this vulnerability, some vendors also shipped SSL libraries incapable
-         of doing renegotiation. If any of these libraries are in use on the client
-         or server, SSL renegotiation should be disabled.
+         renegotiation, due to a vulnerability in the SSL protocol. As a
+         stop-gap fix for this vulnerability, some vendors shipped SSL
+         libraries incapable of doing renegotiation. If any such libraries
+         are in use on the client or server, SSL renegotiation should be
+         disabled.
         </para>
        </note>
       </listitem>
index 7dc2983a89cf821ec2a8d1ba79047dfa014dbc43..57357b18bb2741ab3a9fb20564faf5753fe32397 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.305 2010/05/13 14:16:41 mha Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.306 2010/05/26 23:49:18 tgl Exp $ -->
 
 <chapter id="libpq">
  <title><application>libpq</application> - C Library</title>
          <term><literal>sslmode</literal></term>
          <listitem>
           <para>
-           This option determines whether or with what priority a
+           This option determines whether or with what priority a secure
            <acronym>SSL</> TCP/IP connection will be negotiated with the
            server. There are six modes:
           </para>
              <row>
               <entry><literal>verify-ca</></entry>
               <entry>only try an <acronym>SSL</> connection, and verify that
-              the server certificate is issued by a trusted <acronym>CA</>.
+              the server certificate is issued by a trusted <acronym>CA</>
               </entry>
              </row>
 
               <entry><literal>verify-full</></entry>
               <entry>only try an <acronym>SSL</> connection, verify that
               the server certificate is issued by a trusted <acronym>CA</> and
-              that the server hostname matches that in the certificate.</entry>
+              that the server hostname matches that in the certificate</entry>
              </row>
 
             </tbody>
            <literal>sslmode</> is ignored for Unix domain socket
            communication.
            If <productname>PostgreSQL</> is compiled without SSL support,
-           using option <literal>require</> will cause an error, while
+           using options <literal>require</>, <literal>verify-ca</>, or
+           <literal>verify-full</> will cause an error, while
            options <literal>allow</> and <literal>prefer</> will be
            accepted but <application>libpq</> will not actually attempt
            an <acronym>SSL</>
          <listitem>
           <para>
            This parameter specifies the file name of the client SSL
-           certificate.
+           certificate, replacing the default
+           <filename>~/.postgresql/postgresql.crt</>.
+           This parameter is ignored if an SSL connection is not made. 
           </para>
          </listitem>
         </varlistentry>
          <term><literal>sslkey</literal></term>
          <listitem>
           <para>
-           This parameter specifies the location for the secret key
-           used for the client certificate. It can either specify a filename
-           that will be used instead of the default
-           <filename>~/.postgresql/postgresql.key</>, or can specify an external
-           engine (engines are <productname>OpenSSL</> loadable modules). The
-           external engine specification should consist of a colon-separated
-           engine name and an engine-specific key identifier.
+           This parameter specifies the location for the secret key used for
+           the client certificate. It can either specify a filename that will
+           be used instead of the default
+           <filename>~/.postgresql/postgresql.key</>, or it can specify a key
+           obtained from an external <quote>engine</> (engines are
+           <productname>OpenSSL</> loadable modules).  An external engine
+           specification should consist of a colon-separated engine name and
+           an engine-specific key identifier.  This parameter is ignored if an
+           SSL connection is not made.
           </para>
          </listitem>
         </varlistentry>
          <term><literal>sslrootcert</literal></term>
          <listitem>
           <para>
-           This parameter specifies the file name of the root SSL certificate.
+           This parameter specifies the name of a file containing SSL
+           certificate authority (<acronym>CA</>) certificate(s).
+           If the file exists, the server's certificate will be verified
+           to be signed by one of these authorities.  The default is
+           <filename>~/.postgresql/root.crt</>.
           </para>
          </listitem>
         </varlistentry>
          <listitem>
           <para>
            This parameter specifies the file name of the SSL certificate
-           revocation list (CRL).
+           revocation list (CRL).  Certificates listed in this file, if it
+           exists, will be rejected while attempting to authenticate the
+           server's certificate.  The default is
+           <filename>~/.postgresql/root.crl</>.
           </para>
          </listitem>
         </varlistentry>
@@ -1482,8 +1494,9 @@ PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
 
       <para>
        You must define <symbol>USE_SSL</symbol> in order to get the
-       correct prototype for this function. Doing this will also
-       automatically include <filename>ssl.h</filename> from <productname>OpenSSL</productname>.
+       correct prototype for this function. Doing so will also
+       automatically include <filename>ssl.h</filename> from
+       <productname>OpenSSL</productname>.
       </para>
      </listitem>
     </varlistentry>
@@ -6398,23 +6411,24 @@ user=admin
    By default, <productname>PostgreSQL</> will not perform any verification of
    the server certificate. This means that it is possible to spoof the server
    identity (for example by modifying a DNS record or by taking over the server
-   IP address) without the client knowing. In order to prevent this,
+   IP address) without the client knowing. In order to prevent spoofing,
    <acronym>SSL</> certificate verification must be used.
   </para>
 
   <para>
-   If the parameter <literal>sslmode</> is set to <literal>verify-ca</>
-   libpq will verify that the server is trustworthy by checking the certificate
-   chain up to a trusted <acronym>CA</>. If <literal>sslmode</> is set to
-   <literal>verify-full</>, libpq will <emphasis>also</> verify that the server
-   hostname matches that of the certificate. The SSL connection will fail if
-   the server certificate cannot be verified. <literal>verify-full</> is
-   recommended in most security sensitive environments.
+   If the parameter <literal>sslmode</> is set to <literal>verify-ca</>,
+   libpq will verify that the server is trustworthy by checking the
+   certificate chain up to a trusted certificate authority
+   (<acronym>CA</>). If <literal>sslmode</> is set to <literal>verify-full</>,
+   libpq will <emphasis>also</> verify that the server hostname matches its
+   certificate. The SSL connection will fail if the server certificate cannot
+   be verified. <literal>verify-full</> is recommended in most
+   security-sensitive environments.
   </para>
 
   <para>
-   In <literal>verify-full</> mode, the <literal>cn</> attribute of the
-   certificate is matched against the hostname. If the <literal>cn</>
+   In <literal>verify-full</> mode, the <literal>cn</> (Common Name) attribute
+   of the certificate is matched against the hostname. If the <literal>cn</>
    attribute starts with an asterisk (<literal>*</>), it will be treated as
    a wildcard, and will match all characters <emphasis>except</> a dot
    (<literal>.</>). This means the certificate will not match subdomains.
@@ -6423,7 +6437,8 @@ user=admin
   </para>
 
   <para>
-   To allow verification, the certificate of a trusted <acronym>CA</> must be
+   To allow server certificate verification, the certificate(s) of one or more
+   trusted <acronym>CA</>s must be
    placed in the file <filename>~/.postgresql/root.crt</> in the user's home
    directory. (On Microsoft Windows the file is named
    <filename>%APPDATA%\postgresql\root.crt</filename>.)
@@ -6437,8 +6452,9 @@ user=admin
   </para>
 
   <para>
-   The location of the root certificate store and the CRL can be overridden
-   by the connection parameters <literal>sslrootcert</> and <literal>sslcrl</>
+   The location of the root certificate file and the CRL can be changed by
+   setting
+   the connection parameters <literal>sslrootcert</> and <literal>sslcrl</>
    or the environment variables <envar>PGSSLROOTCERT</> and <envar>PGSSLCRL</>.
   </para>
  </sect2>
@@ -6465,6 +6481,24 @@ user=admin
    environment variables <envar>PGSSLCERT</> and <envar>PGSSLKEY</>.
   </para>
 
+  <para>
+   In some cases, the client certificate might be signed by an
+   <quote>intermediate</> certificate authority, rather than one that is
+   directly trusted by the server.  To use such a certificate, append the
+   certificate of the signing authority to the <filename>postgresql.crt</>
+   file, then its parent authority's certificate, and so on up to a
+   <quote>root</> authority that is trusted by the server.  The root
+   certificate should be included in every case where
+   <filename>postgresql.crt</> contains more than one certificate.
+  </para>
+
+  <para>
+   Note that <filename>root.crt</filename> lists the top-level CAs that are
+   considered trusted for signing server certificates.  In principle it need
+   not list the CA that signed the client's certificate, though in most cases
+   that CA would also be trusted for server certificates.
+  </para>
+
  </sect2>
 
  <sect2 id="libpq-ssl-protection">
@@ -6472,8 +6506,8 @@ user=admin
 
   <para>
    The different values for the <literal>sslmode</> parameter provide different
-   levels of protection, in different environments. SSL itself provides
-   protection against three different types of attacks:
+   levels of protection. SSL can provide
+   protection against three types of attacks:
   </para>
   <table id="libpq-ssl-protect-attacks">
    <title>SSL attacks</title>
@@ -6488,7 +6522,7 @@ user=admin
     <tbody>
      <row>
       <entry>Eavesdropping</entry>
-      <entry>If a third party can listen to the network traffic between the
+      <entry>If a third party can examine the network traffic between the
        client and the server, it can read both connection information (including
        the username and password) and the data that is passed. <acronym>SSL</>
        uses encryption to prevent this.
@@ -6523,27 +6557,28 @@ user=admin
   </table>
 
   <para>
-   For a connection to be known secure, the two first of these have to be
-   set up on <emphasis>both the client and the server</> before the connection
+   For a connection to be known secure, SSL usage must be configured
+   on <emphasis>both the client and the server</> before the connection
    is made. If it is only configured on the server, the client may end up
    sending sensitive information (e.g. passwords) before
-   it knows that the server requires high security. In libpq, this is controlled
+   it knows that the server requires high security. In libpq, secure
+   connections can be ensured
    by setting the <literal>sslmode</> parameter to <literal>verify-full</> or
    <literal>verify-ca</>, and providing the system with a root certificate to
-   verify against. This is analogous to using a <literal>https</>
+   verify against. This is analogous to using an <literal>https</>
    <acronym>URL</> for encrypted web browsing.
   </para>
 
   <para>
    Once the server has been authenticated, the client can pass sensitive data.
    This means that up until this point, the client does not need to know if
-   certificates will be used for authentication, making it safe to specify this
+   certificates will be used for authentication, making it safe to specify that
    only in the server configuration.
   </para>
 
   <para>
    All <acronym>SSL</> options carry overhead in the form of encryption and
-   key-exchange, and it is a tradeoff that has to be made between performance
+   key-exchange, so there is a tradeoff that has to be made between performance
    and security. The following table illustrates the risks the different
    <literal>sslmode</> values protect against, and what statement they make
    about security and overhead:
@@ -6625,8 +6660,8 @@ user=admin
    The difference between <literal>verify-ca</> and <literal>verify-full</>
    depends on the policy of the root <acronym>CA</>. If a public
    <acronym>CA</> is used, <literal>verify-ca</> allows connections to a server
-   that <emphasis>somebody else</> may have registered with the <acronym>CA</>
-   to succeed. In this case, <literal>verify-full</> should always be used. If
+   that <emphasis>somebody else</> may have registered with the <acronym>CA</>.
+   In this case, <literal>verify-full</> should always be used. If
    a local <acronym>CA</> is used, or even a self-signed certificate, using
    <literal>verify-ca</> often provides enough protection.
   </para>
@@ -6635,7 +6670,7 @@ user=admin
    The default value for <literal>sslmode</> is <literal>prefer</>. As is shown
    in the table, this makes no sense from a security point of view, and it only
    promises performance overhead if possible. It is only provided as the default
-   for backwards compatibility, and not recommended in secure deployments.
+   for backwards compatibility, and is not recommended in secure deployments.
   </para>
 
  </sect2>
@@ -6671,7 +6706,7 @@ user=admin
      <row>
       <entry><filename>~/.postgresql/root.crt</></entry>
       <entry>trusted certificate authorities</entry>
-      <entry>checks server certificate is signed by a trusted certificate
+      <entry>checks that server certificate is signed by a trusted certificate
       authority</entry>
      </row>
 
index 2e83dda9cfae2a3d31030fd7d666023091fc92f1..8590cfa35f6b57ccf3f66bf1aafb590f7fbe44f8 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.435 2010/04/30 22:24:50 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.436 2010/05/26 23:49:19 tgl Exp $ -->
 
 <chapter Id="runtime">
  <title>Server Setup and Operation</title>
@@ -731,7 +731,7 @@ psql: could not connect to server: No such file or directory
        files (<varname>nofiles</varname>) might be too low.
        </para>
       </listitem>
-     </varlistentry>      
+     </varlistentry>
 
      <varlistentry>
       <term><systemitem class="osname">BSD/OS</></term>
@@ -1438,28 +1438,30 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
   </para>
 
   <para>
-   The simplest way to prevent invalid servers for <literal>local</>
+   The simplest way to prevent spoofing for <literal>local</>
    connections is to use a Unix domain socket directory (<xref
    linkend="guc-unix-socket-directory">) that has write permission only
    for a trusted local user.  This prevents a malicious user from creating
    their own socket file in that directory.  If you are concerned that
    some applications might still reference <filename>/tmp</> for the
    socket file and hence be vulnerable to spoofing, during operating system
-   startup create symbolic link <filename>/tmp/.s.PGSQL.5432</> that points
+   startup create symbolic link <filename>/tmp/.s.PGSQL.5432</> that points
    to the relocated socket file.  You also might need to modify your
-   <filename>/tmp</> cleanup script to preserve the symbolic link.
+   <filename>/tmp</> cleanup script to prevent removal of the symbolic link.
   </para>
 
   <para>
-   For TCP connections the server
-   must accept only <literal>hostssl</> connections (<xref
+   To prevent spoofing on TCP connections, the best solution is to use
+   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
-   <literal>sslmode='verify-ca'</> or
-   <literal>'verify-full'</> and have the required certificate
-   files present (<xref linkend="libpq-connect">).
+   <literal>sslmode=verify-ca</> or
+   <literal>verify-full</> and have the appropriate root certificate
+   file installed (<xref linkend="libpq-connect">).
   </para>
  </sect1>
   
@@ -1583,13 +1585,13 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
    <term>SSL Host Authentication</term>
 
    <listitem>
-    <para> 
+    <para>
      It is possible for both the client and server to provide SSL
      certificates to each other. It takes some extra configuration
      on each side, but this provides stronger verification of identity
      than the mere use of passwords. It prevents a computer from
      pretending to be the server just long enough to read the password
-     send by the client. It also helps prevent "man in the middle"
+     sent by the client. It also helps prevent <quote>man in the middle</>
      attacks where a computer between the client and server pretends to
      be the server and reads and passes all data between the client and
      server.
@@ -1602,7 +1604,8 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
 
    <listitem>
     <para>
-     If the system administrator cannot be trusted, it is necessary
+     If the system administrator for the server's machine cannot be trusted,
+     it is necessary
      for the client to encrypt the data; this way, unencrypted data
      never appears on the database server. Data is encrypted on the
      client before being sent to the server, and database results have
@@ -1680,20 +1683,33 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
    respectively.
    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>.  
+   <command>chmod 0600 server.key</command>.
    If the private key is protected with a passphrase, the
    server will prompt for the passphrase and will not start until it has
    been entered.
   </para>
 
+  <para>
+   In some cases, the server certificate might be signed by an
+   <quote>intermediate</> certificate authority, rather than one that is
+   directly trusted by clients.  To use such a certificate, append the
+   certificate of the signing authority to the <filename>server.crt</> file,
+   then its parent authority's certificate, and so on up to a <quote>root</>
+   authority that is trusted by the clients.  The root certificate should
+   be included in every case where <filename>server.crt</> contains more than
+   one certificate.
+  </para>
+
   <sect2 id="ssl-client-certificates">
    <title>Using client certificates</title>
+
    <para>
    To require the client to supply a trusted certificate, place
-   certificates of the certificate authorities (<acronym>CA</acronym>)
+   certificates of the certificate authorities (<acronym>CA</acronym>s)
    you trust in the file <filename>root.crt</filename> in the data
    directory, and set the <literal>clientcert</literal> parameter
-   to <literal>1</literal> on the appropriate line(s) in pg_hba.conf.
+   to <literal>1</literal> on the appropriate <literal>hostssl</> line(s) in
+   <filename>pg_hba.conf</>.
    A certificate will then be requested from the client during
    SSL connection startup.  (See <xref linkend="libpq-ssl"> for a
    description of how to set up certificates on the client.)  The server will
@@ -1707,16 +1723,26 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
   </para>
 
   <para>
-   The <literal>clientcert</literal> option in <filename>pg_hba.conf</>
-   is available for all authentication methods, but only for rows
-   specified as <literal>hostssl</>. Unless specified, the default is
-   not to verify the client certificate.
+   The <literal>clientcert</literal> option in <filename>pg_hba.conf</> is
+   available for all authentication methods, but only for rows specified as
+   <literal>hostssl</>.  When <literal>clientcert</literal> is not specified
+   or is set to <literal>0</>, the server will still verify presented client
+   certificates against <filename>root.crt</filename> if that file exists
+   &mdash; but it will not insist that a client certificate be presented.
+  </para>
+
+  <para>
+   Note that <filename>root.crt</filename> lists the top-level CAs that are
+   considered trusted for signing client certificates.  In principle it need
+   not list the CA that signed the server's certificate, though in most cases
+   that CA would also be trusted for client certificates.
   </para>
 
   <para>
-   You can use the authentication method <literal>cert</> to use the
-   client certificate for authenticating users. See
-   <xref linkend="auth-cert"> for details.
+   If you are setting up client certificates, you may wish to use
+   the <literal>cert</> authentication method, so that the certificates
+   control user authentication as well as providing connection security.
+   See <xref linkend="auth-cert"> for details.
   </para>
   </sect2>
 
@@ -1725,7 +1751,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
   <para>
    The files <filename>server.key</>, <filename>server.crt</>,
    <filename>root.crt</filename>, and <filename>root.crl</filename>
-   are only examined during server start; so you must restart 
+   are only examined during server start; so you must restart
    the server for changes in them to take effect.
   </para>
 
@@ -1745,13 +1771,13 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
      <row>
       <entry><filename>server.crt</></entry>
       <entry>server certificate</entry>
-      <entry>requested by client</entry>
+      <entry>sent to client to indicate server's identity</entry>
      </row>
 
      <row>
       <entry><filename>server.key</></entry>
       <entry>server private key</entry>
-      <entry>proves server certificate was sent by the owner; it does not indicate
+      <entry>proves server certificate was sent by the owner; does not indicate
       certificate owner is trustworthy</entry>
      </row>
 
@@ -1812,7 +1838,7 @@ chmod og-rwx server.key
     A self-signed certificate can be used for testing, but a certificate
     signed by a certificate authority (<acronym>CA</>) (either one of the
     global <acronym>CAs</> or a local one) should be used in production
-    so the client can verify the server's identity. If all the clients
+    so that clients can verify the server's identity. If all the clients
     are local to the organization, using a local <acronym>CA</> is
     recommended.
    </para>