We help IT Professionals succeed at work.
Get Started
Troubleshooting Question

gethostbyname() returns incorrect information

Dr. Klahn
Dr. Klahn asked
on
70 Views
Last Modified: 2020-11-06
This Debian linux system recently started producing errors due to incorrect DNSBL lookups in Apache loadable modules.

a) The problem's not in Apache.  It can be reproduced in a little test program shown below.
b) The modules have been in use for over four years before this problem occurred last week.

/* Standard program for confirming Project Spamhaus DNS lookup */
/* If this fails, something's wrong somewhere in DNS */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>


void main() {


  static int oct1, oct2, oct3, oct4;
  struct in_addr addr;
  struct hostent *hp = 0;


/* =====================================================
 * Stage 1.  Lookup 2.0.0.127.sbl.spamhaus.org
 *
 * Should return 127.0.0.2
 * =====================================================
 */


  printf("\n================== FIRST TEST ===================\n\n");
  printf("Lookup 2.0.0.127.sbl.spamhaus.org\n");
  printf("Expected result success, 127.0.0.2\n\n");
  hp = gethostbyname("2.0.0.127.sbl.spamhaus.org");
  if (hp == NULL) {
    printf("Validation failed, h_errno = %d <%s>\n",
            h_errno, hstrerror(h_errno));
    return;
  }


  /* Isn't this next line horrible? */
  addr.s_addr = *(u_long *) hp->h_addr_list[0];
  printf("Official name = <%s>\n", hp->h_name);
  printf("Address length in bytes = %d\n", hp->h_length);
  sscanf(inet_ntoa(addr), "%u.%u.%u.%u",
         &oct1, &oct2, &oct3, &oct4);
  printf("Resolved to %u.%u.%u.%u\n\n", oct1, oct2, oct3, oct4);


  if ((oct1 != 127) || (oct2 != 0) || (oct3 != 0) || (oct4 != 2)) {
    printf("Validation failed, result not 127.0.0.2\n\n");
    printf("================== FAILURE ===================\n\n");
    return;
  }

  printf ("Validation successful\n\n");

/* =====================================================
 * Stage 2.  Lookup 1.0.0.127.sbl.spamhaus.org
 *
 * Should return failure
 * =====================================================
 */

  printf("================== SECOND TEST ===================\n\n");
  printf("Lookup 1.0.0.127.sbl.spamhaus.org\n");
  printf("Expected result failure\n\n");
  hp = gethostbyname("1.0.0.127.sbl.spamhaus.org");
  if (hp == NULL) {
    printf("Lookup failed, h_errno = %d <%s>\n\n",
            h_errno, hstrerror(h_errno));
    printf ("Validation successful\n\n");
    printf("================= ALL TESTS PASS =================\n\n");
    return;
  }

  /* Isn't this next line horrible? */
  addr.s_addr = *(u_long *) hp->h_addr_list[0];
  printf("Official name = <%s>\n", hp->h_name);
  printf("Address length in bytes = %d\n", hp->h_length);
  sscanf(inet_ntoa(addr), "%u.%u.%u.%u",
         &oct1, &oct2, &oct3, &oct4);
  printf("Resolved to %u.%u.%u.%u\n\n", oct1, oct2, oct3, oct4);
  printf("Validation failed, result should not exist\n\n");
  printf("================== FAILURE ===================\n\n");
  return;
}

Compiling and running the test program produces unexpected (I won't say incorrect; the system has some reason for doing this) results.

root:/usr/src/mod_spamhaus/src> ./a.out

================== FIRST TEST ===================

Lookup 2.0.0.127.sbl.spamhaus.org
Expected result success, 127.0.0.2

Official name = <2.0.0.127.sbl.spamhaus.org>
Address length in bytes = 4
Resolved to 127.0.0.2

Validation successful

================== SECOND TEST ===================

Lookup 1.0.0.127.sbl.spamhaus.org
Expected result failure

Official name = <1.0.0.127.sbl.spamhaus.org.my-domain-name.com>
Address length in bytes = 4
Resolved to xxx.yyy.zzz.aaa (the host's IP address)

Validation failed, result should not exist

================== FAILURE ===================

root:/usr/src/mod_spamhaus/src>

Note the response from the second lookup -- the official name returned by the lookup has the host's domain name tagged onto the tail.  This has not been seen previously on any of the systems where the test program was executed.

The problem is specific to gethostbyname, because nslookup returns the correct value - no such domain - and dig also returns the correct info.

root:/usr/src/mod_spamhaus/src> nslookup 1.0.0.127.sbl.spamhaus.org
Server:         84.200.69.80
Address:        84.200.69.80#53

** server can't find 1.0.0.127.sbl.spamhaus.org: NXDOMAIN
root:/usr/src/mod_spamhaus/src> dig 1.0.0.127.sbl.spamhaus.org

; <<>> DiG 9.10.3-P4-Debian <<>> 1.0.0.127.sbl.spamhaus.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 58161
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;1.0.0.127.sbl.spamhaus.org.    IN      A

;; AUTHORITY SECTION:
sbl.spamhaus.org.       8       IN      SOA     need.to.know.only. hostmaster.spamhaus.org. 2011051822 3600 600 432000 10

;; Query time: 127 msec
;; SERVER: 84.200.69.80#53(84.200.69.80)
;; WHEN: Thu Nov 05 18:23:28 GMT 2020
;; MSG SIZE  rcvd: 119

root:/usr/src/mod_spamhaus/src>

So the question is:  What's going on in the DNS subsystem that this issue suddenly cropped up?

Further info:
The host runs Debian that is some years old, not automatically updated, and very little should change in the system.

The DNS servers have not been changed recently.

/etc/resolv.conf contents:
# 1.1.1.1 open nameserver
# Four ones does not properly resolve spamhaus lookups
# nameserver 1.1.1.1


# OpenNIC nameservers
# May be blocked in iptables
# nameserver 172.98.193.42


# dns.watch IPv4 nameservers
nameserver 84.200.69.80    # resolver1.dns.watch
nameserver 84.200.70.40    # resolver2.dns.watch
nameserver 208.67.220.220
nameserver 208.67.222.222


Comment
Watch Question
Principal Software Engineer
CERTIFIED EXPERT
Commented:
This problem has been solved!
Unlock 1 Answer and 18 Comments.
See Answer
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant

An Experts Exchange subscription includes unlimited access to online courses.

Get Started
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE