Unix / Linux: ความแตกต่างระหว่าง ID ผู้ใช้จริง ID ผู้ใช้ที่มีประสิทธิภาพและ ID ผู้ใช้ที่บันทึกไว้


107

ฉันรับรู้รหัสผู้ใช้จริงแล้ว เป็นหมายเลขเฉพาะสำหรับผู้ใช้ในระบบ

ในระบบของฉัน My uidis

$ echo $UID
1014
$                 

อีกสอง ID ย่อมาจากอะไร?
และการใช้ID ผู้ใช้ที่มีประสิทธิภาพและID ผู้ใช้ที่บันทึกไว้คืออะไรและเราใช้ที่ใดในระบบ?


FYI - นอกจากนี้ยังมี ID ผู้ใช้ระบบไฟล์ตามที่ระบุไว้ในหน้า Wikipedia: en.wikipedia.org/wiki/User_identifier
Willem van Ketwich

ฉันคิดว่าเขาไม่ได้พูดถึงเรื่องนี้เพราะ (จากลิงค์ wiki ของคุณ): "ตั้งแต่ kernel 2.0 การมีอยู่ของ fsuid ไม่จำเป็นอีกต่อไปเพราะ Linux ปฏิบัติตามกฎ SUSv3 ในการส่งสัญญาณ แต่ fsuid ยังคงอยู่ด้วยเหตุผลด้านความเข้ากันได้"
RtmY

คำตอบ:


151

ความแตกต่างระหว่างรหัสผู้ใช้จริงและรหัสผู้ใช้ที่มีประสิทธิภาพเกิดขึ้นเนื่องจากคุณอาจจำเป็นต้องใช้ข้อมูลประจำตัวของผู้ใช้รายอื่นชั่วคราว (โดยส่วนใหญ่จะเป็นrootเช่นนั้น แต่อาจเป็นผู้ใช้คนใดก็ได้) หากคุณมี ID ผู้ใช้เพียงตัวเดียวจะไม่มีทางเปลี่ยนกลับไปเป็น ID ผู้ใช้เดิมของคุณได้ในภายหลัง (นอกเหนือจากการยอมรับคำของคุณและในกรณีที่คุณrootใช้rootสิทธิ์เพื่อเปลี่ยนเป็นผู้ใช้รายใดก็ได้)

ดังนั้นรหัสผู้ใช้จริงคือตัวคุณเอง (ผู้ที่เป็นเจ้าของกระบวนการ) และรหัสผู้ใช้ที่มีประสิทธิผลคือสิ่งที่ระบบปฏิบัติการพิจารณาเพื่อตัดสินใจว่าคุณได้รับอนุญาตให้ทำบางสิ่งหรือไม่ (โดยส่วนใหญ่ มีข้อยกเว้นบางประการ)

เมื่อคุณเข้าสู่ระบบเชลล์ล็อกอินจะตั้งค่า ID ผู้ใช้จริงและที่มีประสิทธิภาพเป็นค่าเดียวกัน (ID ผู้ใช้จริงของคุณ) ตามที่ไฟล์รหัสผ่านให้

ตอนนี้มันเกิดขึ้นเช่นกันที่คุณรันโปรแกรม setuid และนอกเหนือจากการรันในฐานะผู้ใช้อื่น (เช่นroot) โปรแกรม setuid ก็ควรจะทำอะไรบางอย่างในนามของคุณด้วย วิธีนี้ทำงานอย่างไร?
หลังจากรันโปรแกรม setuid โปรแกรมจะมี ID จริงของคุณ (เนื่องจากคุณเป็นเจ้าของกระบวนการ) และ ID ผู้ใช้ที่มีประสิทธิภาพของเจ้าของไฟล์ (เช่นroot) เนื่องจากเป็น setuid

โปรแกรมทำทุกอย่างที่ต้องใช้เวทย์มนตร์ด้วยสิทธิพิเศษของผู้ใช้ขั้นสูงจากนั้นจึงต้องการทำบางสิ่งในนามของคุณ ซึ่งหมายความว่าความพยายามที่จะทำสิ่งที่คุณไม่ควรจะสามารถที่จะทำควรจะล้มเหลว มันทำได้อย่างไร? เห็นได้ชัดว่าการเปลี่ยนรหัสผู้ใช้ที่มีประสิทธิภาพเป็นรหัสผู้ใช้จริง!

ตอนนี้โปรแกรม setuid มีวิธีการเปลี่ยนกลับเนื่องจากทุกเมล็ดไม่มีใครรู้ว่าเป็น ID ของคุณและ ... ID ของคุณ ปังคุณตายแล้ว

นี่คือรหัสผู้ใช้ชุดที่บันทึกไว้สำหรับ


7
เพื่อความชัดเจนยิ่งขึ้นในประเด็นสุดท้ายเกี่ยวกับ ID ผู้ใช้ที่ตั้งค่าไว้โปรดดูWikipedia
GDP2

คุณช่วยชี้ให้ฉันอ่านบางส่วนที่ฉันสามารถหา sys โทรตรวจสอบ Real uid แทนได้ไหม ขอบคุณ
mik1904

1
@ mik1904: หนึ่งที่สำคัญที่สุดที่คุณมีแนวโน้มที่จะใช้ซึ่งจริงๆการตรวจสอบการaccessโพสต์ที่แท้จริงคือ นั่นคือ 99.9% ของมัน นอกจากนี้setfsuid(แต่ไม่ค่อยจำเป็น) และ funcs ระดับต่ำมากและคุณต้อง (แต่ไม่ได้ตรวจสอบ) ID ผู้ใช้จริงสำหรับการรับ / ตั้งค่าลำดับความสำคัญหรือตัวกำหนดตารางเวลาและ IDs จะถูกส่งไปยังตัวจัดการสัญญาณหรือส่งคืนโดยwaitet al เป็นรหัสจริง execveไม่ตรวจสอบ แต่อาจล้มเหลวหากคุณเปลี่ยน ID ผู้ใช้จริง ยังforkไม่ตรวจสอบ แต่อาจล้มเหลวหากคุณใช้โควต้ากระบวนการสูงสุดใน UID จริง Google กับsite:man7.orgเป็นเพื่อนของคุณที่นี่
Damon

"คำสั่ง ping จำเป็นต้องเปิดซ็อกเก็ตและเคอร์เนล Linux ต้องการสิทธิ์รูทสำหรับสิ่งนั้น" นี่ไม่ถูกต้องจริงๆ pingต้องการซ็อกเก็ตดิบ ผู้ใช้ทุกคนสามารถ (โดยปกติ) เปิดซ็อกเก็ตและสำหรับการฟังสูงกว่า 1024
Daniel Farrell

44

ฉันจะพยายามอธิบายทีละขั้นตอนพร้อมกับตัวอย่าง

พื้นหลังสั้น ๆ

แต่ละขั้นตอนมีของตัวเอง 'ข้อมูลประจำตัวของกระบวนการ' ซึ่งมีคุณลักษณะเช่นPIDนี้PPID, PGID, session IDและยังเป็นจริงและมีประสิทธิภาพของผู้ใช้และรหัสกลุ่ม: RUID, EUID, ,RGIDEGID

เราจะเน้นที่สิ่งเหล่านั้น


ส่วนที่ 1: ทำความเข้าใจ UID และ GID

ตอนนี้ฉันจะเข้าสู่เชลล์ด้วยข้อมูลประจำตัวของฉันและเรียกใช้:

$ grep $LOGNAME /etc/passwd
rotem:x:1000:1000:rotem,,,:/home/rotem:/bin/bash

คุณสามารถดูชื่อบันทึกของฉัน (rotem), UIDและGIDซึ่งมีทั้ง 1,000 รายการและรายละเอียดอื่น ๆ เช่นเชลล์ที่ฉันลงชื่อเข้าใช้


ส่วนที่ 2: ทำความเข้าใจ RUID และ RGID

ทุกขั้นตอนมีเจ้าของและเป็นกลุ่ม
ในเชลล์ของเราทุกกระบวนการที่เราเรียกใช้ตอนนี้จะสืบทอดสิทธิ์ของบัญชีผู้ใช้ของฉันและจะทำงานด้วย UID และ GID เดียวกัน

ให้รันคำสั่งง่ายๆเพื่อตรวจสอบ:

$ sleep 10 & ps aux | grep 'sleep'

และตรวจสอบกระบวนการ UID และ GID:

$ stat -c "%u %g" /proc/$pid/
1000 1000

เหล่านี้เป็นจริง ID ผู้ใช้ ( RUID) จริงและกลุ่ม ID ( RGID) ของกระบวนการ

(*) ตรวจสอบตัวเลือกอื่น ๆ เพื่อดู UID และ GIDและวิธีการที่จะได้รับในหนึ่งซับใน

สำหรับตอนนี้ยอมรับความจริงที่ว่า แอตทริบิวต์EUIDและEGID"ซ้ำซ้อน" และเท่ากับRUIDและRGIDอยู่เบื้องหลัง

ส่วนที่ 3: ทำความเข้าใจ EUID และ EGID

ลองใช้pingคำสั่งเป็นตัวอย่าง

ค้นหาตำแหน่งไบนารีด้วยwhichคำสั่งจากนั้นเรียกใช้ls -la:

-rwsr-xr-x  1 root root   64424 Mar 10  2017  ping

rootคุณจะเห็นว่าเจ้าของและกลุ่มของไฟล์ที่มี เนื่องจากpingคำสั่งจำเป็นต้องเปิดซ็อกเก็ตและเคอร์เนล Linux ต้องการrootสิทธิ์สำหรับสิ่งนั้น

แต่pingถ้าไม่มีrootสิทธิ์จะใช้ได้ยังไง?
สังเกตตัวอักษร"s"แทน "x" ในส่วนของเจ้าของสิทธิ์ของไฟล์
นี้เป็นบิตอนุญาตเป็นพิเศษสำหรับไฟล์ไบนารีเฉพาะ (เช่นpingและsudo) ซึ่งเป็นที่รู้จักกันsetuid

นี่คือที่มาEUIDและEGIDเข้ามามีบทบาท
อะไรจะเกิดขึ้นคือเมื่อsetuidไบนารีเช่นpingรัน, กระบวนการเปลี่ยนแปลงของมันมีผลบังคับใช้ User ID ( EUID) จากค่าเริ่มต้นRUIDให้กับเจ้าของของไฟล์นี้พิเศษไบนารีปฏิบัติการซึ่งในกรณีนี้คือ root-
ทั้งหมดนี้ทำได้โดยข้อเท็จจริงง่ายๆที่ว่าไฟล์นี้มีsetuidบิต

เคอร์เนลตัดสินใจว่ากระบวนการนี้มีสิทธิพิเศษหรือไม่โดยดูEUIDจากกระบวนการ เนื่องจากตอนนี้EUIDชี้ไปrootที่การดำเนินการจะไม่ถูกปฏิเสธโดยเคอร์เนล

แจ้งให้ทราบล่วงหน้า : บนลินุกซ์ใหม่ล่าสุดออกการส่งออกของpingคำสั่งจะมีลักษณะที่แตกต่างกันเพราะความจริงที่ว่าพวกเขานำความสามารถของลินุกซ์วิธีนี้แทนการsetuidวิธีการ - สำหรับผู้ที่ไม่คุ้นเคย - อ่านที่นี่

ส่วนที่ 4: SUID และ SGID ล่ะ?

ID ผู้ใช้ที่บันทึกไว้ ( SUID) ถูกใช้เมื่อกระบวนการที่มีสิทธิพิเศษกำลังทำงานอยู่ ( rootเช่น) และจำเป็นต้องทำงานบางอย่างที่ไม่มีสิทธิพิเศษ

ในกรณีนั้น UID ( EUID) ที่มีประสิทธิภาพจากก่อนหน้านี้จะถูกบันทึกไว้ภายในSUIDแล้วเปลี่ยนเป็นงานที่ไม่มีสิทธิ เมื่องานที่ไม่มีสิทธิพิเศษเสร็จสิ้นEUIDจะถูกนำออกจากมูลค่าSUIDและเปลี่ยนกลับไปเป็นบัญชีที่มีสิทธิ์



1
คำตอบที่ชัดเจนยกเว้นวรรคสุดท้ายของ SUID สับสนกับงานที่มีสิทธิพิเศษและมีสิทธิพิเศษ มีประโยชน์หากมีตัวอย่างให้ ขอบคุณ.
Upendra

2
คำตอบที่แม่นยำมาก ขอบคุณ !!
user37416
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.