/ etc / hosts를 보완하기 위해 사용자 별 호스트 파일을 만들 수 있습니까?


192

특정 사용자에게만 해당되는 호스트 목록을 추가 할 수 있습니까? 아마도 사용자 별 호스트 파일일까요?

이 메커니즘은 /etc/hosts파일 의 항목도 보완해야 합니다.


2
대신 고유 이름 서버를 실행하고 사용자 별 resolv.conf마다 다른 이름 서버를 사용하도록 할 수도 있습니다. 단, 사용자 별 resolv.conf를 만드는 것은 사용자 별 / etc / hosts를 만드는 것만 큼 어렵습니다.
SF.

2
서버가 원격 인 경우 ~ / .ssh / config 파일 ( this post)을 시도 할 수 있습니다 .
aaiezza

답변:


133

찾고있는 기능은 glibc에서 구현됩니다. HOSTALIASES환경 변수 를 설정하여 사용자 정의 호스트 파일을 정의 할 수 있습니다 . 이 파일의 이름은 gethostbyname( 문서 참조 )에 의해 선택됩니다 .

예 (우분투 13.10에서 테스트) :

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

몇 가지 제한 사항 :

  • HOSTALIASES만 사용하는 응용 프로그램 작동 getaddrinfo(3)이나gethostbyname(3)
  • setuid 를 사용 하면 libc가 환경을 삭제하므로 HOSTALIASES설정이 손실됩니다. ping 은 setuid root (ICMP 패킷을 수신해야하기 때문에)이므로 HOSTALIASESping을 호출하기 전에 이미 루트 상태가 아니면 ping을 사용할 수 없습니다.

12
점을 사용하지 않고 nscd호스트 이름을 사용하는 경우에는 작동하지 않습니다 .
Stéphane Chazelas

3
이것은 CentOS 6에서 작동하지 않는 것 같습니다
kbolino

3
파티에 늦었지만, 이것이 원하는 것과 반대입니다. OP는 호스트 해결 항목을 / etc / hosts에 추가하는 것과 비슷한 솔루션을 찾고 있지만 에스컬레이션 된 권한없이 사용자 영역에서 수행 할 수있는 솔루션을 찾고 있다고 생각합니다. (예 127.0.0.1 somedomain.com)
누리 스

그때는 기억 나지 않지만 요즘 핑은 리눅스에서 suid 바이너리가 아니다. 기능을 사용합니다. 당신이 실행 getcap /usr/sbin/ping하면 다음과 같은 것을 볼 수 있습니다 : /usr/bin/ping = cap_net_admin,cap_net_raw+p. 그리고 기술적으로 그것은 ICMP 대신 원시 소켓을 열어야한다는 것입니다 (그러나 나는 그것이 의미론이라고 주장 할 수 있다고 생각합니다).
Pryftan

"HOSTALIASES가 가리키는 별명 파일은 먼저 이름을 검색합니다"라고 말했지만 우선 순위는 임의적이며이 wget 예제를 수십 번 실행하면 잘못됩니다.
Nakilon

42

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몇 가지 존재하지 않는 경로를).


12
대담 +1, 충격 값 -1
fche

7
이진 패치의 경우 +1, 보안 관련의 경우 -1
Parthian Shot

@ParthianShot, 보안에 어떤 영향을 미칩니 까?
Stéphane Chazelas

1
@ StéphaneChazelas LD_LIBRARY_PATH사용자가 소유 한 디렉토리를 가리 키도록 변경 하면 사용자가 실행하는 다른 프로세스가 해당 디렉토리를 사용하여 라이브러리를 교체하여 생성 된 새 프로세스를 선택할 수 있습니다. 그리고 libnss_files.so패키지 관리자 를 통한 업데이트 (보안 업데이트 포함)는 패치 된 버전에 반영되지 않습니다. 수정 LD_LIBRARY_PATH은 일반적으로 다른 이유로 권장하지 않는 것이 좋지만 이러한 문제로 인해 현명하지 않습니다.
Parthian Shot

13
@ParthianShot, 업데이트 누락에 대한 요점은 공정한 것입니다. 그러나 다른 점으로, 불량 소프트웨어가 귀하의 이름으로 실행되는 경우 $ LD_LIBRARY_PATH의 영역에 대한 쓰기 액세스 권한이 이미 귀하의 것과 같이 훨씬 더 악화되고 안정적인 영역에 대한 쓰기 권한을 가지고 있기 때문에 걱정할 필요가 없습니다. .bash *, crontab, .forward 및 사용하는 모든 소프트웨어에 의한 모든 구성 파일 (예 : LD_ {PRELOAD, LIBRARY_PATH}를 설정할 수 있지만 일반적으로 훨씬 더 나쁠 것임)
Stéphane Chazelas

24

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
기다림. 마운트 된 파일 시스템을 디렉토리 (마운트 포인트)에 마운트했다고 생각했습니다. 파일을 다른 파일에 마운트 할 수 있다는 것을 몰랐습니다. 정말 작동합니까? (나는 진지하게 요구하고있다. 그것은 냉소가 아니다.)
살인자

5
그래도 작동합니다. --bind를 사용하여 다른 파일 위에 파일을 마운트 할 수 있습니다.
frielp

호기심 많은 사람들에 대한 메모와 마찬가지로 이것은 네임 스페이스와 관련이 있습니다. syscalls가 unshare(2)있으며 clone(2)그것은 마술의 일부입니다. 참조 namespaces(7)user_namespaces(7).
Pryftan

5

한 가지 해결 방법은 각 사용자를 chroot별도의 상태 /etc/hosts로 두는 것 입니다.


3
이것은 답변이 될 수 있지만, 약간의 설명으로 언급 된 바와 같이 코멘트로 더 적합합니다
Anthon

2
글쎄 ... 네, 가능합니다. chrooting은 이런 종류의 솔루션에 매우 강력한 솔루션입니다. 그리고 자체 문제 세트를 제공합니다.
Parthian Shot

5

나는 같은 요구에 직면하여 libnss-userhosts를 시도했지만 멀티 스레드 응용 프로그램에서는 실패합니다. 따라서 libnss-homehosts 작성 했습니다 . 매우 새롭고 나만 테스트했습니다. 기회가 생길 수도 있습니다! /etc/host.conf의 일부 옵션, 여러 개의 별칭 이름 및 역방향 확인 (주소 이름)을 지원합니다.


1
이것은 libnss 유지 관리자 및 / 또는 배포 관리자에게 던지는 것이 좋습니다. 그러나 그 전에는 루트가없는 사용자는이를 사용할 수 없습니다. 여전히, +1
einpoklum

3

다음을 배치하면 ~/.bashrcbash에서 나를 위해 일하고 있습니다. 명령의 호스트 이름을의 항목을 기반으로하는 주소로 변환합니다 ~/.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이이 "해결"을 사용할 수 있습니까? 아니면 기능 "해결"을 사용하는 기능 만?
Qinsi

2

이것이 당신에게 도움이 될지 확실하지 않지만, 여기에는 내 사용자 만 쉽게 액세스 할 수있는 저장된 "호스트"를 추가하는 방법을 찾고있었습니다.

기본적으로 업무용 네트워크의 특정 상자에 ssh를 넣을 수 있어야했는데 여기에는 하나의 진입 점이 있습니다.

내가 한 것은 내 .bashrc파일 에 별칭을 추가하는 것이 었습니다 .

예를 들어 다음을 추가 한 경우 :

alias jrfbox='ssh jason@192.168.6.6' 

맨 아래에 ~/.bashrc( ~홈 디렉토리입니다). 그런 다음 로그 아웃하고 다시 로그인 한 후을 입력 jrfbox하고을 누르면 Enter연결됩니다.


14
SSH 사례에서 특히 흥미로운 경우을 참조하십시오 man ssh_config.
Nick

1
로그 아웃하지 않고 다시에 다시로드 ~/.bashrc, 간단하게 할 source ~/.bashrc.
user991710

1
@ user991710 또는 그 문제에 대해. ~/.bashrc
Pryftan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.