此机制还应补充
/etc/hosts
文件中的条目。#1 楼
您要寻找的功能已在glibc中实现。您可以通过设置HOSTALIASES
环境变量来定义定制主机文件。该文件中的名称将由gethostbyname
拾取(请参阅文档)。示例(在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 root或在执行时被赋予net_raw
功能(因为它需要侦听ICMP数据包),因此HOSTALIASES
无法与ping
一起使用,除非您在调用ping
之前已经是root用户。评论
请注意,如果您使用的是nscd,它将无法正常运行,并且仅限于主机名中不带点的情况。
–StéphaneChazelas
2014年5月29日12:45
这似乎在CentOS 6上不起作用
– kbolino
2015年12月1日在18:51
派对晚了,但这与期望相反,不是吗?我认为OP正在寻找一种类似的解决方案,以将主机解析项添加到/ etc / hosts中,但是这种解决方案可以在用户级完成而无需提升特权。 (即127.0.0.1 somedomain.com)
– Nuri Hodges
16-11-10在18:53
尽管有人说“将首先搜索HOSTALIASES指向的别名文件”,但是优先级是随机的,如果运行此wget示例多次,它将出错。
– Nakilon
19年1月14日在10:27
在MacOS上不起作用:(
– Peter Dotchev
19年7月15日在13:18
#2 楼
除了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
相同的长度。perl -pi -e 's:/etc/hosts:/tmp/hosts:g' ~/lib/libnss_files.so.2
编辑
/tmp/hosts
以添加所需的条目。并使用export LD_LIBRARY_PATH=~/lib
让
/tmp/hosts
查找nss_files
而不是/tmp/hosts
。也可以代替
/etc/hosts
,也可以将其命名为/tmp/hosts
(在这里使用两个斜杠,使/dev/fd//3
的长度与/dev/fd//3
的长度相同),并执行exec 3< ~/hosts
例如,这将允许不同的命令使用不同的
/etc/hosts
文件。 br /> 如果
hosts
已安装并正在运行,则可以通过执行相同的技巧来绕过它,但是这次是nscd
,并用一些不存在的路径替换nscd套接字的路径(类似libc.so.6
)。 >评论
+1表示大胆,-1表示电击值
– fche
2013年9月27日在12:37
+1表示二进制补丁,-1表示安全性
–Parthian Shot
15年6月26日在20:28
@ParthianShot,对安全有何影响?
–StéphaneChazelas
15年6月27日在11:05
@StéphaneChazelas将LD_LIBRARY_PATH更改为指向用户拥有的目录意味着用户运行的任何其他进程都可以使用该目录来选择通过替换库产生的任何新进程。通过软件包管理器对libnss_files.so的更新(包括安全更新)将不会反映在修补版本中。出于其他原因,修改LD_LIBRARY_PATH通常是不好的建议,但由于这些问题,这也是不明智的。
–Parthian Shot
2015年6月28日在3:26
@ParthianShot,关于缺少更新的观点很合理。但是,对于您的另一点,如果恶意软件以您的名义运行,则对$ LD_LIBRARY_PATH中某个区域的写访问权限将是您的后顾之忧,因为它已经具有对更糟糕和更可靠的区域(如您的计算机)的写访问权限.bash *,crontab,.forward以及您使用的所有软件的所有配置文件(例如,它可以设置LD_ {PRELOAD,LIBRARY_PATH},但通常情况会更糟)
–StéphaneChazelas
15年6月28日在7:09
#3 楼
使用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
评论
等待。我以为mount只是将文件系统装载到目录(装载点)上。我不知道一个文件可以挂载到另一个文件上。这真的有用吗? (我很认真地问。这不是在讽刺。)
– Killermist
16年1月1日在22:49
是的,它可以工作,您可以使用--bind将文件挂载到另一个文件上。
–带状装饰
16年1月4日在8:12
就像对那些好奇的人的说明:这与名称空间有关;这里有系统调用unshare(2)和clone(2),这是魔术的一部分。另请参见namespaces(7)和user_namespaces(7)。
–Pryftan
18 Mar 11 '18 at 0:02
这真是太酷了!
–显微镜
20-2-19在21:31
尽管它确实很有帮助,但近几年来的众多攻击表明,用户名称空间也是一个巨大的安全风险。上面没有使用过(即您需要sudo权限),但应予以提及。 Debian默认禁用了它们。还应该考虑的另一件事是,要使用取消共享,您必须执行/分叉另一个进程。因此,将其植入到用于自动化的shell脚本中并不是完全简单的。一种方法是将整个代码作为unshare参数传递给sh -c,如此处所述:piware.de/2012/12/…
–stefanct
20-4-25在16:02
#4 楼
一种解决方案是让每个用户都有一个单独的chroot
,这样他们每个人都可以自己拥有一个单独的/etc/hosts
。评论
这可能是一个答案,但是如不加解释地指出,它更适合作为注释。
–安东
2013年12月10日上午10:49
好吧...是的,这是可行的。尽管chrooting是解决此类问题的非常繁重的解决方案。并带来了自己的问题。
–Parthian Shot
15年6月26日在20:31
#5 楼
我也面临同样的需求,因此我尝试了libnss-userhosts,但是在多线程应用程序上失败了。因此,我写了libnss-homehosts。这是很新的东西,只有我自己测试过。您可能会为此提供一个机会。它支持/etc/host.conf中的某些选项,多个别名和反向解析(地址到名称)。
评论
向libnss维护者和/或发行维护者推销似乎是一个好主意。但是在此之前,没有root用户的用户将无法使用它。还是+1
– einpoklum
17年8月14日在9:19
@bandie您的工具可以在我的Linux上完美运行。您知道MacOS的任何类似解决方案吗?
–尼古拉
20年8月7日在10:05
@Nicolai,不幸的是没有。 MacOS没有libnss吗?如果是这样,可以将libnss-homehost移植到。
– Bandie
20年8月9日在14:42
#6 楼
在~/.bashrc
中放置以下内容对bash来说很有效。它将根据~/.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*.*$;;p;q}" "$hostfile")
if [[ -n "$ip" ]]; then
command "${FUNCNAME[1]}" "${@:1:$(($arg-1))}" "$ip" "${@:$(($arg+1)):$#}"
return
fi
fi
done
fi
command "${FUNCNAME[1]}" "$@"
}
function ping {
resolve "$@"
}
function traceroute {
resolve "$@"
}
~/.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
评论
git或wget可以使用此“解析”吗?还是使用函数“解决”功能的您的函数?
–秦寺
19年7月2日在9:32
#7 楼
不知道这是否对您有帮助,但我来这里是为了寻找一种将保存的“主机”添加到仅我的用户可以轻松访问的位置的方法。我基本上需要能够将ssh转换为特定的我们工作网络上只有一个入口点的框。
我所做的就是在我的
.bashrc
文件中添加了别名。例如,如果您添加了:
alias jrfbox='ssh jason@192.168.6.6'
位于
~/.bashrc
的底部(~
是您的主目录)。然后注销并再次登录后,可以键入jrfbox
,按Enter键,它将连接。评论
如果您对SSH情况特别感兴趣,则应该看到man ssh_config。
–尼克
13年5月6日在18:08
您不必注销并重新登录即可重新加载〜/ .bashrc,只需执行源〜/ .bashrc。
–user991710
17 Mar 2 '17 at 8:51
@ user991710还是这个问题。 〜/ .bashrc
–Pryftan
18 Mar 10 '18 at 23:53
评论
好吧,您可以改为运行自己的名称服务器,并让用户针对每个特定于用户的resolv.conf使用不同的名称服务器-除了创建特定于用户的resolv.conf似乎与制作特定于用户的/ etc / hosts一样困难。 />如果服务器是远程服务器,则可以尝试〜/ .ssh / config文件:这篇文章。