如何在El Capitan的Mac OS X"chroot"中使用DNS解析?

hor*_*irs 12 sockets macos chroot

我正在尝试创建一个chroot来运行一个需要Internet访问的程序来构建一个沙盒化的,不可变的开发人员环境.到目前为止,我的监狱工作得很好:我可以在其中运行bash并从那里运行简单的程序!但DNS解析不起作用:

bash-3.2$ curl google.ca
curl: (6) Could not resolve host: google.ca
Run Code Online (Sandbox Code Playgroud)

我几乎肯定这是因为内部进程无法连接到mDNSResponder在jail外运行的守护进程.在监狱外面有一个mDNSResponder供整个系统使用的插座:

host ?  ls -lA /var/run/mDNSResponder
srw-rw-rw-  1 root  daemon  0 22 Oct 10:41 /var/run/mDNSResponder
Run Code Online (Sandbox Code Playgroud)

但是,在监狱里面却没有.所以,我试图用socat从监狱中创建一个Unix套接字"代理"到外面:我跑socat(以下命令)创建我的监狱内的插座,然后在监狱内运行再次卷曲,而且卷曲仍然给出了相同的错误消息.在mDNSResponder使用SIGUSR1 打开详细日志后,我在syslog中看到了这个:

2015-10-26 5:32:30.835 PM mDNSResponder[95]:  12: connect_callback: Adding FD for uid 0
2015-10-26 5:32:30.835 PM mDNSResponder[95]:  12: DNSServiceCreateConnection START PID[23271](socat)
2015-10-26 5:32:30.836 PM mDNSResponder[95]:  12: read_msg: ERROR failed to get errsd via SCM_RIGHTS
2015-10-26 5:32:30.836 PM mDNSResponder[95]:  12: DNSServiceCreateConnection STOP PID[23271](socat)
2015-10-26 5:32:30.836 PM mDNSResponder[95]:  12: Removing FD
2015-10-26 5:32:31.339 PM curl[23269]: dnssd_clientstub read_all(5) failed 0/4 0 
2015-10-26 5:32:31.339 PM curl[23269]: dnssd_clientstub write_all(4) failed -1/28 32 Broken pipe
2015-10-26 5:32:31.341 PM mDNSResponder[95]:  12: connect_callback: Adding FD for uid 0
2015-10-26 5:32:31.341 PM mDNSResponder[95]:  12: DNSServiceCreateConnection START PID[23272](socat)
2015-10-26 5:32:31.342 PM mDNSResponder[95]:  12: read_msg: ERROR failed to get errsd via SCM_RIGHTS
2015-10-26 5:32:31.342 PM mDNSResponder[95]:  12: DNSServiceCreateConnection STOP PID[23272](socat)
2015-10-26 5:32:31.342 PM mDNSResponder[95]:  12: Removing FD
2015-10-26 5:32:31.844 PM curl[23269]: dnssd_clientstub read_all(5) failed 0/4 0 
2015-10-26 5:32:31.846 PM mDNSResponder[95]:  12: connect_callback: Adding FD for uid 0
2015-10-26 5:32:31.846 PM mDNSResponder[95]:  12: DNSServiceCreateConnection START PID[23274](socat)
2015-10-26 5:32:31.847 PM mDNSResponder[95]:  12: read_msg: ERROR failed to get errsd via SCM_RIGHTS
2015-10-26 5:32:31.847 PM mDNSResponder[95]:  12: DNSServiceCreateConnection STOP PID[23274](socat)
2015-10-26 5:32:31.847 PM mDNSResponder[95]:  12: Removing FD
2015-10-26 5:32:32.349 PM curl[23269]: dnssd_clientstub read_all(5) failed 0/4 0 
2015-10-26 5:32:32.350 PM mDNSResponder[95]:  12: connect_callback: Adding FD for uid 0
2015-10-26 5:32:32.351 PM mDNSResponder[95]:  12: DNSServiceCreateConnection START PID[23275](socat)
2015-10-26 5:32:33.361 PM mDNSResponder[95]:  12: DNSServiceCreateConnection STOP PID[23275](socat)
2015-10-26 5:32:33.361 PM mDNSResponder[95]:  12: Removing FD
Run Code Online (Sandbox Code Playgroud)

在我这看起来像是curl通过dnssd_clientstub尝试三次来解决这个名字.这是在socat被监禁的进程尝试连接时的日志:

host ~/C/jail (master*) ?
sudo socat -v -d -d UNIX-LISTEN:/Users/hornairs/Code/jail/jail-test/private/var/run/mDNSResponder,mode=666,fork,user=root,group=daemon UNIX-CLIENT:/private/var/run/mDNSResponder
Password:
2015/10/26 18:16:03 socat[24334] N listening on LEN=67 AF=1 "/Users/hornairs/Code/jail/jail-test/private/var/run/mDNSResponder"
2015/10/26 18:16:07 socat[24334] N accepting connection from LEN=16 AF=1 "" on LEN=67 AF=1 "/Users/hornairs/Code/jail/jail-test/private/var/run/mDNSResponder"
2015/10/26 18:16:07 socat[24334] N forked off child process 24341
2015/10/26 18:16:07 socat[24334] N listening on LEN=67 AF=1 "/Users/hornairs/Code/jail/jail-test/private/var/run/mDNSResponder"
2015/10/26 18:16:07 socat[24341] N opening connection to LEN=32 AF=1 "/private/var/run/mDNSResponder"
2015/10/26 18:16:07 socat[24341] N successfully connected from local address LEN=16 AF=1 ""
2015/10/26 18:16:07 socat[24341] N starting data transfer loop with FDs [6,6] and [5,5]
> 2015/10/26 18:16:07.081847  length=28 from=0 to=27
............................< 2015/10/26 18:16:07.082019  length=4 from=0 to=3
....> 2015/10/26 18:16:07.082167  length=50 from=28 to=77
...............\b...............P.....google.ca....> 2015/10/26 18:16:07.082287  length=1 from=78 to=78
.2015/10/26 18:16:07 socat[24341] N socket 2 (fd 5) is at EOF
2015/10/26 18:16:07 socat[24341] N exiting with status 0
2015/10/26 18:16:07 socat[24334] N childdied(): handling signal 20
Run Code Online (Sandbox Code Playgroud)

为了比较,以下是从主机运行时成功查找的内容:

2015-10-26 5:31:56.524 PM mDNSResponder[95]:  12: connect_callback: Adding FD for uid 501
2015-10-26 5:31:56.524 PM mDNSResponder[95]:  12: DNSServiceCreateConnection START PID[23190](curl)
2015-10-26 5:31:56.524 PM mDNSResponder[95]:  12: Result code socket 27 created 00000000 00000001
2015-10-26 5:31:56.524 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(15000, 0, google.ca., Addr) START PID[23190]()
2015-10-26 5:31:56.525 PM mDNSResponder[95]:  12: Result code socket 27 closed  00000000 00000001 (0)
2015-10-26 5:31:56.525 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(google.ca., Addr) ADD    4 google.ca. Addr 74.216.233.251
2015-10-26 5:31:56.525 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(google.ca., Addr) ADD    4 google.ca. Addr 74.216.233.249
2015-10-26 5:31:56.525 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(google.ca., Addr) ADD    4 google.ca. Addr 74.216.233.227
*snip*
2015-10-26 5:31:56.525 PM mDNSResponder[95]:  12: Result code socket 27 created 00000000 00000002
2015-10-26 5:31:56.525 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(15000, 0, google.ca., AAAA) START PID[23190]()
2015-10-26 5:31:56.526 PM mDNSResponder[95]:  12: Result code socket 27 closed  00000000 00000002 (0)
2015-10-26 5:31:56.526 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(google.ca., AAAA) ADD   16 google.ca. AAAA 2607:F8B0:400B:080A:0000:0000:0000:100F
2015-10-26 5:31:56.526 PM mDNSResponder[95]:  12: Cancel 00000000 00000001
2015-10-26 5:31:56.526 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(google.ca., Addr) STOP PID[23190]()
2015-10-26 5:31:56.526 PM mDNSResponder[95]:  12: Cancel 00000000 00000002
2015-10-26 5:31:56.526 PM mDNSResponder[95]:  12: DNSServiceQueryRecord(google.ca., AAAA) STOP PID[23190]()
2015-10-26 5:31:56.587 PM mDNSResponder[95]:  12: DNSServiceCreateConnection STOP PID[23190](curl)
2015-10-26 5:31:56.587 PM mDNSResponder[95]:  12: Removing FD
Run Code Online (Sandbox Code Playgroud)

我注意到失败和成功之间的主要区别在于uidjail中的请求为0,而外部请求为501.好奇,但似乎并不是请求实际失败的地方.

来自的错误消息mDNSResponder似乎与通过errsd套接字获取传入请求有关.https://github.com/jevinskie/mDNSResponder/blob/2942dde61f920fbbf96ff9a3840567ebbe7cb1b6/mDNSShared/uds_daemon.c#L3660

在这一点上,我似乎mDNSResponder希望它的客户端在套接字上传递一对fd以响应客户端,我不确定甚至可以从chroot内部做.我是一个非常差的C程序员,所以我可能错了,但如果这是事实,是否有可能这样做,并且是否有更好的途径让DNS在chroot内工作?

其他花絮:

  • 您可以配置mDNSResponder为在其启动的plist文件中侦听多个套接字,但该文件现在受系统完整性保护的保护,我不想禁用它以使其工作.这是janky,并且容易陷入不同步的监狱文件系统我经常改变的主机,它打破DNS每一个过程,如果因为该文件不存在,不能创建的插口内.运行代理似乎更具弹性

  • ping在监狱里立即死亡,这就是我使用的原因curl.它Killed: 9立即在控制台上收到消息.

  • 我使用绑定挂载将一些其他文件放入chroot,但我无法让它适用于mDNSResponder套接字.我使用http://bindfs.org(因为OS X不支持Linux mount --bind)将/ var/run挂载到chroot,但是在尝试连接时会出现在日志中:

    2015-10-26 6:39:40.833 PM curl[25002]: dnssd_clientstub ConnectToServer: connect()-> No of tries: 1
    2015-10-26 6:39:41.837 PM curl[25002]: dnssd_clientstub ConnectToServer: connect()-> No of tries: 2
    2015-10-26 6:39:42.843 PM curl[25002]: dnssd_clientstub ConnectToServer: connect()-> No of tries: 3
    2015-10-26 6:39:43.848 PM curl[25002]: dnssd_clientstub ConnectToServer: connect() failed path:/var/run/mDNSResponder Socket:4 Err:-1 Errno:61 Connection refused
    
    Run Code Online (Sandbox Code Playgroud)

sah*_*sah 2

这里的问题是套接字上的请求和响应使用和系统调用/var/run/mDNSResponder的“辅助数据”功能,而 socat 不代理辅助数据。我能够获得一个自定义代理,它可以中继辅助数据以进行工作,并为 chroot 内的进程提供 DNS。recvmsgsendmsg