web-dev-qa-db-ja.com

/ etc / hostsを補完するユーザー固有のhostsファイルを作成できますか?

特定のユーザーにのみ固有のホストのリストを追加することはできますか?おそらく、ユーザー固有の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を呼び出す前にrootになっていない限り、pingを使用します。
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にすることもできます(ここでは、2つのスラッシュを使用して、/dev/fd//3の長さが/etc/hostsの長さと同じになるようにします)。

exec 3< ~/hosts

たとえば、異なるコマンドが異なるhostsファイルを使用できるようにします。

nscdがインストールされて実行されている場合は、同じトリックを実行してバイパスできますが、今回はlibc.so.6を使用して、nscdソケットへのパス(/var/run/nscd/socketなど)を存在しないパス。

44

unshareコマンドで作成されたプライベートマウントスペースを使用して、シェルプロセスおよびそのシェルから開始された後続の子プロセスにプライベートの/ 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

1つの解決策は、各ユーザーを別々のchrootに入れて、各ユーザーが別々の/etc/hosts自分自身に。

6
Pletiplot

以下を~/.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*.*$;\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]}" "$@"
}

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
4
Kyle Fernandes

これがあなたに役立つかどうかはわかりませんが、ユーザーだけが簡単にアクセスできる場所に保存された「ホスト」を追加する方法を探してここに来ました。

私は基本的に、エントリポイントが1つしかない作業ネットワークの特定のボックスにSSH接続できる必要がありました。

私がしたことは、.bashrcファイルにエイリアスを追加することでした。

たとえば、追加した場合:

alias jrfbox='ssh [email protected]' 

~/.bashrcの下部(~はホームディレクトリです)。次に、ログアウトして再度ログインした後、jrfboxと入力して、 Enter、それが接続されます。

2
Jason