mirror of
https://github.com/postgres/postgres.git
synced 2025-07-26 01:22:12 +03:00
Support suffix matching of host names in pg_hba.conf
A name starting with a dot can be used to match a suffix of the actual host name (e.g., .example.com matches foo.example.com).
This commit is contained in:
@ -282,6 +282,14 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
|||||||
to resolve an IP address.)
|
to resolve an IP address.)
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A host name specification that starts with a dot
|
||||||
|
(<literal>.</literal>) matches a suffix of the actual host
|
||||||
|
name. So <literal>.example.com</literal> would match
|
||||||
|
<literal>foo.example.com</literal> (but not just
|
||||||
|
<literal>example.com</literal>).
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When host names are specified
|
When host names are specified
|
||||||
in <filename>pg_hba.conf</filename>, you should make sure that
|
in <filename>pg_hba.conf</filename>, you should make sure that
|
||||||
@ -310,6 +318,12 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
|||||||
everyone's problem.
|
everyone's problem.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Also, a reverse lookup is necessary to implement the suffix
|
||||||
|
matching feature, because the actual client host name needs to
|
||||||
|
be known in order to match it against the pattern.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Note that this behavior is consistent with other popular
|
Note that this behavior is consistent with other popular
|
||||||
implementations of host name-based access control, such as the
|
implementations of host name-based access control, such as the
|
||||||
@ -605,6 +619,12 @@ host postgres all 192.168.93.0/24 ident
|
|||||||
# TYPE DATABASE USER ADDRESS METHOD
|
# TYPE DATABASE USER ADDRESS METHOD
|
||||||
host postgres all 192.168.12.10/32 md5
|
host postgres all 192.168.12.10/32 md5
|
||||||
|
|
||||||
|
# Allow any user from hosts in the example.com domain to connect to
|
||||||
|
# any database if the user's password is correctly supplied.
|
||||||
|
#
|
||||||
|
# TYPE DATABASE USER ADDRESS METHOD
|
||||||
|
host all all .example.com md5
|
||||||
|
|
||||||
# In the absence of preceding "host" lines, these two lines will
|
# In the absence of preceding "host" lines, these two lines will
|
||||||
# reject all connections from 192.168.54.1 (since that entry will be
|
# reject all connections from 192.168.54.1 (since that entry will be
|
||||||
# matched first), but allow Kerberos 5 connections from anywhere else
|
# matched first), but allow Kerberos 5 connections from anywhere else
|
||||||
|
@ -564,6 +564,26 @@ ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
|
|||||||
|
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether host name matches pattern.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
hostname_match(const char *pattern, const char *actual_hostname)
|
||||||
|
{
|
||||||
|
if (pattern[0] == '.') /* suffix match */
|
||||||
|
{
|
||||||
|
size_t plen = strlen(pattern);
|
||||||
|
size_t hlen = strlen(actual_hostname);
|
||||||
|
|
||||||
|
if (hlen < plen)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (pg_strcasecmp(pattern, actual_hostname + (hlen - plen)) == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (pg_strcasecmp(pattern, actual_hostname) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if a connecting IP matches a given host name.
|
* Check to see if a connecting IP matches a given host name.
|
||||||
*/
|
*/
|
||||||
@ -588,7 +608,7 @@ check_hostname(hbaPort *port, const char *hostname)
|
|||||||
port->remote_hostname = pstrdup(remote_hostname);
|
port->remote_hostname = pstrdup(remote_hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pg_strcasecmp(port->remote_hostname, hostname) != 0)
|
if (!hostname_match(hostname, port->remote_hostname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Lookup IP from host name and check against original IP */
|
/* Lookup IP from host name and check against original IP */
|
||||||
|
@ -32,7 +32,8 @@
|
|||||||
# ADDRESS specifies the set of hosts the record matches. It can be a
|
# ADDRESS specifies the set of hosts the record matches. It can be a
|
||||||
# host name, or it is made up of an IP address and a CIDR mask that is
|
# host name, or it is made up of an IP address and a CIDR mask that is
|
||||||
# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
|
# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
|
||||||
# specifies the number of significant bits in the mask.
|
# specifies the number of significant bits in the mask. A host name
|
||||||
|
# that starts with a dot (.) matches a suffix of the actual host name.
|
||||||
# Alternatively, you can write an IP address and netmask in separate
|
# Alternatively, you can write an IP address and netmask in separate
|
||||||
# columns to specify the set of hosts. Instead of a CIDR-address, you
|
# columns to specify the set of hosts. Instead of a CIDR-address, you
|
||||||
# can write "samehost" to match any of the server's own IP addresses,
|
# can write "samehost" to match any of the server's own IP addresses,
|
||||||
|
Reference in New Issue
Block a user