我正试图创建一个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
的错误消息似乎涉及通过套接字从传入请求获取errsd
。 https://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
另外值得注意的是:我不能在chroot里面运行一个重复的mDNSResponder。它会在前台立即被杀死:''bash-3.2#/ usr/sbin/mDNSResponder \ n杀死:9'并且在syslog中:'kernel [0]:AMFI:hook..execve()kill pid 26798:不允许在chroot'中 – hornairs