ฉันสามารถสร้างไฟล์โฮสต์เฉพาะของผู้ใช้เพื่อเติมเต็ม / etc / hosts ได้อย่างไร


192

เป็นไปได้หรือไม่ที่จะเพิ่มรายการโฮสต์ที่เฉพาะเจาะจงกับผู้ใช้บางคน? อาจเป็นไฟล์โฮสต์ที่เฉพาะเจาะจงของผู้ใช้?

กลไกนี้ควรเสริมรายการใน/etc/hostsไฟล์


2
ดีคุณอาจเรียกใช้เนมเซิร์ฟเวอร์ของตัวเองและให้ผู้ใช้ใช้เนมเซิร์ฟเวอร์ที่แตกต่างกันต่อ resolv.conf เฉพาะผู้ใช้ - ยกเว้นการสร้าง resolv.conf เฉพาะผู้ใช้ดูเหมือนจะยากพอ ๆ กับการสร้าง / etc / hosts ของผู้ใช้
เอสเอฟ

2
หากเซิร์ฟเวอร์อยู่ในระยะไกลคุณอาจลองใช้ไฟล์ ~ / .ssh / config: โพสต์นี้
aaiezza

คำตอบ:


133

ฟังก์ชั่นที่คุณกำลังมองหาถูกนำมาใช้ใน 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ใช้ libc ทำให้สภาพแวดล้อมดีขึ้นซึ่งหมายความว่าการHOSTALIASESตั้งค่าจะหายไป pingเป็น setuid root (เพราะจำเป็นต้องฟังแพ็คเก็ต ICMP) ดังนั้นHOSTALIASESจะไม่ทำงานกับ ping จนกว่าคุณจะรูทแล้วก่อนที่คุณจะเรียก ping

12
โปรดทราบว่ามันใช้งานไม่ได้หากคุณกำลังใช้nscdและ จำกัด ชื่อโฮสต์โดยไม่มีจุด
Stéphane Chazelas

3
ดูเหมือนจะไม่สามารถใช้งานได้กับ CentOS 6
kbolino

3
ไปงานปาร์ตี้สาย แต่นี่คือสิ่งที่ตรงกันข้ามกับสิ่งที่ต้องการไม่ใช่หรือ? ฉันคิดว่า OP กำลังมองหาโซลูชันที่คล้ายกันในการเพิ่มรายการแก้ไขโฮสต์ไปยัง / etc / hosts แต่รายการหนึ่งสามารถทำได้ใน userland โดยไม่ต้องเพิ่มสิทธิ์ (เช่น127.0.0.1 somedomain.com)
Nuri Hodges

ฉันจำไม่ได้แล้ว แต่วันนี้ ping ไม่ใช่ไบนารี suid ใน Linux; มันใช้ความสามารถ หากคุณทำงานคุณอาจจะเห็นสิ่งที่ชอบ:getcap /usr/sbin/ping /usr/bin/ping = cap_net_admin,cap_net_raw+pและในทางเทคนิคแล้วมันต้องเปิดซ็อกเก็ตดิบแทนที่จะเป็น ICMP (แต่ฉันคิดว่าคุณคงเถียงได้ว่ามันเป็นแค่ความหมาย)
Pryftan

แม้ว่าชายคนนั้นจะพูดว่า "ไฟล์นามแฝงที่ HOSTALIASES ชี้ไปก่อนจะค้นหาชื่อ" ลำดับความสำคัญนั้นเป็นแบบสุ่มและหากเรียกใช้ตัวอย่างนี้หลายสิบครั้งมันผิดพลาด
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 สำหรับค่าความตกใจ
เมื่อ

7
+1 สำหรับการแพตช์แบบไบนารี -1 สำหรับผลกระทบด้านความปลอดภัย
คู่ปรับ Shot

@ParthianShot ความปลอดภัยหมายถึงอะไร?
Stéphane Chazelas

1
@ StéphaneChazelasการเปลี่ยนLD_LIBRARY_PATHไปชี้ไปที่ไดเรกทอรีที่ผู้ใช้เป็นเจ้าของนั้นหมายถึงกระบวนการอื่นใดที่ผู้ใช้สามารถดำเนินการได้โดยใช้ไดเรกทอรีนั้นเพื่อร่วมเลือกกระบวนการใหม่ ๆ ที่เกิดจากการแทนที่ไลบรารี และการอัปเดตlibnss_files.soผ่านผู้จัดการแพ็คเกจ (รวมถึงการอัปเดตความปลอดภัย) จะไม่ปรากฏในเวอร์ชันที่ได้รับการแก้ไข การแก้ไขLD_LIBRARY_PATHโดยทั่วไปเป็นสิ่งที่ไม่ดีที่จะแนะนำด้วยเหตุผลอื่น แต่ก็ไม่ฉลาดเพราะปัญหาเหล่านั้น
คู่ปรับ Shot

13
@ParthianShot ประเด็นของคุณเกี่ยวกับการอัพเดทที่ขาดหายไปนั้นเป็นประเด็นที่ยุติธรรม อย่างไรก็ตามสำหรับจุดอื่นของคุณหากซอฟต์แวร์โกงกำลังทำงานในชื่อของคุณการเขียนการเข้าถึงพื้นที่ใน $ LD_LIBRARY_PATH จะเป็นสิ่งที่คุณกังวลน้อยที่สุดเนื่องจากมีการเข้าถึงการเขียนในพื้นที่ที่แย่กว่าและน่าเชื่อถือกว่าเช่นคุณ .bash *, crontab, .wardward และไฟล์การกำหนดค่าทั้งหมดโดยซอฟต์แวร์ทั้งหมดที่คุณใช้ (ซึ่งสามารถตั้งค่าอินสแตนซ์ LD_ {PRELOAD, LIBRARY_PATH} แต่โดยทั่วไปแล้วจะแย่กว่านี้มาก)
Stéphane Chazelas

24

Private mountspaces ที่สร้างด้วยunshareคำสั่งสามารถใช้เพื่อจัดเตรียมไฟล์ private / 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
รอ. ฉันคิดว่าการเมานต์เพิ่งติดตั้งระบบไฟล์ลงในไดเรกทอรี (จุดเมานท์) ฉันไม่ทราบว่าสามารถติดตั้งไฟล์ลงในไฟล์อื่นได้ มันใช้งานได้จริงเหรอ? (ฉันกำลังถามอย่างจริงจังนั่นไม่ใช่การเสียดสี)
killermist

5
ใช่มันใช้งานได้คุณสามารถเมาท์ไฟล์ผ่านไฟล์อื่นด้วย --bind
frielp

เช่นเดียวกับโน้ตสำหรับผู้ที่อยากรู้อยากเห็น: นี่คือการทำกับ namespaces; มีตึกระฟ้าunshare(2)และclone(2)นั่นเป็นส่วนหนึ่งของเวทมนตร์ที่นี่ ดูเพิ่มเติมและnamespaces(7) user_namespaces(7)
Pryftan

5

ทางออกหนึ่งคือให้ผู้ใช้แต่ละคนแยกกันchrootดังนั้นพวกเขาจึงสามารถแยกกัน/etc/hostsได้


3
นี่อาจเป็นคำตอบ แต่ตามที่ระบุไว้ด้วยคำอธิบายเล็ก ๆ น้อย ๆ มันเหมาะกว่าเป็นความคิดเห็น
Anthon

2
ดี ... ใช่มันเป็นไปได้ ถึงแม้ว่าการ chrooting เป็นวิธีการแก้ปัญหาสำหรับงานนี้ค่อนข้างหนัก และนำมาพร้อมกับชุดของปัญหาของตัวเอง
คู่ปรับ Shot

5

ฉันต้องเผชิญกับความต้องการเดียวกันดังนั้นฉันจึงลองใช้ libnss-userhosts แต่มันล้มเหลวในแอพพลิเคชั่นแบบมัลติเธรด ดังนั้นผมจึงได้เขียนlibnss-homehosts มันใหม่มากและทดสอบโดยฉันเท่านั้น คุณอาจให้โอกาสมัน! สนับสนุนตัวเลือกบางอย่างใน /etc/host.conf ชื่อนามแฝงหลายชื่อและการแก้ไขแบบย้อนกลับ (address to name)


1
ดูเหมือนว่าเป็นความคิดที่ดีที่จะเลือกผู้ดูแล libnss และ / หรือผู้ดูแลการกระจาย แต่ก่อนหน้านั้นเกิดขึ้นผู้ใช้ที่ไม่มีรูทเองจะไม่สามารถใช้งานได้ ถึงกระนั้น +1
einpoklum

3

การวางสิ่งต่อไปนี้ใน~/.bashrcการทำงานสำหรับฉันด้วยการทุบตี ~/.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.