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


193

特定のユーザーにのみ固有のホストのリストを追加することは可能ですか?おそらくユーザー固有のホストファイルですか?

このメカニズムは、/etc/hostsファイル内のエントリも補完する必要があります。


3
まあ、代わりに独自のネームサーバーを実行し、ユーザーにユーザー固有のresolv.confごとに異なるネームサーバーを使用させることができます-ユーザー固有のresolv.confの作成は、ユーザー固有の/ etc / hostsを作成するのとまったく同じように難しいようです。
SF。

2
:サーバーがリモートである場合は、〜/ .ssh / configファイル試してみてくださいこの記事を
aaiezza

回答:


134

探している機能はglibcに実装されています。HOSTALIASES環境変数を設定することにより、カスタムホストファイルを定義できます。このファイルの名前はgethostbynameドキュメントを参照)によって選択されます。

例(Ubuntu 13.10でテスト済み):

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

いくつかの制限:

  • HOSTALIASESgetaddrinfo(3)またはを使用するアプリケーションでのみ動作しますgethostbyname(3)
  • ときにsetuidが使用されているlibcのは、ことを意味し、環境をサニタイズHOSTALIASES設定が失われます。pingはsetuid root(ICMPパケットをリッスンする必要があるため)であるためHOSTALIASES、pingを呼び出す前に既にrootである場合を除き、pingで動作しません。

12
使用している場合は機能nscdせず、ドットのないホスト名に制限されることに注意してください。
ステファンシャゼル

3
これはCentOS 6では動作しないようです
kbolino

3
パーティーに遅れましたが、これは望まれるものの逆ですよね?OPは、ホスト解決エントリを/ etc / hostsに追加する同様のソリューションを探していると思いますが、権限を昇格させなくてもユーザーランドで実行できるものを探しています。(すなわち127.0.0.1 somedomain.com
ヌリホッジズ

そのときは覚えていませんが、最近のpingはLinuxのsuidバイナリではありません。機能を使用します。実行getcap /usr/sbin/pingすると、次のようなものが表示される場合があります/usr/bin/ping = cap_net_admin,cap_net_raw+p。そして技術的には、ICMPではなくrawソケットを開く必要があるということです(しかし、それは単なるセマンティクスであると主張できると思います)。
プリフタン

1
「HOSTALIASESが指すエイリアスファイルが最初に名前を検索する」と言っているにもかかわらず、優先順位はランダムであり、このwgetの例を実行すると、何十回も問題が発生します。
ナキロン

43

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)を存在しないパスに置き換えます。


12
大胆さ+1、衝撃値-1
fche

7
バイナリパッチの場合は+1、セキュリティへの影響の場合は-1
Parthian Shot

@ParthianShot、セキュリティにどのような影響がありますか?
ステファンシャゼル

1
@StéphaneChazelas LD_LIBRARY_PATHユーザーが所有するディレクトリを指すように変更することは、ユーザーが実行する他のプロセスがそのディレクトリを使用して、ライブラリを置き換えることによって生成される新しいプロセスを共同で使用できることを意味します。またlibnss_files.so、パッケージマネージャーを介した更新(セキュリティ更新を含む)は、パッチが適用されたバージョンには反映されません。LD_LIBRARY_PATH一般に、変更は他の理由で推奨するのは悪いことですが、これらの問題があるため賢明でもありません。
パルティアショット

13
@ParthianShot、アップデートの欠落についてのあなたの主張は公正な点です。ただし、他の点では、不正なソフトウェアがあなたの名前で実行されている場合、$ LD_LIBRARY_PATHの領域への書き込みアクセスを持つことは、あなたのようなはるかに悪化し、より信頼性の高い領域への書き込みアクセスをすでに取得しているので、心配することはほとんどありません.bash *、(それは例えばLD_ {PRELOAD、LIBRARY_PATH}を設定することができますが、一般的に多くの悪いことだろう)、あなたが使用するすべてのソフトウェアでのcrontab、.forwardファイル、およびすべての設定ファイル
ステファン・Chazelas

25

この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

3
待つ。マウントされたファイルシステムをディレクトリ(マウントポイント)にマウントするだけだと思いました。ファイルを別のファイルにマウントできることを知りませんでした。それは本当に機能しますか?(私は真剣にそれを求めています。それは皮肉ではありません。)
キラーミスト

6
はい、動作します。--bindを使用すると、ファイルを別のファイルにマウントできます。
フリエルプ

1
好奇心those盛な人へのメモとして:これは名前空間に関するものです。syscallがunshare(2)あり、clone(2)それがここの魔法の一部です。namespaces(7)およびも参照してくださいuser_namespaces(7)
プリフタン

6

1つの解決策は、各ユーザーを個別chrootに配置すること/etc/hostsです。そのため、ユーザーは自分自身を個別に使用できます。


3
これは答えかもしれませんが、説明の少ないところで述べたように、コメントとしてより適しています
アントン

2
まあ...ええ、それは実行可能です。chrootingは、この種のことに対する非常に強力なソリューションですが、そして、それ自体に一連の問題をもたらします。
パルティアショット

6

同じニーズに直面したので、libnss-userhostsを試しましたが、マルチスレッドアプリケーションでは失敗します。したがって、私はlibnss-homehostsを書きました。とても新しく、私だけがテストしました。あなたはそれにチャンスを与えるかもしれません!/etc/host.confのいくつかのオプション、複数のエイリアス名、および逆解決(アドレスから名前)をサポートしています。


1
これは、libnssメンテナーおよび/またはディストリビューションメンテナーに提案することをお勧めします。しかし、それが起こる前に、root自身のないユーザーはそれを使用できません。それでも、+ 1
アインポクルム

4

以下を置くことは~/.bashrc私にとってbashで働いています。コマンドのホスト名をのエントリに基づいてアドレスに変換します~/.hosts。場合は、~/.hosts存在しないか、またはホスト名がで見つからない場合~/.hosts、コマンドは通常通り実行されます。これは、関連する関数の元のフラグで動作し、フラグに関連してホスト名が配置される場所に関係なく、たとえばping -i 0.5 host1 -c 3動作します。~/.hostsファイルは、ホスト名を見つけるための他の任意の場所の上に好みを取るので、任意dupicateホスト名がある場合、のアドレスが~/.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

gitまたはwgetはこの「解決」を使用できますか?または、関数「resolve」を使用する関数だけですか?
キンシー

2

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

基本的に、作業ネットワーク上の特定のボックスにsshできるようにする必要がありました。これには1つのエントリポイントしかありません。

.bashrcファイルにエイリアスを追加しました。

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

alias jrfbox='ssh jason@192.168.6.6' 

~/.bashrc~あなたのホームディレクトリです)の下部。あなたがログアウトして再度ログインした後に続いて、次のように入力することができjrfbox、ヒットEnter、そしてそれが接続します。


14
SSHの場合に特に興味がある場合は、が表示されman ssh_configます。
ニック

1
リロードするためにログアウトして再度ログインする必要はあり~/.bashrcませんsource ~/.bashrc
user991710

1
@ user991710またはそのことについて. ~/.bashrc
プリフタン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.