DNS resolution in chroot jail

"Michael Procter" <[email protected]> Wed, 19 Oct 2005 13:38:42 +0100
Newsgroups gmane.network.siproxd
Message-ID <[email protected]>
I'm running siproxd snapshot from 4th October, and was testing the
'multiple contact handling' in sip_rewrite_contact.  During my testing,
I found another problem, this time associated with DNS resolution.  I
think I may have updated something on my system to break it, as I don't
think you have changed it between these releases.

The problem is that once chrooted, siproxd cannot resolve DNS names.  I
can see in utils.c:secure_environment() that you perform a lookup of
'localhost' before chrooting, to fix this problem.  But for me, it
doesn't.  I added an additional line, just after the lookup of
'localhost', and before the chroot, of the form:

	get_ip_by_host("www.google.com", &dummy);

which made it work as I expect.

I think the problem is that 'localhost' can be looked up without
resorting to a remote DNS lookup, so all the relevant libraries are not
installed before the call to chroot.

I did an 'strace' of siproxd starting up, and here is an extract of the
work done between looking up 'localhost' and looking up
'www.google.com'.

time([1129723469])                      = 1129723469
write(2, "13:04:29 utils.c:194 ", 2113:04:29 utils.c:194 )   = 21
write(2, "DNS lookup - resolved: localhost"..., 45DNS lookup - resolved:
localhost -> 127.0.0.1) = 45
write(2, "\n", 1
)                       = 1
time([1129723469])                      = 1129723469
write(2, "13:04:29 utils.c:214 ", 2113:04:29 utils.c:214 )   = 21
write(2, "DNS lookup - store into cache, e"..., 39DNS lookup - store
into cache, entry 0)) = 39
write(2, "\n", 1
)                       = 1
time([1129723469])                      = 1129723469
time([1129723469])                      = 1129723469
open("/etc/hosts", O_RDONLY)            = 4
fcntl64(4, F_GETFD)                     = 0
fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=217, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x40017000
read(4, "127.0.0.1 localhost.localdomain "..., 4096) = 217
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0x40017000, 4096)                = 0
open("/etc/ld.so.cache", O_RDONLY)      = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=57385, ...}) = 0
old_mmap(NULL, 57385, PROT_READ, MAP_PRIVATE, 4, 0) = 0x40017000
close(4)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or
directory)
open("/lib/libnss_dns.so.2", O_RDONLY)  = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\r\0"...,
512) = 512
fstat64(4, {st_mode=S_IFREG|0644, st_size=17840, ...}) = 0
old_mmap(NULL, 20616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4,
0) = 0x40217000
old_mmap(0x4021b000, 8192, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x3000) = 0x4021b000
close(4)                                = 0
munmap(0x40017000, 57385)               = 0
gettimeofday({1129723469, 797825}, NULL) = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53),
sin_addr=inet_addr("10.7.1.2")}, 28) = 0
fcntl64(4, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
gettimeofday({1129723469, 798933}, NULL) = 0
poll([{fd=4, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
send(4, "\340\333\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\1\0"..., 32,
0) = 32
poll([{fd=4, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
ioctl(4, FIONREAD, [100])               = 0
recvfrom(4, "\340\333\201\200\0\1\0\4\0\0\0\0\3www\6google\3com\0\0"...,
1024, 0, {sa_family=AF_INET, sin_port=htons(53),
sin_addr=inet_addr("10.7.1.2")}, [16]) = 100
close(4)                                = 0
time([1129723470])                      = 1129723470
write(2, "13:04:30 utils.c:194 ", 2113:04:30 utils.c:194 )   = 21
write(2, "DNS lookup - resolved: www.googl"..., 52DNS lookup - resolved:
www.google.com -> 66.102.9.99) = 52
write(2, "\n", 1
)                       = 1
time([1129723470])                      = 1129723470
write(2, "13:04:30 utils.c:214 ", 2113:04:30 utils.c:214 )   = 21
write(2, "DNS lookup - store into cache, e"..., 39DNS lookup - store
into cache, entry 1)) = 39
write(2, "\n", 1
)                       = 1
time([1129723470])                      = 1129723470
time([1129723470])                      = 1129723470
write(2, "13:04:30 utils.c:259 ", 2113:04:30 utils.c:259 )   = 21
write(2, "chrooting to /var/lib/siproxd/", 30chrooting to
/var/lib/siproxd/) = 30


This suggests to me that an additional library is pulled in for remote
lookups, and also that hosts only listed in /etc/hosts will not be
visible after the chroot, unless you create a new /etc/hosts within the
chroot jail, or hardlink to the existing one.

I suppose you could also hardlink the libraries that it needs into the
right place within the chroot jail to get this to work too, rather than
forcing a lookup of an address that won't be resolved locally.  And this
might be the better solution - setting up the chroot jail so that all
the relevant libraries are available.

Regards,

Michael Procter


-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl