Tôi có thể tạo tệp máy chủ dành riêng cho người dùng để bổ sung / etc / hosts không?


192

Có thể thêm một danh sách các máy chủ chỉ dành riêng cho một người dùng nhất định không? Có lẽ một tập tin lưu trữ cụ thể người dùng?

Cơ chế này cũng sẽ bổ sung cho các mục trong /etc/hoststệp.


2
tốt, thay vào đó, bạn có thể chạy máy chủ tên riêng và người dùng sử dụng các máy chủ tên khác nhau cho mỗi độ phân giải cụ thể của người dùng - ngoại trừ việc tạo độ phân giải dành riêng cho người dùng dường như khó khăn như tạo / etc / máy chủ cụ thể của người dùng.
SF.

2
Nếu máy chủ ở xa, bạn có thể thử tệp ~ / .ssh / config: bài đăng này .
aaiezza

Câu trả lời:


133

Các chức năng bạn đang tìm kiếm được thực hiện trong glibc. Bạn có thể xác định tệp máy chủ tùy chỉnh bằng cách đặt HOSTALIASESbiến môi trường. Tên trong tệp này sẽ được chọn bởi gethostbyname(xem tài liệu ).

Ví dụ (đã thử nghiệm trên Ubuntu 13.10):

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

Một số hạn chế:

  • HOSTALIASESchỉ hoạt động cho các ứng dụng sử dụng getaddrinfo(3)hoặcgethostbyname(3)
  • Khi setuid được sử dụng, libc vệ sinh môi trường, điều đó có nghĩa là HOSTALIASEScài đặt bị mất. ping là root setuid (vì nó cần nghe các gói ICMP), vì vậy HOSTALIASESsẽ không hoạt động với ping trừ khi bạn đã root trước khi bạn gọi ping.

12
Lưu ý rằng nó không hoạt động nếu bạn đang sử dụng nscdvà bị giới hạn ở tên máy chủ không có dấu chấm.
Stéphane Chazelas

3
Điều này dường như không hoạt động trên CentOS 6
kbolino

3
Đến bữa tiệc muộn, nhưng đây là điều ngược lại với những gì mong muốn, phải không? Tôi nghĩ OP đang tìm kiếm một giải pháp tương tự để thêm các mục giải quyết máy chủ vào / etc / hosts, nhưng một mục có thể được thực hiện trong vùng người dùng mà không có đặc quyền leo thang. (tức là 127.0.0.1 somedomain.com)
Nuri Hodges

Tôi không nhớ nhưng ngày nay ping không phải là một hệ nhị phân tuyệt vời trong Linux; nó sử dụng các khả năng. Nếu bạn chạy, getcap /usr/sbin/pingbạn có thể thấy một cái gì đó như : /usr/bin/ping = cap_net_admin,cap_net_raw+p. Và về mặt kỹ thuật, nó cần phải mở một ổ cắm thô chứ không phải ICMP (nhưng tôi cho rằng bạn có thể tranh luận rằng đó chỉ là ngữ nghĩa).
Pryftan

Mặc dù người đàn ông nói rằng "tệp bí danh được chỉ ra bởi HOSTALIASES trước tiên sẽ được tìm kiếm tên", ưu tiên là ngẫu nhiên và nếu chạy ví dụ wget này hàng chục lần thì nó bị lỗi.
Nakilon

42

Bên cạnh những LD_PRELOADmánh khóe. Một thay thế đơn giản có thể hoạt động trên một vài hệ thống sẽ là chỉnh sửa nhị phân một bản sao của thư viện hệ thống xử lý độ phân giải tên máy chủ để thay thế /etc/hostsbằng một đường dẫn của riêng bạn.

Chẳng hạn, trên Linux:

Nếu bạn không sử dụng nscd, hãy sao chép libnss_files.sovào một số vị trí của riêng bạn như:

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

(thư viện dùng chung có thể được đặt ở nơi khác, vd /lib/libnss_files.so.2)

Bây giờ, nhị phân chỉnh sửa bản sao để thay thế /etc/hoststrong đó thành một cái gì đó có cùng độ dài /tmp/hosts.

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

Chỉnh sửa /tmp/hostsđể thêm mục bạn muốn. Và sử dụng

export LD_LIBRARY_PATH=~/lib

cho nss_filesđể tìm trong /tmp/hoststhay vì /etc/hosts.

Thay vì /tmp/hosts, bạn cũng có thể làm cho nó /dev/fd//3(ở đây sử dụng hai dấu gạch chéo sao cho độ dài bằng /dev/fd//3với /etc/hosts) và làm

exec 3< ~/hosts

Ví dụ, cho phép các lệnh khác nhau sử dụng các hoststệp khác nhau .

Nếu nscdđược cài đặt và chạy, bạn có thể bỏ qua nó bằng cách thực hiện cùng một mẹo, nhưng lần này là libc.so.6và thay thế đường dẫn đến ổ cắm nscd (một cái gì đó giống như /var/run/nscd/socket) bằng một số đường dẫn không tồn tại.


12
+1 cho độ táo bạo, -1 cho giá trị sốc
fche

7
+1 cho vá nhị phân, -1 cho ý nghĩa bảo mật
Parthian Shot

@ParthianShot, ý nghĩa bảo mật nào?
Stéphane Chazelas

1
@ StéphaneChazelas Thay đổi LD_LIBRARY_PATHđể trỏ đến một thư mục do người dùng sở hữu có nghĩa là bất kỳ quá trình nào khác do người dùng điều hành có thể sử dụng thư mục đó để đồng chọn bất kỳ quy trình mới nào được sinh ra bằng cách thay thế các thư viện. Và các cập nhật libnss_files.sothông qua trình quản lý gói (bao gồm các cập nhật bảo mật) sẽ không được phản ánh trong phiên bản vá. Sửa đổi LD_LIBRARY_PATHnói chung là một điều xấu để khuyến nghị vì những lý do khác, nhưng nó cũng không khôn ngoan vì những vấn đề đó.
Bắn Parthian

13
@ParthianShot, quan điểm của bạn về các bản cập nhật bị thiếu là một điểm công bằng. Tuy nhiên, đối với điểm khác của bạn, nếu một phần mềm giả mạo đang chạy trong tên của bạn, thì nó có quyền truy cập ghi vào một khu vực trong $ LD_LIBRARY_PATH sẽ là điều ít lo lắng nhất của bạn vì nó đã có quyền truy cập ghi vào các khu vực tồi tệ hơn và đáng tin cậy hơn như của bạn .bash *, crontab, .forward và tất cả các tệp cấu hình của tất cả các phần mềm bạn sử dụng (ví dụ, nơi nó có thể đặt LD_ {PRELOAD, LIBRARY_PATH} nhưng thường sẽ tệ hơn rất nhiều)
Stéphane Chazelas

24

Các không gian gắn kết riêng được tạo bằng unsharelệnh có thể được sử dụng để cung cấp tệp riêng / etc / hosts cho một quy trình shell và mọi quá trình con tiếp theo bắt đầu từ shell đó.

# 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
Chờ đợi. Tôi nghĩ mount chỉ gắn hệ thống tập tin vào thư mục (điểm gắn kết). Tôi không biết rằng một tập tin có thể được gắn vào một tập tin khác. Điều đó thực sự làm việc? (Tôi đang hỏi điều đó một cách nghiêm túc. Đó không phải là châm biếm.)
killermist

5
Đúng, nó hoạt động, bạn có thể gắn một tệp trên một tệp khác bằng --bind.
trợ giúp

Cũng như một lưu ý cho những người tò mò: điều này là để làm với không gian tên; có những tòa nhà chọc trời unshare(2)clone(2)đó là một phần của phép thuật ở đây. Xem thêm namespaces(7)user_namespaces(7).
Pryftan

5

Một giải pháp là để mỗi người dùng riêng biệt chroot, vì vậy họ có thể có một người riêng biệt /etc/hosts.


3
Đây có thể là một câu trả lời, nhưng như đã nêu với rất ít lời giải thích, nó phù hợp hơn với tư cách là một bình luận
Anthon

2
Chà ... ừ, có thể làm được. Mặc dù chroot là một giải pháp khá nặng nề cho loại điều này. Và mang theo nó các vấn đề riêng của nó.
Bắn Parthian

5

Tôi đã phải đối mặt với cùng một nhu cầu, vì vậy tôi đã thử libnss-userhost, nhưng nó thất bại ở các ứng dụng đa luồng. Vì vậy, tôi đã viết libnss-homehosts . Nó rất mới và chỉ được thử nghiệm bởi tôi. Bạn có thể cho một cơ hội cho nó! Nó hỗ trợ một số tùy chọn trong /etc/host.conf, nhiều tên bí danh và phân giải ngược (địa chỉ thành tên).


1
Đây có vẻ là một ý tưởng tốt để phù hợp với những người duy trì libnss và / hoặc cho những người duy trì phân phối. Nhưng trước khi điều đó xảy ra, người dùng không có root sẽ không thể sử dụng nó. Tuy nhiên, +1
einpoklum

3

Đặt sau đây ~/.bashrclà làm việc cho tôi trong bash. Nó chuyển đổi tên máy chủ trong lệnh thành một địa chỉ dựa trên các mục trong ~/.hosts. Nếu ~/.hostskhông tồn tại hoặc nếu không thể tìm thấy tên máy chủ ~/.hosts, lệnh sẽ thực thi như bình thường. Điều này sẽ làm việc với các cờ ban đầu của các chức năng có liên quan và không biết nơi đặt tên máy chủ liên quan đến các cờ, ví dụ ping -i 0.5 host1 -c 3, hoạt động. Các ~/.hoststập tin cần ưu tiên hơn bất kỳ vị trí khác cho việc tìm kiếm tên máy chủ, vì vậy nếu có bất kỳ hostname dupicate, địa chỉ trong ~/.hostssẽ được sử dụng.

$ 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 "$@"
}

Một ví dụ ~/.hostsđược đưa ra dưới đây. Nó theo cùng định dạng như /etc/hosts. Nhận xét và khoảng trắng được xử lý chính xác.

$ 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 hoặc wget có thể sử dụng "giải quyết" này không? Hay chỉ là chức năng của bạn, người sử dụng chức năng "giải quyết"?
Qinsi

2

Không chắc điều này có giúp gì cho bạn không, nhưng tôi đến đây để tìm cách thêm "máy chủ" đã lưu ở đâu đó chỉ có thể truy cập dễ dàng cho người dùng của tôi.

Về cơ bản tôi cần có thể ssh vào một số hộp nhất định trên mạng công việc của chúng tôi, nơi chỉ có một điểm vào.

Những gì tôi đã làm là thêm bí danh vào .bashrctập tin của tôi .

Ví dụ: nếu bạn đã thêm:

alias jrfbox='ssh jason@192.168.6.6' 

ở dưới cùng của bạn ~/.bashrc( ~là thư mục nhà của bạn). Sau đó, sau khi bạn đăng xuất và đăng nhập lại, bạn có thể nhập jrfbox, nhấn Entervà nó sẽ kết nối.


14
Nếu bạn thú vị cụ thể trong trường hợp SSH, bạn sẽ thấy man ssh_config.
Nick

1
Bạn không cần phải đăng xuất và đăng nhập lại để tải lại ~/.bashrc, chỉ cần làm source ~/.bashrc.
dùng991710

1
@ user991710 Hoặc cho vấn đề đó. ~/.bashrc
Pryftan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.