How can I find out what files or sockets are needed by Curl when running in a chroot'ed PHP environment on Mac OSX?
I recently secured my website by chrooting PHP but now every call to Amazon S3 through it's API is failing, with the error message:
Resource id #43; cURL error: Couldn't resolve host 's3.amazonaws.com'
The same code works fine when called from a non-chroot`ed command line so presumably it's some set of files that need to be opened by CURL that are failing to be opened.
How do I figure out which files it's trying to open to be able to map them into the chroot'ed directoy?
With Andrei's suggestion I used strace (or rather dtruss the mac equivalent) to get some debug output.
This is a request that is chrooted and doesn't work.
lstat64("/lib/amazonWS/lib\0", 0x7FFF5FBF97D0, 0x26) = 0 0
lstat64("/lib/amazonWS\0", 0x7FFF5FBF9630, 0x182) = 0 0
open("/lib/amazonWS/lib/requestcore/requestcore.class.php\0", 0x0, 0x1B6) = 5 0
fstat64(0x5, 0x100A9F448, 0x8) = 0 0
fstat64(0x5, 0x100A9F448, 0x90) = 0 0
fstat64(0x5, 0x100A9F448, 0x1001B1FE4) = 0 0
mmap(0x0, 0x72D1, 0x1, 0x1, 0x5, 0xFFFFFF8016E89160) = 0x3BF0000 0
stat64("/lib/amazonWS/lib/requestcore/requestcore.class.php\0", 0x10621CD68, 0x10621C847) = 0 0
munmap(0x103BF0000, 0x72D1) = 0 0
close(0x5) = 0 0
setitimer(0x2, 0x7FFF5FBFBCE0, 0x0) = 0 0
kqueue(0x7FFF5FBFB000, 0x0, 0x50) = 5 0
kevent(0x5, 0x7FFF5FBFB000, 0x1) = 0 0
socket(0x1, 0x1, 0x0) = 6 0
setsockopt(0x6, 0xFFFF, 0x1022) = 0 0
connect_nocancel(0x6, 0x7FFF5FBFADD0, 0x6A) = -1 Err#2
close_nocancel(0x6) = 0 0
close_nocancel(0x5) = 0 0
kqueue(0x7FFF5FBFB000, 0x0, 0x50) = 5 0
kevent(0x5, 0x7FFF5FBFB000, 0x1) = 0 0
socket(0x1, 0x1, 0x0) = 6 0
setsockopt(0x6, 0xFFFF, 0x1022) = 0 0
connect_nocancel(0x6, 0x7FFF5FBFADD0, 0x6A) = -1 Err#2
close_nocancel(0x6) = 0 0
close_nocancel(0x5) = 0 0
open_nocancel(".\0", 0x0, 0x0) = 5 0
fstat64(0x5, 0x7FFF5FBFBA80, 0x0) = 0 0
fcntl_nocancel(0x5, 0x32, 0x7FFF5FBFBCB0) = 0 0
close_nocancel(0x5) = 0 0
stat64("/basereality\0", 0x7FFF5FBFB9F0, 0x0) = 0 0
lstat64("/basereality/../BaseReality/html/50x.html\0", 0x7FFF5FBFB730, 0x23D) = 0 0
This is a request that is not chrooted and works:
1806/0x1dd3: 149524 5 3 open("/documents/projects/intahwebz/intahwebz/lib/amazonWS/lib/requestcore/requestcore.class.php\0", 0x0, 0x1B6) = 5 0
1806/0x1dd3: 149525 3 0 fstat64(0x5, 0x100A9F578, 0x8) = 0 0
1806/0x1dd3: 149527 2 0 fstat64(0x5, 0x100A9F578, 0x90) = 0 0
1806/0x1dd3: 149528 2 0 fstat64(0x5, 0x100A9F578, 0x1001B1FE4) = 0 0
1806/0x1dd3: 149531 5 2 mmap(0x0, 0x72D1, 0x1, 0x1, 0x5, 0x1F) = 0x3BF0000 0
1806/0x1dd3: 149535 4 2 stat64("/documents/projects/intahwebz/intahwebz/lib/amazonWS/lib/requestcore/requestcore.class.php\0", 0x1061966D0, 0x106196057) = 0 0
1806/0x1dd3: 149565 6 3 munmap(0x103BF0000, 0x72D1) = 0 0
1806/0x1dd3: 149568 4 2 close(0x5) = 0 0
1806/0x1dd3: 149661 4 1 setitimer(0x2, 0x7FFF5FBFBCE0, 0x0) = 0 0
1806/0x1dd3: 149767 90 2 kqueue(0x7FFF5FBFB000, 0x0, 0x50) = 5 0
1806/0x1dd3: 149770 4 1 kevent(0x5, 0x7FFF5FBFB000, 0x1) = 0 0
1806/0x1dd3: 149782 12 8 socketpair(0x1, 0x1, 0x0) = 0 0
1806/0x1dd3: 149792 12 9 sendto_nocancel(0x6, 0x105D8FCF0, 0x3A) = 58 0
1806/0x1dd3: 149796 7 3 sendmsg_nocancel(0x6, 0x7FFF5FBFAD30, 0x0) = 1 0
1806/0x1dd3: 149797 4 0 close_nocancel(0x9) = 0 0
1806/0x1dd3: 149802 45 4 recvfrom_nocancel(0x7, 0x7FFF5FBFAD7C, 0x4) = 4 0
1806/0x1dd3: 149806 5 2 close_nocancel(0x7) = 0 0
1806/0x1dd3: 149814 6 3 socketpair(0x1, 0x1, 0x0) = 0 0
1806/0x1dd3: 149816 4 1 sendto_nocancel(0x6, 0x105D8FCF0, 0x3A) = 58 0
1806/0x1dd3: 149818 5 2 sendmsg_nocancel(0x6, 0x7FFF5FBFAD30, 0x0) = 1 0
1806/0x1dd3: 149819 3 0 close_nocancel(0x9) = 0 0
1806/0x1dd3: 149822 215 2 recvfrom_nocancel(0x7, 0x7FFF5FBFAD7C, 0x4) = 4 0
1806/0x1dd3: 149840 20 17 close_nocancel(0x7) = 0 0
1806/0x1dd3: 149843 4 1 kevent(0x5, 0x7FFF5FBFB000, 0x1) = 0 0
1806/0x1dd3: 149844 3 1 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149846 2 0 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149848 5 2 recvfrom_nocancel(0x6, 0x7FFF5FBFAE30, 0x1C) = 28 0
1806/0x1dd3: 149851 5 1 recvfrom_nocancel(0x6, 0x105D8FCF0, 0x40) = 64 0
1806/0x1dd3: 149856 8 3 select_nocancel(0x7, 0x7FFF5FBFADB0, 0x0) = 1 0
1806/0x1dd3: 149861 3 1 kevent(0x5, 0x7FFF5FBFA860, 0x1) = 0 0
1806/0x1dd3: 149863 4 1 recvfrom_nocancel(0x6, 0x7FFF5FBFAE30, 0x1C) = 28 0
1806/0x1dd3: 149864 3 1 recvfrom_nocancel(0x6, 0x105D85990, 0x42) = 66 0
1806/0x1dd3: 149867 4 1 select_nocancel(0x7, 0x7FFF5FBFADB0, 0x0) = 0 0
1806/0x1dd3: 149869 2 0 kevent(0x5, 0x7FFF5FBFA860, 0x1) = 0 0
1806/0x1dd3: 149871 3 1 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149872 2 0 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149873 2 0 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149874 2 0 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149876 4 1 recvfrom_nocancel(0x6, 0x7FFF5FBFAE30, 0x1C) = 28 0
1806/0x1dd3: 149877 4 0 recvfrom_nocancel(0x6, 0x105D859E0, 0x40) = 64 0
1806/0x1dd3: 149879 3 1 select_nocancel(0x7, 0x7FFF5FBFADB0, 0x0) = 1 0
1806/0x1dd3: 149881 2 0 kevent(0x5, 0x7FFF5FBFA860, 0x1) = 0 0
1806/0x1dd3: 149883 3 0 recvfrom_nocancel(0x6, 0x7FFF5FBFAE30, 0x1C) = 28 0
1806/0x1dd3: 149884 3 0 recvfrom_nocancel(0x6, 0x105D85A20, 0x42) = 66 0
1806/0x1dd3: 149886 3 1 select_nocancel(0x7, 0x7FFF5FBFADB0, 0x0) = 0 0
1806/0x1dd3: 149888 2 0 kevent(0x5, 0x7FFF5FBFA860, 0x1) = 0 0
1806/0x1dd3: 149889 2 0 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149890 2 0 kevent(0x5, 0x0, 0x0) = 0 0
1806/0x1dd3: 149900 389953 9 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149904 60 1 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149909 7 3 recvfrom_nocancel(0x6, 0x7FFF5FBFAE30, 0x1C) = 28 0
1806/0x1dd3: 149913 7 2 recvfrom_nocancel(0x6, 0x105D8FD10, 0x2E) = 46 0
1806/0x1dd3: 149921 9 4 select_nocancel(0x7, 0x7FFF5FBFADB0, 0x0) = 0 0
1806/0x1dd3: 149928 5 1 kevent(0x5, 0x7FFF5FBFA860, 0x1) = 0 0
1806/0x1dd3: 149932 3 1 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149932 2 0 kevent(0x5, 0x0, 0x0) = 0 0
1806/0x1dd3: 149945 439745 12 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149952 13 3 kevent(0x5, 0x0, 0x0) = 1 0
1806/0x1dd3: 149961 15 6 recvfrom_nocancel(0x6, 0x7FFF5FBFAE30, 0x1C) = 28 0
1806/0x1dd3: 149969 11 4 recvfrom_nocancel(0x6, 0x105D8FD10, 0x2A) = 42 0
1806/0x1dd3: 149981 16 8 select_nocancel(0x7, 0x7FFF5FBFADB0, 0x0) = 0 0
1806/0x1dd3: 149987 9 3 kevent(0x5, 0x7FFF5FBFA860, 0x1) = 0 0
1806/0x1dd3: 150002 19 9 sendto_nocancel(0x6, 0x105D8FCF0, 0x1C) = 28 0
1806/0x1dd3: 150011 12 5 sendto_nocancel(0x6, 0x105D8FCF0, 0x1C) = 28 0
1806/0x1dd3: 150025 22 10 close_nocancel(0x5) = 0 0
1806/0x1dd3: 150095 26 18 socket(0x2, 0x1, 0x6) = 5 0
1806/0x1dd3: 150109 12 4 setsockopt(0x5, 0xFFFF, 0x1022) = 0 0
1806/0x1dd3: 150113 9 2 fcntl(0x5, 0x3, 0x0) = 2 0
1806/0x1dd3: 150117 7 2 fcntl(0x5, 0x4, 0x6) = 0 0
1806/0x1dd3: 150191 81 73 connect(0x5, 0x7FFF5FBFB9F0, 0x10) = -1 Err#36
1806/0x1dd3: 150217 689426 21 select(0x6, 0x7FFF5FBFB730, 0x7FFF5FBFB6B0, 0x7FFF5FBFB630, 0x7FFF5FBFB7D0) = 1 0
1806/0x1dd3: 150226 72 2 getsockopt(0x5, 0xFFFF, 0x1007) = 0 0
1806/0x1dd3: 150230 6 2 getpeername(0x5, 0x7FFF5FBFB780, 0x7FFF5FBFB6FC) = 0 0
1806/0x1dd3: 150232 4 1 getsockname(0x5, 0x7FFF5FBFB700, 0x7FFF5FBFB6FC) = 0 0
1806/0x1dd3: 150332 23 17 open_nocancel("/opt/local/share/curl/curl-ca-bundle.crt\0", 0x0, 0x1B6) = 7 0
1806/0x1dd3: 150339 6 2 fstat64(0x7, 0x7FFF5FBFB440, 0x7FFF5FBFB50C) = 0 0
1806/0x1dd3: 150350 14 9 read_nocancel(0x7, "##\n## lib/ca-bundle.crt -- Bundle of CA Root Certificates\n##\n## Certificate data from Mozilla as of: Thu Nov 22 00:12:21 2012\n##\n## This is a bundle of X.509 certificates of public Certificate Authorities\n## (CA). These were automatically extracted from Mo", 0x1000) = 4096 0
So it looks like it isn't a direct file access that's failing in the process but socket send. I'm following some instructions to try set up /dev/urandom and other non-file paths into the chrooted environment, but again, is there any way to know what socket socketpair(0x1, 0x1, 0x0)
is rather than just working in the dark?
Update 2
It's a known problem on OSX to do a DNS lookup inside a chroot: https://lists.macosforge.org/pipermail/macports-dev/2011-April/014565.html
Apparently I need to run a mDNSResponder service at /path/to/chroot/var/run/mDNSResponder
Probably there are DNS issue, check if there are correct resolv.conf under your chroot environment.
So, apparently on OSX all system calls to
gethostbyname
are directed through the mDNSResponder service which is running as a socket at /var/run/mDNSResponder which is different from Linux platforms where DNS requests are just sent through files such as resolv.conf.mDNSResponder is not available in the chroot'ed environment and so all DNS lookups will fail.
Theoretically it's possible to create a duplicate mDNSResponder service that is listening on a socket at /chroot/var/run/mDNSResponder. However no-one appears to have actually done this.
What is much easier to do is to set up a proxy service e.g. with Squidman running on the localhost and then make all HTTP requests through it.
Also to note creating your own dev/random and dev/urandom inside the chroot with
mknod
doesn't appear to work as they run out of randomness, and the proxy requests will fail. Instead you should link them withsudo ln -s /dev/urandom /chroot/dev/urandom