Thread: BUG #5559: Full SSL verification fails when hostaddr provided
The following bug has been logged online: Bug reference: 5559 Logged by: Christopher Head Email address: chris2k01@hotmail.com PostgreSQL version: 8.4.4 Operating system: Gentoo Linux i386, kernel 2.6.34 Description: Full SSL verification fails when hostaddr provided Details: When establishing a connection to a PostgreSQL server using a connection string, there are two parameters that can be provided to specify where to connect to: "host" and "hostaddr". If both are provided, the documentation states that "hostaddr" is used to actually establish the socket (thus avoiding a potentially-expensive DNS lookup), while "host" is used for doing some Kerberos stuff. It makes sense that in the case of an SSL connection with "sslmode=verify-full" (check that the server's certificate is signed by a trusted CA and has the correct hostname), if both parameters are provided, that "host" also be used for certificate checking. Unfortunately, as per line 536 of the file fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full verification just plain fails without trying at all. I suspect this line should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)". There is no security vulnerability here, since "host" is a configuration slot intended to hold some kind of semantic name for the host as understood by the user (which is precisely what you want to verify a certificate againstâthat you are connecting to the semantically-correct server, not simply the one that happens to have the right IP address), while "hostaddr" is merely a network-level implementation detail which should be essentially meaningless to the user. Although it's easy enough to avoid the issue when using psql (just don't include "hostaddr" at all), this unfortunately causes all connections to fail when using pgAdmin3, as that program apparently does its own DNS lookups and always attaches a hostaddr (thus causing the confusing message "verified SSL connections are only supported when connecting to a host name" even if one *does* in fact specify a host*name* in the appropriate place!)
"Christopher Head" <chris2k01@hotmail.com> writes: > When establishing a connection to a PostgreSQL server using a connection > string, there are two parameters that can be provided to specify where to > connect to: "host" and "hostaddr". If both are provided, the documentation > states that "hostaddr" is used to actually establish the socket (thus > avoiding > a potentially-expensive DNS lookup), while "host" is used for doing some > Kerberos stuff. > It makes sense that in the case of an SSL connection with > "sslmode=verify-full" (check that the server's certificate is signed by a > trusted CA and has the > correct hostname), if both parameters are provided, that "host" also be used > for certificate checking. Unfortunately, as per line 536 of the file > fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full > verification just plain fails without trying at all. I suspect this line > should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)". That's really a definitional change, but it seems like a reasonable one to me. Magnus, what do you think? regards, tom lane
On Wed, Jul 14, 2010 at 00:09, Tom Lane <tgl@sss.pgh.pa.us> wrote: > "Christopher Head" <chris2k01@hotmail.com> writes: >> When establishing a connection to a PostgreSQL server using a connection >> string, there are two parameters that can be provided to specify where to >> connect to: "host" and "hostaddr". If both are provided, the documentati= on >> states that "hostaddr" is used to actually establish the socket (thus >> avoiding >> a potentially-expensive DNS lookup), while "host" is used for doing some >> Kerberos stuff. > >> It makes sense that in the case of an SSL connection with >> "sslmode=3Dverify-full" (check that the server's certificate is signed b= y a >> trusted CA and has the >> correct hostname), if both parameters are provided, that "host" also be = used >> for certificate checking. Unfortunately, as per line 536 of the file >> fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full >> verification just plain fails without trying at all. I suspect this line >> should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)". > > That's really a definitional change, but it seems like a reasonable one > to me. =A0Magnus, what do you think? Yeah, I think it is, but I haven't had the time to look into the code yet to see if I agree with the fix as well. Hope to get there soon. --=20 =A0Magnus Hagander =A0Me: http://www.hagander.net/ =A0Work: http://www.redpill-linpro.com/
Magnus Hagander <magnus@hagander.net> writes: > On Wed, Jul 14, 2010 at 00:09, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> "Christopher Head" <chris2k01@hotmail.com> writes: >>> ... Unfortunately, as per line 536 of the file >>> fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full >>> verification just plain fails without trying at all. I suspect this line >>> should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)". >> >> That's really a definitional change, but it seems like a reasonable one >> to me. Magnus, what do you think? > Yeah, I think it is, but I haven't had the time to look into the code > yet to see if I agree with the fix as well. Hope to get there soon. The test actually needs to check for pghost being nonempty, I think, but otherwise it seems straightforward. Will apply. regards, tom lane
... btw, the libpq documentation claims that If hostaddr is specified without host, the value for hostaddr gives the remote address. When Kerberos is used, a reverse name query occurs to obtain the host name for Kerberos. but so far as I can see this is flat wrong. pg_krb5_sendauth throws an error if you didn't provide a host name, and so do the other places in fe-auth.c that need the host name. What we're about to do to SSL verification will match that. So I think the docs need a fix here. regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > ... btw, the libpq documentation claims that >=20 > If hostaddr is specified without host, the value for hostaddr > gives the remote address. When Kerberos is used, a reverse name > query occurs to obtain the host name for Kerberos. >=20 > but so far as I can see this is flat wrong. pg_krb5_sendauth throws > an error if you didn't provide a host name, and so do the other places > in fe-auth.c that need the host name. What we're about to do to SSL > verification will match that. So I think the docs need a fix here. I think the confusion here is that the *Kerberos* libraries do the reverse-DNS lookup to get the hostname to request as part of the principal. It's true that we don't, but that doesn't mean it's not done. Not sure where or if we need to discuss how Kerberos works in the libpq documentation or what the context is for the above, but I'm pretty sure that's where the original wording came from. Thanks, Stephen
Stephen Frost <sfrost@snowman.net> writes: > * Tom Lane (tgl@sss.pgh.pa.us) wrote: >> ... btw, the libpq documentation claims that >> >> If hostaddr is specified without host, the value for hostaddr >> gives the remote address. When Kerberos is used, a reverse name >> query occurs to obtain the host name for Kerberos. >> >> but so far as I can see this is flat wrong. pg_krb5_sendauth throws >> an error if you didn't provide a host name, and so do the other places >> in fe-auth.c that need the host name. What we're about to do to SSL >> verification will match that. So I think the docs need a fix here. > I think the confusion here is that the *Kerberos* libraries do the > reverse-DNS lookup to get the hostname to request as part of the > principal. It's true that we don't, but that doesn't mean it's not > done. Not sure where or if we need to discuss how Kerberos works in the > libpq documentation or what the context is for the above, but I'm pretty > sure that's where the original wording came from. Yeah, but the code in fe-auth.c throws an error before the Kerberos libraries get a chance to do any such thing. I suppose that the documentation text was accurate when written, but that was a long time ago. [ pokes in CVS a bit... ] It looks like the insistence that pghost be supplied was added by Magnus on 2005-03-25, probably because the Windows version of Kerberos didn't handle the case correctly; and it's been that way in every release later than 8.0.1. http://archives.postgresql.org/pgsql-committers/2005-03/msg00355.php http://archives.postgresql.org/pgsql-committers/2005-03/msg00356.php That patch did not adjust the documentation wording, but evidently should have. (The claim about a reverse lookup has been in the docs at least since 7.0.) Given the lack of complaints in the past five years, I'm not interested in trying to go back to the old behavior, but we do need to fix the docs. regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Yeah, but the code in fe-auth.c throws an error before the Kerberos > libraries get a chance to do any such thing. I suppose that the > documentation text was accurate when written, but that was a long time > ago. errrr, yeah, there are some issues with the wording that's there, that's for sure. For starters, Kerberos doesn't require nor care if you give it a host name or an IP address; regardless, it will do a reverse-DNS lookup on whatever host is connected to and then use *that* hostname to request the principal from the KDC. If that fails, it will use what you gave it to try and find the principal (but that generally needs to be a fully-qualified DNS name and needs to match exactly what's in the KDC). I wouldn't bomb out if you've only been given a hostaddr, but I would warn people that using Kerberos means it'll do a reverse DNS lookup, if they care about minimizing those. > [ pokes in CVS a bit... ] It looks like the insistence that pghost be > supplied was added by Magnus on 2005-03-25, probably because the Windows > version of Kerberos didn't handle the case correctly; and it's been that > way in every release later than 8.0.1. It's possible that SSPI does something different and may expect you to provide the FQDN when connecting, but I'd be suprised. It could have been a misconfiguration or a bug in older versions that prevented it from doing the normal rDNS lookup. In fact, I just had someone test, and even SSPI, on a recent version of Windows, does the rDNS lookup to request the principal. > That patch did not adjust the documentation wording, but evidently > should have. (The claim about a reverse lookup has been in the docs > at least since 7.0.) Given the lack of complaints in the past five > years, I'm not interested in trying to go back to the old behavior, > but we do need to fix the docs. I've never found a reason to use hostaddr, so I don't particularly care, but it doesn't seem right to break Kerberos auth if you were only given an IP address unless hostaddr's entire point is that it will prevent a DNS lookup from happening, ever. If that's the case, it should probably be made more clear in the docs that you can't use hostaddr w/ Kerberos but you *can* use an IP address in 'host' and have Kerberos work (or at least, it should). Thanks, Stephen
Stephen Frost <sfrost@snowman.net> writes: > I've never found a reason to use hostaddr, so I don't particularly care, > but it doesn't seem right to break Kerberos auth if you were only given > an IP address unless hostaddr's entire point is that it will prevent a > DNS lookup from happening, ever. Well, given your description we *can't* prevent Kerberos auth from doing a synchronous reverse-DNS lookup. So the question is why did that test get put in, back in 2005? I have no objection to removing it if that doesn't lead to crashing, but ... regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Stephen Frost <sfrost@snowman.net> writes: > > I've never found a reason to use hostaddr, so I don't particularly care, > > but it doesn't seem right to break Kerberos auth if you were only given > > an IP address unless hostaddr's entire point is that it will prevent a > > DNS lookup from happening, ever. >=20 > Well, given your description we *can't* prevent Kerberos auth from doing > a synchronous reverse-DNS lookup. So the question is why did that test > get put in, back in 2005? I have no objection to removing it if that > doesn't lead to crashing, but ... We could prevent it by doing exactly what we're doing now- bailing if we end up in the KRB5 code when hostaddr is passed in but host isn't. We could justify that by saying that the user asked for no DNS lookups (through the use of hostaddr) and that using Kerberos would then violate that request, since it'd do an rDNS lookup. I'd advocate *against* that, since it strikes me as bizarre, but having the hostaddr option in the first place is a bit strange to me, so perhaps I just don't run into the use-case it's built for enough to be able to say it doesn't make sense. In any case, here's what I believe the original issue was and what I would suggest: Per the documentation- krb5_sname_to_principal() and krb5_sock_to_principal() are for easy cr= e- ation of ``service'' principals that can, for instance, be used to loo= kup a key in a keytab. For both functions the sname parameter will be used for the first component of the created principal. If sname is NULL, ``host'' will be used instead. krb5_sname_to_principal() will use the passed hostname for the second component. If type is KRB5_NT_SRV_HST this name will be looked up with gethostbyname(). If hostname is NULL, the local hostname will be used. krb5_sock_to_principal() will use the ``sockname'' of the passed socke= t, which should be a bound AF_INET or AF_INET6 socket. There must be a m= ap- ping between the address and ``sockname''. The function may try to resolve the name in DNS. If we were passing in NULL before when hostaddr was set and host wasn't, then we were probably ending up with Kerberos trying to use the local hostname, which almost certainly wasn't right. I expect that the correct answer here would be to do whatever the actual connection logic does- if it connects using host, then use host, if it connects using hostaddr, then use hostaddr. An alternative might be to just use krb5_sock_to_principal(), since we have the socket already.=20=20 Thanks, Stephen
Stephen Frost <sfrost@snowman.net> writes: > krb5_sname_to_principal() will use the passed hostname for the second > component. If type is KRB5_NT_SRV_HST this name will be looked up with > gethostbyname(). If hostname is NULL, the local hostname will be used. > If we were passing in NULL before when hostaddr was set and host wasn't, > then we were probably ending up with Kerberos trying to use the local > hostname, which almost certainly wasn't right. Ah. I agree that that would be unexpected behavior. > I expect that the > correct answer here would be to do whatever the actual connection logic > does- if it connects using host, then use host, if it connects using > hostaddr, then use hostaddr. Uh, no, because hostaddr is (required to be) a numeric IP. The odds of it being useful in this context seem negligible. At this point I'm satisfied that what the code is doing is right. We can't authenticate against Kerberos without knowing the server host name, because we can't form a correct principal name. Whether use of hostaddr would avoid an rDNS lookup inside the library is not relevant. regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Stephen Frost <sfrost@snowman.net> writes: > > krb5_sname_to_principal() will use the passed hostname for the sec= ond > > component. If type is KRB5_NT_SRV_HST this name will be looked up= with > > gethostbyname(). If hostname is NULL, the local hostname will be = used. >=20 > > If we were passing in NULL before when hostaddr was set and host wasn't, > > then we were probably ending up with Kerberos trying to use the local > > hostname, which almost certainly wasn't right. >=20 > Ah. I agree that that would be unexpected behavior. >=20 > > I expect that the > > correct answer here would be to do whatever the actual connection logic > > does- if it connects using host, then use host, if it connects using > > hostaddr, then use hostaddr. >=20 > Uh, no, because hostaddr is (required to be) a numeric IP. The odds of > it being useful in this context seem negligible. Err, no, it'll work just fine- gethostbyname() will take the dotted-quad numeric IP and return the hostname and Kerberos will use that to generate the principal. Maybe I'm missing something, but hostaddr being an IP is just like if you passed in host with an IP, which I believe is what psql does when called like so: beren:/home/sfrost> psql -h 172.18.148.12 -d gis Welcome to psql 8.3.7, the PostgreSQL interactive terminal. and that certainly works just fine. beren:/home/sfrost> klist [...] 07/14/10 17:37:50 07/14/10 17:58:25 postgres/beren.tsf.noblis.org@TSF.NOB= LIS.ORG > At this point I'm satisfied that what the code is doing is right. We > can't authenticate against Kerberos without knowing the server host > name, because we can't form a correct principal name. Whether use of > hostaddr would avoid an rDNS lookup inside the library is not relevant. I don't believe anything is going to avoid an rDNS lookup except bombing out before invoking krb5_sname_to_principal(). Perhaps that's what's intended, to avoid any DNS lookup, but I don't believe it's because it wouldn't *work* to give krb5_sname_to_principal() an IP address=20 (provided rDNS is, in fact, functional in your environment). Thanks, Stephen
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Uh, no, because hostaddr is (required to be) a numeric IP. The odds of > it being useful in this context seem negligible. Perhaps I was being a bit overzealous in my last response, sorry about that. If the point here is that people who are using hostaddr are in an environment where DNS is non-functional or actively broken, then yes, just bombing out would probably be fine. I think the issue I have here is that if you've gone to the trouble to set things up on the server-side to a point where it asks the client to do Kerberos (which, I think, must be the case if we've gotten to this point in the code), and for some reason the client has decided to use hostaddr instead of host (perhaps some client-side code saw a dotted-quad and thought "oh, you must want to use hostaddr instead of host"), it shouldn't break without a real reason. Thanks, Stephen
Stephen Frost <sfrost@snowman.net> writes: > * Tom Lane (tgl@sss.pgh.pa.us) wrote: >> Uh, no, because hostaddr is (required to be) a numeric IP. The odds of >> it being useful in this context seem negligible. > Err, no, it'll work just fine- gethostbyname() will take the dotted-quad > numeric IP and return the hostname and Kerberos will use that to generate > the principal. Hm. That might happen to work for Kerberos, but it won't work for GSSAPI or SSPI --- in both those code paths we just push the host name literally into a constructed principal string. Not sure if we really want Kerberos to work differently from the more modern alternatives. > Maybe I'm missing something, but hostaddr being an IP is > just like if you passed in host with an IP, No, it's entirely different. The point of hostaddr is to avoid doing a forward DNS lookup inside PQconnect() when you would rather it be done at some other time. It's not to substitute for actually knowing the host name. I expect that typical applications making use of it would essentially cache the hostaddr corresponding to host name and would be able to pass both to libpq. The option to supply only hostaddr is just there for cases where you truly don't need to know the host name, which clearly does *not* include Kerberos auth. The case you're describing could perfectly well be handled by passing host as a numeric IP string, without using hostaddr; so I don't think we are losing any functionality. > I don't believe anything is going to avoid an rDNS lookup except bombing > out before invoking krb5_sname_to_principal(). So it would seem. The bottom line is that if you don't want any DNS activity to happen during PQconnect(), you can't use Kerberos auth. What we allow or don't allow won't change that. regards, tom lane
Stephen Frost <sfrost@snowman.net> writes: > Perhaps I was being a bit overzealous in my last response, sorry about > that. If the point here is that people who are using hostaddr are in an > environment where DNS is non-functional or actively broken, then yes, > just bombing out would probably be fine. Well, if your environment includes broken DNS then you are clearly going to get nowhere anyway with Kerberos auth, no? The point of hostaddr is *not* to try to avoid that problem. Rather, it's to allow the application to shift the time expense of the forward DNS lookup to some other place than its PQconnect() call. If you've got an app where the cost of PQconnect() is that critical, you're likely going to want to avoid Kerberos auth anyway, so I don't think it's all that important exactly how the two features play together. As the code stands in HEAD, I think everything is nicely self-consistent: host is what we believe the server name is for authentication purposes, and hostaddr is an optional pre-looked-up address corresponding to that. There is nothing in this suggesting that we should be expected to try to generate an authentication name from hostaddr alone. In particular, the fact that Kerberos is capable of trying to do that is at odds with the other three code paths where the server name is needed for authentication. I don't feel any need to expose Kerberos' peculiarity here. regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Hm. That might happen to work for Kerberos, but it won't work for > GSSAPI or SSPI --- in both those code paths we just push the host name > literally into a constructed principal string. Not sure if we really > want Kerberos to work differently from the more modern alternatives. I'm not looking at the code right now, but I just don't see how this can be the case, at least for GSSAPI. I routinely use both krb5 and GSSAPI auth types (depending on which server I'm using) with values passed to -h that certainly aren't the FQDN of the host, and it works just fine. I can't imagine we're doing some magic here ourselves and then passing the right FQDN to the Kerberos/GSSAPI libraries. Typical usage, all of them work: vardamir/8.2: psql -h 172.18.148.10 -d gis psql -h vardamir -d gis psql -h vardamir.tsf.noblis.org -d gis beren/8.3: psql -h beren -d gis psql -h 172.18.148.12 beren/8.4: psql --cluster 8.4/main -h beren -d gis psql --cluster 8.4/main -h 172.18.148.12 psql --cluster 8.4/main -h beren.nicc.noblis.org -d gis beren:/home/sfrost> hostname --fqdn beren.tsf.noblis.org I always get a postgres/beren.tsf.noblis.org@TSF.NOBLIS.ORG ticket, for that server, since that's what the rDNS is, and that's what's in the KDC (it hasn't got entries for any of the others). In any case, let's please make sure not to break that. :) Thanks! Stephen
Do the docs need any more updating? --------------------------------------------------------------------------- Tom Lane wrote: > Stephen Frost <sfrost@snowman.net> writes: > > Perhaps I was being a bit overzealous in my last response, sorry about > > that. If the point here is that people who are using hostaddr are in an > > environment where DNS is non-functional or actively broken, then yes, > > just bombing out would probably be fine. > > Well, if your environment includes broken DNS then you are clearly going > to get nowhere anyway with Kerberos auth, no? The point of hostaddr is > *not* to try to avoid that problem. Rather, it's to allow the > application to shift the time expense of the forward DNS lookup to some > other place than its PQconnect() call. If you've got an app where the > cost of PQconnect() is that critical, you're likely going to want to > avoid Kerberos auth anyway, so I don't think it's all that important > exactly how the two features play together. > > As the code stands in HEAD, I think everything is nicely > self-consistent: host is what we believe the server name is for > authentication purposes, and hostaddr is an optional pre-looked-up > address corresponding to that. There is nothing in this suggesting > that we should be expected to try to generate an authentication name > from hostaddr alone. In particular, the fact that Kerberos is capable > of trying to do that is at odds with the other three code paths where > the server name is needed for authentication. I don't feel any need > to expose Kerberos' peculiarity here. > > regards, tom lane > > -- > Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-bugs -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + None of us is going to be here forever. +
Bruce Momjian <bruce@momjian.us> writes: > Do the docs need any more updating? No doubt, but it's a bit premature to consider that while we're still arguing whether the code needs to change more. regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Stephen Frost <sfrost@snowman.net> writes: > > Perhaps I was being a bit overzealous in my last response, sorry about > > that. If the point here is that people who are using hostaddr are in an > > environment where DNS is non-functional or actively broken, then yes, > > just bombing out would probably be fine. >=20 > Well, if your environment includes broken DNS then you are clearly going > to get nowhere anyway with Kerberos auth, no? Yes, that's correct as far as I can tell. There may be a way to get Kerberos to work just on IP addresses, but I didn't have any success when trying to force that in my environment. > The point of hostaddr is > *not* to try to avoid that problem. Rather, it's to allow the > application to shift the time expense of the forward DNS lookup to some > other place than its PQconnect() call. If you've got an app where the > cost of PQconnect() is that critical, you're likely going to want to > avoid Kerberos auth anyway, so I don't think it's all that important > exactly how the two features play together. I can agree with that in general, I feel we just need to be very clear that using hostaddr is *only* for that reason, that an IP address *can* be passed to host, and that using hostaddr should be done judiciously since it will break Kerberos, GSSAPI, etc. > As the code stands in HEAD, I think everything is nicely > self-consistent: host is what we believe the server name is for > authentication purposes, and hostaddr is an optional pre-looked-up > address corresponding to that. There is nothing in this suggesting > that we should be expected to try to generate an authentication name > from hostaddr alone. In particular, the fact that Kerberos is capable > of trying to do that is at odds with the other three code paths where > the server name is needed for authentication. I don't feel any need > to expose Kerberos' peculiarity here. Kerberos and GSSAPI act exactly the same in this regard, at a functional level (even if how it gets there is slightly different), from everything I've seen with them (and they're supposed to be compatible to boot, so I'd be suprised if it wasn't the case). One distinction that I'd make is that while we may feel host is the server name for authentication, Kerberos, GSSAPI, SSPI, are just going to use that host to get the IP to do an rDNS lookup to get what *they* feel the hostname for authentication is, and that's what will be requested from the KDC. Reviewing what's currently on developer.postgresql.org, here's what I think the docs would read and what the associated code behavior should be (which I think it's pretty close to already, but perhaps not entirely..): hostaddr This option is not recommended except in cases where PQconnectdb() must avoid a host name look-up. host can be used with regular hostnames, IP addresses, etc, directly. Numeric IP address of host to connect to. This should be in the standard IPv4 address format, e.g., 172.28.40.9. If your machine supports IPv6, you can also use those addresses. TCP/IP communication is always used when a nonempty string is specified for this parameter. Using hostaddr instead of host allows the application to avoid a host name look-up, which might be important in applications with time constraints. However, Kerberos, GSSAPI, and SSPI depend on being able to do a host name look-up, and so are disabled when hostaddr is used without host to prevent a DNS lookup from happening. Full SSL certificate verification requires the client provide the host name (XXX: I don't believe this needs to be the case. If you have a certificate whose CN is an IP address, which I've seen quite a few times in the past, I don't see any reason to break SSL-based auth when hostaddr is used; of course, if you care about speed, SSL negotiation a'int exactly cheap... I don't believe the OpenSSL libs do any DNS lookups; the user must pass in exactly what is in the CN). The following rules are used: If host is specified without hostaddr, a host name lookup occurs. If hostaddr is specified without host, the value for hostaddr gives the server address. The connection attempt will fail in any of the cases where a host name is required. If both host and hostaddr are specified, the value for hostaddr gives the server address. The value for host is ignored unless needed for authentication or verification purposes, in which case it will be used as the host name, and DNS look-ups may occur. (XXX: They will for Kerberos/GSSAPI/SSPI, I don't think they will for SSL unless libpq does a lookup, but that shouldn't be the case here, since hostaddr is populated.) Also, note that host rather than hostaddr is used to identify the connection in ~/.pgpass (see Section 31.14).=20 Thanks, Stephen
Stephen Frost <sfrost@snowman.net> writes: > Reviewing what's currently on developer.postgresql.org, here's what I > think the docs would read and what the associated code behavior should > be (which I think it's pretty close to already, but perhaps not > entirely..): I think this is overcomplicated and probably wrong in detail. I suggest that we document hostaddr as being an auxiliary field that is not intended to be the primary source of the host name, but merely saves libpq from having to do a forward DNS lookup. In some cases it will work to supply hostaddr without host, but in others it won't. We should also state that supplying it does not guarantee no DNS lookups occur, because these external auth libraries will do one anyway. regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > I suggest that we document hostaddr as being an auxiliary field that is > not intended to be the primary source of the host name, but merely saves > libpq from having to do a forward DNS lookup. In some cases it will > work to supply hostaddr without host, but in others it won't. We should > also state that supplying it does not guarantee no DNS lookups occur, > because these external auth libraries will do one anyway. That sounds like it implies we'd also remove the check which prevents Kerberos from being used and fix it to use hostaddr if host is null. That's fine with me. I'd rather have it not broken anyway. Thanks, Stephen
Stephen Frost <sfrost@snowman.net> writes: > * Tom Lane (tgl@sss.pgh.pa.us) wrote: >> I suggest that we document hostaddr as being an auxiliary field that is >> not intended to be the primary source of the host name, but merely saves >> libpq from having to do a forward DNS lookup. In some cases it will >> work to supply hostaddr without host, but in others it won't. We should >> also state that supplying it does not guarantee no DNS lookups occur, >> because these external auth libraries will do one anyway. > That sounds like it implies we'd also remove the check which prevents > Kerberos from being used and fix it to use hostaddr if host is null. Uh, no, it implies no such thing. I don't think that's a "fix", it's merely fuzzing what the values are for. Magnus, I'm curious to hear your thoughts on this... regards, tom lane
On Wed, 14 Jul 2010 18:35:55 -0400 Tom Lane <tgl@sss.pgh.pa.us> wrote: > Bruce Momjian <bruce@momjian.us> writes: > > Do the docs need any more updating? > > No doubt, but it's a bit premature to consider that while we're still > arguing whether the code needs to change more. > > regards, tom lane > Sorry to bother everyone, but AFAICT this discussion kind of disappeared. Did I perhaps get dropped from CC? I'm interested to know what the final resolution of this is. My own thought would be: "host" means the thing you intended to connect to: a unique identifier for the server, probably (usually) the hostname, and also the thing that goes in a certificate. Should (probably) never be omitted. "hostaddr" means the thing you actually send your TCP SYN packet to: maybe an IP address if you want to save a DNS lookup, maybe even "localhost" if you want to use an SSH tunnel (or even some other hostname if you have an even stranger tunnel set up), but purely a "network-layer" thing about *how to get to* the server, and not a "user-trust-layer" thing about *who the server is*. If omitted, defaults to being equal to "host". I don't know if that's what was intended, but that's what I thought they would mean. Chris
On Sun, Dec 19, 2010 at 5:13 PM, Christopher Head <chris2k01@hotmail.com> w= rote: > On Wed, 14 Jul 2010 18:35:55 -0400 > Tom Lane <tgl@sss.pgh.pa.us> wrote: > >> Bruce Momjian <bruce@momjian.us> writes: >> > Do the docs need any more updating? >> >> No doubt, but it's a bit premature to consider that while we're still >> arguing whether the code needs to change more. >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regards, tom lane >> > > Sorry to bother everyone, but AFAICT this discussion kind of > disappeared. Did I perhaps get dropped from CC? I'm interested to know > what the final resolution of this is. I don't think there ever was any more discussion. > My own thought would be: > "host" means the thing you intended to connect to: a unique identifier > for the server, probably (usually) the hostname, and also the thing > that goes in a certificate. Should (probably) never be omitted. > > "hostaddr" means the thing you actually send your TCP SYN packet to: > maybe an IP address if you want to save a DNS lookup, maybe even > "localhost" if you want to use an SSH tunnel (or even some other > hostname if you have an even stranger tunnel set up), but purely a > "network-layer" thing about *how to get to* the server, and not a > "user-trust-layer" thing about *who the server is*. If omitted, > defaults to being equal to "host". > > I don't know if that's what was intended, but that's what I thought > they would mean. Me, too. I reread the original discussion of this topic and I'm still a little fuzzy on it, but the issue that was under discussion seems to be what information we pass to external auth libraries like GSSAPI or Kerberos, given that we have host and hostaddr to choose from. --=20 Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
On Tue, 4 Jan 2011 19:42:38 -0500 Robert Haas <robertmhaas@gmail.com> wrote: > Me, too. I reread the original discussion of this topic and I'm still > a little fuzzy on it, but the issue that was under discussion seems to > be what information we pass to external auth libraries like GSSAPI or > Kerberos, given that we have host and hostaddr to choose from. I'd have thought the logical thing there would be "host", in keeping with the idea that "host is the thing you want to connect to, hostaddr is just how you get there". If you're tunnelling through SSH, you want to ask Kerberos for a ticket to the final end machine, not "localhost", after all. Chris
Christopher Head wrote: > On Wed, 14 Jul 2010 18:35:55 -0400 > Tom Lane <tgl@sss.pgh.pa.us> wrote: > > > Bruce Momjian <bruce@momjian.us> writes: > > > Do the docs need any more updating? > > > > No doubt, but it's a bit premature to consider that while we're still > > arguing whether the code needs to change more. > > > > regards, tom lane > > > > Sorry to bother everyone, but AFAICT this discussion kind of > disappeared. Did I perhaps get dropped from CC? I'm interested to know > what the final resolution of this is. > > My own thought would be: > "host" means the thing you intended to connect to: a unique identifier > for the server, probably (usually) the hostname, and also the thing > that goes in a certificate. Should (probably) never be omitted. > > "hostaddr" means the thing you actually send your TCP SYN packet to: > maybe an IP address if you want to save a DNS lookup, maybe even > "localhost" if you want to use an SSH tunnel (or even some other > hostname if you have an even stranger tunnel set up), but purely a > "network-layer" thing about *how to get to* the server, and not a > "user-trust-layer" thing about *who the server is*. If omitted, > defaults to being equal to "host". > > I don't know if that's what was intended, but that's what I thought > they would mean. I have adjusted the libpq docs to be clearer about 'hostaddr' by using an itemized list and rewording; attached and applied. I am not sure what else needs to be done, and I don't think anyone else knows either, so unless I hear otherwise, I will consider this item closed. Perhaps the clearer docs will highlight a new open item. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. + diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index e78d708..3824588 100644 *** a/doc/src/sgml/libpq.sgml --- b/doc/src/sgml/libpq.sgml *************** PGconn *PQconnectdbParams(const char **k *** 164,185 **** Using <literal>hostaddr</> instead of <literal>host</> allows the application to avoid a host name look-up, which might be important in applications with time constraints. However, a host name is ! required for Kerberos, GSSAPI, or SSPI authentication, as well as ! for full SSL certificate verification. The following rules are ! used: ! If <literal>host</> is specified without <literal>hostaddr</>, ! a host name lookup occurs. ! If <literal>hostaddr</> is specified without <literal>host</>, ! the value for <literal>hostaddr</> gives the server network address. ! The connection attempt will fail in any of the cases where a ! host name is required. ! If both <literal>host</> and <literal>hostaddr</> are specified, ! the value for <literal>hostaddr</> gives the server network address. ! The value for <literal>host</> is ignored unless needed for ! authentication or verification purposes, in which case it will be ! used as the host name. Note that authentication is likely to fail ! if <literal>host</> is not the name of the machine at ! <literal>hostaddr</>. Also, note that <literal>host</> rather than <literal>hostaddr</> is used to identify the connection in <filename>~/.pgpass</> (see <xref linkend="libpq-pgpass">). --- 164,199 ---- Using <literal>hostaddr</> instead of <literal>host</> allows the application to avoid a host name look-up, which might be important in applications with time constraints. However, a host name is ! required for Kerberos, GSSAPI, or SSPI authentication ! methods, as well as for <literal>verify-full</> SSL ! certificate verification. The following rules are used: ! <itemizedlist> ! <listitem> ! <para> ! If <literal>host</> is specified without <literal>hostaddr</>, ! a host name lookup occurs. ! </para> ! </listitem> ! <listitem> ! <para> ! If <literal>hostaddr</> is specified without <literal>host</>, ! the value for <literal>hostaddr</> gives the server network address. ! The connection attempt will fail if the authentication ! method requires a host name. ! </para> ! </listitem> ! <listitem> ! <para> ! If both <literal>host</> and <literal>hostaddr</> are specified, ! the value for <literal>hostaddr</> gives the server network address. ! The value for <literal>host</> is ignored unless the ! authentication method requires it, in which case it will be ! used as the host name. ! </para> ! </listitem> ! </itemizedlist> ! Note that authentication is likely to fail if <literal>host</> ! is not the name of the server at network address <literal>hostaddr</>. Also, note that <literal>host</> rather than <literal>hostaddr</> is used to identify the connection in <filename>~/.pgpass</> (see <xref linkend="libpq-pgpass">).