2015-10-26 208 views
11

我正试图创建一个chroot来运行需要互联网访问的程序来构建自己的沙盒,不可变的开发人员环境。到目前为止,我的监狱运作良好:我可以在其中运行bash并从那里运行简单的程序! DNS解析不工作,但是:如何获得DNS解析以在El Capitan的Mac OS X chroot中工作?

bash-3.2$ curl google.ca 
curl: (6) Could not resolve host: google.ca 

我几乎可以肯定,这是因为内部过程是无法连接到监狱外运行mDNSResponder守护进程。监狱外面有一个mDNSResponder插座为整个系统的使用方法:

host ➜ ls -lA /var/run/mDNSResponder 
srw-rw-rw- 1 root daemon 0 22 Oct 10:41 /var/run/mDNSResponder 

不过,监狱里没有。所以,我试图使用socat来创建一个从监狱到外面的unix套接字“代理”:我运行socat(下面的命令)在我的监狱内创建一个套接字,然后在监狱里再次卷曲,但仍然卷曲给出相同的错误信息。我看到这个系统日志与SIGUSR1打开的mDNSResponder详细日志记录后:

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 

它通过dnssd_clientstub我看来像curl试图三次来解析名称。这里的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 

为了便于比较,这里就是一个成功的查找看起来当我从主机上运行它像:

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 

主要的区别我注意到在失败和成功之间,uid对于jail中的请求为0,对于其外部的请求为0123。好奇,但这似乎并不是请求实际上失败的地方。

来自mDNSResponder的错误消息似乎涉及通过套接字从传入请求获取errsdhttps://github.com/jevinskie/mDNSResponder/blob/2942dde61f920fbbf96ff9a3840567ebbe7cb1b6/mDNSShared/uds_daemon.c#L3660

在这一点上,在我看来,mDNSResponder希望它的客户端在套接字中传递一对fd来响应客户端,我不知道甚至可以从chroot内部做到这一点。我是一个非常差的C程序员,所以我可能会错误的,但如果这是事实,是否有可能做到这一点,是否有更好的方式让DNS在chroot中工作?

其他花絮:

  • 您可以配置mDNSResponder听不止一个插座在它的launchd plist文件,但该文件现在由系统完整性保护,我不希望禁用保护让这个工作。它很笨拙,容易与我经常在主机上进行更改的监狱文件系统不同步,因为它不能创建其中一个套接字,因为该文件不存在,所以它会为每个进程打破DNS。运行代理似乎更有弹性

  • ping立即死在监狱,这就是为什么我使用curl。它立即在控制台上获取Killed: 9消息。

  • 我正在使用绑定挂载将一些其他文件放入chroot中,但是我无法获得适用于mDNSResponder套接字的工作。我用http://bindfs.org(因为OS X不支持Linux的mount --bind)安装在/ var /运行在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 
    
+0

另外值得注意的是:我不能在chroot里面运行一个重复的mDNSResponder。它会在前台立即被杀死:''bash-3.2#/ usr/sbin/mDNSResponder \ n杀死:9'并且在syslog中:'kernel [0]:AMFI:hook..execve()kill pid 26798:不允许在chroot'中 – hornairs

回答

0

你应该确保你的chroot中有一个/etc/resolv.conf的副本。没有它,它不知道要联系哪个DNS服务器,所以唯一的回退选择是使用mDNS。但即使mDNS可行,它也可能只能用它解析本地域名,而不是google.ca

相关问题