Skip to content

socket.getfqdn() doesn't cope properly with purely DNS-based setups #49254

Open

Description

@dfranke
mannequin
BPO 5004
Nosy @loewis, @tiran, @mcepl, @bitdancer, @ThomasWaldmann, @jan-hudec, @shoop
Files
  • python2.7-socket-getfqdn.patch
  • python5004-test.c: test C program showing various gethost function output on my system
  • python2.7-socket-getfqdn.patch: Updated patch, originally by Stijn.Hoop
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2009-01-19.22:29:02.219>
    labels = ['type-bug', 'library', '3.9', '3.10', '3.11']
    title = "socket.getfqdn() doesn't cope properly with purely DNS-based setups"
    updated_at = <Date 2021-12-16.17:35:04.319>
    user = 'https://bugs.python.org/dfranke'

    bugs.python.org fields:

    activity = <Date 2021-12-16.17:35:04.319>
    actor = 'mcepl'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2009-01-19.22:29:02.219>
    creator = 'dfranke'
    dependencies = []
    files = ['29919', '29921', '50390']
    hgrepos = []
    issue_num = 5004
    keywords = ['patch']
    message_count = 24.0
    messages = ['80216', '109635', '109647', '162508', '173987', '187065', '187098', '187234', '187237', '187238', '187253', '187256', '187350', '187355', '297435', '300593', '308979', '372583', '404775', '404780', '404796', '404806', '404826', '405364']
    nosy_count = 14.0
    nosy_names = ['loewis', 'christian.heimes', 'mcepl', 'r.david.murray', 'dfranke', 'devurandom', 'mcjeff', 'ankitoshniwal', 'Thomas.Waldmann', 'Stijn.Hoop', 'bulb', 'James Shewey', 'richard.security.consultant', 'shoop']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue5004'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Activity

    1. dfranke commented on Jan 19, 2009

      dfrankemannequin
      MannequinAuthor

      On Linux and presumably on other POSIX-like systems, socket.getfqdn()
      doesn't work if a system resolves its own FQDN using DNS rather than
      /etc/hosts.

      My system's FQDN is 'fugue.tank.wellohorld.com'. My /etc/hosts is empty
      except for loopback entries, and /etc/resolv.conf contains the line
      'domain tank.wellohorld.com'. This is sufficient for 'hostname -f' to
      do the Right Thing, but socket.getfqdn() simply returns 'fugue':

      dfranke@fugue:~/Python-2.6.1$ hostname
      fugue
      dfranke@fugue:~/Python-2.6.1$ hostname -f
      fugue.tank.wellohorld.com
      dfranke@fugue:~/Python-2.6.1$ ./python
      Python 2.6.1 (r261:67515, Jan 19 2009, 13:56:59)
      [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import socket
      >>> socket.getfqdn()
      'fugue'
      >>>
      dfranke@fugue:~/Python-2.6.1$ echo -e '$a\n172.17.0.120
      fugue.tank.wellohorld.com fugue\n.\nwq' | sudo ed /etc/hosts
      305
      350
      dfranke@fugue:~/Python-2.6.1$ ./python
      Python 2.6.1 (r261:67515, Jan 19 2009, 13:56:59)
      [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import socket
      >>> socket.getfqdn()
      'fugue.tank.wellohorld.com'
      >>>
      dfranke@fugue:~/Python-2.6.1$
    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      and removed
      stdlibStandard Library Python modules in the Lib/ directory
      on Jan 19, 2009
    3. BreamoreBoy commented on Jul 8, 2010

      BreamoreBoymannequin
      Mannequin

      Would someone with appropriate knowledge please take a look to see if this is still an issue.

    4. added
      stdlibStandard Library Python modules in the Lib/ directory
      and removed on Jul 8, 2010
    5. loewis commented on Jul 9, 2010

      loewismannequin
      Mannequin

      I think anybody willing to invest the time could acquire the appropriate knowledge, at least to determine whether it's still an issue (i.e. trying to reproduce it). To fix it, one would then need to read the source code of hostname, and find out what they do differently; strace might be sufficient already.

    6. ankitoshniwal commented on Jun 7, 2012

      ankitoshniwalmannequin
      Mannequin

      I cannot reproduce this issue. I just tested this on my mac.

      atoshniw@prusev-mn:~/Documents/code/python-dev/bin #hostname -f
      prusev-mn.helloworld.com
      atoshniw@prusev-mn:~/Documents/code/python-dev/bin #python
      Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) 
      [GCC 4.2.1 (Apple Inc. build 5646)] on darwin
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import socket
      >>> socket.getfqdn()
      'prusev-mn.helloworld.com'
    7. mcjeff commented on Oct 28, 2012

      mcjeffmannequin
      Mannequin

      Gave this a go myself...

      $ ./python
      Python 3.4.0a0 (default:57a33af85407, Oct 27 2012, 21:26:30) 
      [GCC 4.4.3] on linux
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import socket
      >>> socket.getfqdn()
      'host.domain.com'
      >>> 
      $ hostname -f
      host.domain.com
      
      $ cat /etc/hosts
      127.0.0.1       localhost.localdomain   localhost

      # The following lines are desirable for IPv6 capable hosts
      ::1 ip6-localhost ip6-loopback
      fe00::0 ip6-localnet
      ff00::0 ip6-mcastprefix
      ff02::1 ip6-allnodes
      ff02::2 ip6-allrouters

      Linux host 3.5.2-x86_64 #1 SMP Wed Aug 15 14:31:07 EDT 2012 x86_64 GNU/Linux

      According to strace, both rely on DNS:

      recvfrom(3, "Wj\201\200\0\1\0\1\0\5\0\0\00219\003134\003230\003173\7in-a"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("1.2.3.4")}, [16]) = 176

      Same behavior on both 2.6 & hg tip. I think this is a non-issue.

    8. StijnHoop commented on Apr 16, 2013

      StijnHoopmannequin
      Mannequin

      Still seeing this on Fedora 18 / Python 2.7.3.

      I only have loopback in /etc/hosts

      [TUE\shoop@pclin281] <~> cat /etc/hosts
      127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
      ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

      I search in .campus.tue.nl and .win.tue.nl:

      [TUE\shoop@pclin281] <~> grep search /etc/resolv.conf
      search campus.tue.nl. win.tue.nl.

      Hostname -f reliably returns .campus.tue.nl as it should

      [TUE\shoop@pclin281] <> hostname -f
      pclin281.campus.tue.nl
      [TUE\shoop@pclin281] <
      > hostname -f
      pclin281.campus.tue.nl

      But socket.getfqdn disagrees, even with itself when run multiple times:

      [TUE\shoop@pclin281] <~> python
      Python 2.7.3 (default, Aug  9 2012, 17:23:57) 
      [GCC 4.7.1 20120720 (Red Hat 4.7.1-5)] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import socket
      >>> socket.getfqdn()
      'pclin281'
      >>> socket.getfqdn()
      'pclin281.win.tue.nl'
      >>> socket.getfqdn()
      'pclin281'
      >>> socket.getfqdn()
      'pclin281.win.tue.nl'
      >>> 

      Note that pclin281.win.tue.nl is in fact also a valid DNS entry, but not one that I would expect the function to ever return given the search order.

    9. bitdancer commented on Apr 16, 2013

      @bitdancer
      Member

      Note that socket.getfqdn is a wrapper around a couple of socket calls that are just wrappers of OS level socket calls. If you take a look at socket.py you'll see the definition. As Martin said earlier, if you (or anyone else) can figure out what hostname does differently and suggest how to patch our getfqdn method to behave similarly, I'm sure the patch will be welcome.

      Unfortunately there won't be any good way to write a test for this.

    10. StijnHoop commented on Apr 18, 2013

      StijnHoopmannequin
      Mannequin

      OK, fair enough.

      From reading sources, it appears that hostname is using getaddrinfo(3) on kernelhostname with hints->ai_flags & AI_CANONNAME, while Lib/socket.py simply uses gethostbyaddr(kernelhostname), and falls back on kernelhostname in case of errors.

      Unfortunately I am not entirely sure who is "correct" here, as I don't know the intent of socket.getfqdn().

      In my case, kernelhostname is set to 'pclin281' e.g. without the dots. I believe this to be correct, but I know that this is already "controversial" as in there exists software that expects an FQDN there, and internet folklore is split about 50/50 about this necessity.

      Then, apparently, there is confusion about AI_CANONNAME and what it actually should do. glibc upstream does address lookups but Fedora patches this out. See this recent glibc bug for more pointers:

      http://sourceware.org/bugzilla/show_bug.cgi?id=15218

      As mentioned in that bug, a lot of software runs on Fedora and works using that definition of AI_CANONNAME.

      However, switching Lib/socket.py / getfqdn from gethostbyaddr to getaddrinfo might have more implications than just fixing this case. I can try to write a patch, but is this the right direction?

    11. StijnHoop commented on Apr 18, 2013

      StijnHoopmannequin
      Mannequin

      Attached is a very lightly tested patch that matches hostname -f behaviour on my system. I suspect this should be OK but it definitely needs more testing than just my system...

    12. 26 remaining items

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.10 (EOL)end of life3.11only security fixes3.9 (EOL)end of lifestdlibStandard Library Python modules in the Lib/ directorytopic-socketRelated to the socket, socketserver and selectors modulestype-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions