it-swarm.cn

我可以创建用户特定的主机文件来补充/ etc / hosts吗?

是否可以添加仅特定于某个用户的主机列表?也许是特定于用户的主机文件?

此机制还应补充/etc/hosts文件中的条目。

205
redspike

您要寻找的功能已在glibc中实现。您可以通过设置HOSTALIASES环境变量来定义自定义主机文件。该文件中的名称将由gethostbyname拾取(请参阅 documentation )。

示例(在Ubuntu 13.10上测试):

_$ echo 'g www.google.com' >> ~/.hosts
$ export HOSTALIASES=~/.hosts
$ wget g -O /dev/null
_

一些限制:

  • HOSTALIASES仅适用于使用getaddrinfo(3)gethostbyname(3)的应用程序
  • 对于setuid/setgid/ setcap应用程序,libc清理环境,这意味着HOSTALIASES设置丢失。 ping是setuid根目录或在执行时被赋予_net_raw_功能(因为它需要侦听ICMP数据包),所以HOSTALIASES不适用于ping,除非在调用ping之前已经是root用户。
141
pwuertz

除了LD_PRELOAD技巧。一个可能在少数系统上工作的简单替代方法是,对处理主机名解析的系统库副本进行二进制编辑,以用自己的路径替换/etc/hosts

例如,在Linux上:

如果您不使用nscd,请将libnss_files.so复制到自己的某个位置,例如:

mkdir -p -- ~/lib &&
cp /lib/x86_64-linux-gnu/libnss_files.so.2 ~/lib

(共享库可能位于其他地方,例如/lib/libnss_files.so.2

现在,对副本进行二进制编辑,以将其中的/etc/hosts替换为与/tmp/hosts相同的长度。

Perl -pi -e 's:/etc/hosts:/tmp/hosts:g' ~/lib/libnss_files.so.2

编辑/tmp/hosts以添加所需的条目。并使用

export LD_LIBRARY_PATH=~/lib

nss_files查找/tmp/hosts而不是/etc/hosts

代替/tmp/hosts,也可以将其设置为/dev/fd//3(此处使用两个斜杠,以便/dev/fd//3的长度与/etc/hosts的长度相同),然后执行

exec 3< ~/hosts

例如,这将允许不同的命令使用不同的hosts文件。

如果nscd已安装并正在运行,则可以通过相同的技巧来绕过它,但是这次是libc.so.6,并用一些替换nscd套接字的路径(例如/var/run/nscd/socket)不存在的路径。

44
Stéphane Chazelas

使用unshare命令创建的专用装载空间可用于向Shell进程以及从该Shell启动的任何后续子进程提供专用/ etc/hosts文件。

# Start by creating your custom /etc/hosts file
[user] cd ~
[user] cat >my_hosts <<EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1 news.bbc.co.uk
EOF

[user] Sudo unshare --mount
# We're now running as root in a private mountspace. 
# Any filesystem mounts performed in this private mountspace
# are private to this Shell process and its children

# Use a bind mount to install our custom hosts file over /etc/hosts
[root] mount my_hosts /etc/hosts --bind

[root] cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1 news.bbc.co.uk

[root] exec su - appuser

[appuser] # Run your app here that needs a custom /etc/hosts file

[appuser] ping news.bbc.co.uk
PING news.bbc.co.uk (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.026 ms
^C
--- news.bbc.co.uk ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.026/0.044/0.062/0.018 ms
28
frielp

我遇到了同样的需求,所以我尝试了libnss-userhosts,但是在多线程应用程序上失败了。因此,我写了 libnss-homehosts 。这是很新的东西,只有我自己测试过。您可能会为此机会!它支持/etc/Host.conf中的某些选项,多个别名和反向解析(地址到名称)。

6
bandie

一种解决方案是让每个用户都拥有一个单独的chroot,因此他们每个人都可以拥有一个单独的/etc/hosts对自己。

6
Pletiplot

将以下内容放在~/.bashrc中对我来说是有效的。它将根据~/.hosts中的条目将命令中的主机名转换为地址。如果~/.hosts不存在或在~/.hosts中找不到主机名,则该命令将正常执行。这应该与相关功能的原始标志一起使用,而与主机名相对于标志的放置位置无关,例如ping -i 0.5 Host1 -c 3,有效。 ~/.hosts文件优先于其他位置来查找主机名,因此,如果有任何重复的主机名,将使用~/.hosts中的地址。

$ cat ~/.bashrc 
function resolve {
        hostfile=~/.hosts
        if [[ -f "$hostfile" ]]; then
                for arg in $(seq 1 $#); do
                        if [[ "${!arg:0:1}" != "-" ]]; then
                                ip=$(sed -n -e "/^\s*\(\#.*\|\)$/d" -e "/\<${!arg}\>/{s;^\s*\(\S*\)\s*.*$;\1;p;q}" "$hostfile")
                                if [[ -n "$ip" ]]; then
                                        command "${FUNCNAME[1]}" "${@:1:$(($arg-1))}" "$ip" "${@:$(($arg+1)):$#}"
                                        return
                                fi
                        fi
                done
        fi
        command "${FUNCNAME[1]}" "[email protected]"
}

function ping {
        resolve "[email protected]"
}

function traceroute {
        resolve "[email protected]"
}

~/.hosts的示例如下。它采用与/etc/hosts相同的格式。注释和空格已正确处理。

$ cat ~/.hosts 
# addresses and hostnames
stackexchange.com se

192.168.0.1 Host1 # this is Host1's address
login-node.inst.ac.uk login
4
Kyle Fernandes

不知道这是否对您有帮助,但是我来到这里是在寻找一种将保存的“主机”添加到只有我的用户才能轻松访问的地方的方法。

我基本上需要能够放入我们工作网络中的某些框,该框只有一个入口点。

我所做的就是在.bashrc文件。

例如,如果您添加了:

alias jrfbox='ssh [email protected]' 

在您的~/.bashrc~是您的主目录)。然后注销并再次登录后,您可以输入jrfbox,按 Enter,它将连接。

2
Jason