เหตุใดฉันจึงได้รับ“ หน้าจอกำลังยุติ” โดยไม่มีรูต


23

ฉันได้ติดตั้งหน้าจอใน Fedora 19 แล้วเมื่อฉันทดสอบคำสั่งว่ารูทผ่าน SSH มันจะทำงานได้อย่างสมบูรณ์ ตัวอย่างเช่นถ้าฉันป้อนscreenเทอร์มินัลอีมูเลเตอร์ใหม่เริ่มทำงานและรอคำสั่ง ฉันสามารถแยกมันออกได้ ฯลฯ อย่างไรก็ตามเมื่อฉันพยายามทำเช่นเดียวกันเมื่อฉันเข้าสู่ระยะไกลผ่าน SSH ในฐานะผู้ใช้มาตรฐานคำสั่งจะยุติทันที [screen is terminating]ข้อความเดียวที่ผมเห็นคือ

มีใครบางคนเคยมีปัญหานี้หรือไม่? มันเกี่ยวข้องกับการอนุญาตที่ไม่ดีหรือไม่?

ปรับปรุง:

$ strace -e trace=file screen
execve("/usr/bin/screen", ["screen"], [/* 23 vars */]) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libutempter.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcrypt.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpam.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libfreebl3.so", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
access("/home/steam/.nethackrc", F_OK)  = -1 ENOENT (No such file or directory)
readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
lstat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
open("/var/run/utmp", O_RDONLY)         = 3
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/shadow", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
lstat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
stat("/var/run/screen", {st_mode=S_IFDIR|0775, st_size=60, ...}) = 0
Directory '/var/run/screen' must have mode 777.
+++ exited with 1 +++

ฉันได้ลองเปลี่ยนการอนุญาตเป็น 777 แล้ว แต่เมื่อฉันดำเนินการscreenฉันจะได้รับ:

ไดเรกทอรี '/ var / run / screen' ต้องมีโหมด 775

ดังนั้นฉันจึงย้อนกลับการเปลี่ยนแปลงของฉัน


คำสั่งคืออะไร?
ewwhite

หนึ่งที่ง่ายที่สุด: "หน้าจอ" ฉันบันทึกตัวอย่างที่shelr.tv/records/525179c7966080791000005f

คุณอยู่บน VPS หรือเซิร์ฟเวอร์ที่โฮสต์โดยบังเอิญหรือไม่
ewwhite

มันเป็นเซิร์ฟเวอร์โฮสต์

strace -e trace=file screenเพื่อตรวจสอบว่ามันล้มเหลวในการเข้าถึงไฟล์ หรือใช้tmuxเป็น work-around มันทำงานเหมือนกันยกเว้นจะใช้ ^ b แทน ^ a
Emmanuel

คำตอบ:


5

พลิกดิ้นระหว่าง "ต้องมีโหมด 777" และ "ต้องมีโหมด 775" straceที่เกิดจากการ

screenมักเป็นโปรแกรม setuid หรือ setgid มันได้รับสิทธิพิเศษเมื่อมีการดำเนินการซึ่งจะใช้ในการสร้างไฟล์ซ็อกเก็ตและ / หรือแก้ไข utmp

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

screen ตรวจสอบว่ามันจะถูกเรียกใช้ด้วยสิทธิ์ setuid สิทธิ์ setgid หรือไม่และปรับความคาดหวังของสิทธิ์ไดเรกทอรี

straceดังนั้นนี้จะสร้างระดับของปัญหาที่ไม่สามารถบั๊กได้อย่างง่ายดายด้วย

แต่ถ้าคุณรูทก็มีวิธีแก้ไข! หากกระบวนการติดตามกำลังทำงานในฐานะรูทกระบวนการติดตามจะได้รับสิทธิพิเศษตามปกติ ดังนั้นนี่คือสิ่งที่คุณทำ:

  1. เปิด 2 เทอร์มินัลใหม่
  2. ในเทอร์มินัลแรกล็อกอินเข้าสู่เครื่องระยะไกลในฐานะรูท
  3. ในเทอร์มินัลที่สองล็อกอินเข้าสู่เครื่องระยะไกลตามผู้ใช้ปกติ
  4. ใช้psเพื่อรับ PID ของกระบวนการเชลล์ของผู้ใช้ปกติในเทอร์มินัลที่สอง
  5. ในเทอร์มินัลแรกรัน strace -f -p SHELLPID
  6. ในเทอร์มินัลที่สองเรียกใช้หน้าจอและดูว่าล้มเหลว
  7. ในเทอร์มินัลแรกตอนนี้คุณมีบันทึก strace ที่คุณต้องการค้นหาว่ามีอะไรผิดปกติจริงๆ

การเพิ่มคีย์ให้กับstraceคำสั่งคือ-fตัวเลือกซึ่งบอกให้ติดตามกระบวนการลูก -pคุณต้องการที่จะติดตามหน้าจอที่จะเป็นเด็กของกระบวนการเปลือกที่คุณระบุไว้ด้วย

ฉันยังต้องการใช้-ffและระบุไฟล์เอาต์พุตด้วย-oเช่นเดียวกับใน

strace -ff -o /tmp/screentrace -p SHELLPID

ซึ่งจะสร้างไฟล์เอาต์พุตแยกต่างหากสำหรับแต่ละกระบวนการย่อย ต่อจากนั้นคุณอ่านพวกเขาด้วยและผลที่ได้มักจะสะอาดกว่าสิ่งที่คุณได้ใช้เพียงครั้งเดียวless /tmp/screentrace*-f

UPDATE

ตอนนี้ฉันได้เห็นผลลัพธ์ของ strace แล้วฉันไม่รู้ว่าเกิดอะไรขึ้น แต่บรรทัดนี้เป็นสิ่งที่น่าประหลาดใจที่สุดในการติดตาม:

chown("/dev/pts/2", 1002, 5)            = -1 EPERM (Operation not permitted)

ไม่กี่บรรทัดก่อนหน้านี้มันสร้าง pty ซึ่งถูกเปิดเผยโดยTIOCGPTNให้เป็นหมายเลข 2

open("/dev/ptmx", O_RDWR)               = 5
...
ioctl(5, TIOCGPTN, [2])                 = 0
stat("/dev/pts/2", {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 2), ...}) = 0

แต่มันก็ไม่สามารถที่จะ chown มัน ฉันไม่รู้ว่าทำไม chown นั้นจะล้มเหลว แต่ความล้มเหลวของ chown นั้นให้เหตุผลที่เป็นไปได้ว่าทำไมหน้าจอยอมแพ้ คุณสามารถรับข้อมูลเพิ่มเติมได้เพียงเพิ่ม-vตัวเลือก strace และดูที่statหลังTIOCGPTNเพื่อดูว่าใครเป็นเจ้าของ/dev/pts/รายการ


ขอบคุณสำหรับขั้นตอนอย่างละเอียด ฉันพยายามดูผลลัพธ์ที่สร้างโดย strace แต่ฉันไม่สามารถเข้าใจได้ว่าเกิดอะไรขึ้น ต่อไปนี้คือลิงก์ที่มีเนื้อหาของสามไฟล์ที่สร้างโดย strace: pastebin.com/raw.php?i=aeqDwTBXยินดีรับฟังข้อคิดเห็นใด ๆ :)
Laurent

2

บนสาเหตุที่เป็นไปได้สำหรับข้อผิดพลาดนั้น - นโยบาย selinux ไม่ถูกต้อง แต่ตามข้อผิดพลาดของตัวแก้ไขข้อผิดพลาดเหล่านั้นได้รับการแก้ไขใน fedora 17/18

ในฐานะที่เป็นวิธีแก้ปัญหาที่คุณสามารถเปลี่ยนตัวแปรSCREENDIRในตัวคุณเพื่อสิ่งที่ต้องการ~/.bashrc$HOME/.screen


ฉันได้ลองแล้ว แต่ไม่ได้แก้ปัญหา
Laurent

1

เมื่อฉันพบข้อผิดพลาดนี้ ฉันต้องปรับการอนุญาตด้วยสิ่งต่อไปนี้:

chmod 2775 /usr/bin/screen

และนี่ช่วยแก้ไขปัญหาสำหรับฉัน 2 มีความสำคัญมากสำหรับสิทธิ์การเข้าถึงที่ถูกต้อง

คุณควรอ่านเพิ่มเติมเกี่ยวกับ SUID, SGID, Sticky Bit, ACL และวิธีที่มันกระทบการเข้าถึง


คุณทำงาน มันไม่ดี แต่ฉันไม่เห็นโซลูชันอื่น ๆ ในขณะนี้
แวดวง Antti Rytsöläปรึกษา

0

คำสั่งหน้าจอกำลังทำงานอยู่แล้ว ดังนั้นฉันจึงยกเลิกมันและพิมพ์คำสั่งอีกครั้ง ใช่นี่ไม่ใช่ความละเอียดที่ดีเหมือนคนอื่น ๆ แต่ใช้เวลาน้อยลงในการทำเช่นนี้

เพียงแค่ ps และค้นหา pid ฆ่า PID และดำเนินการต่อด้วยคำสั่งพิมพ์หน้าจออีกครั้ง

หากคุณใช้คำสั่งหลายหน้าจอตรวจสอบให้แน่ใจว่าคุณยุติกระบวนการที่ถูกต้องที่เกี่ยวข้องกับเทอร์มินัล


0

ฉันพบปัญหานี้ได้รับการแก้ไขหลังจากแสดงความคิดเห็นบรรทัดต่อไปนี้ใน / etc / fstab และรีบูตเครื่อง:

devpts         /dev/pts        devpts  defaults        0       0

0

ตรวจสอบให้แน่ใจว่าไม่มีผู้อื่นscreenใช้อุปกรณ์นั้น

สามารถทำได้ด้วย/superuser/97844/how-can-i-determine-what-process-has-a-file-open-in-linux :

sudo lsof /dev/ttyS0

แล้วฆ่ากระบวนการนั้นถ้าเป็นกรณี

ด้วยเหตุผลบางอย่างภายใต้สภาพเช่นนี้sudo screenยังคงสามารถเข้าถึงอุปกรณ์ screenแต่แล้วว่าการเชื่อมต่อจะคิดถึงตัวละครที่มีการบริโภคโดยคนอื่น ๆ

ตรวจสอบให้แน่ใจว่าผู้ใช้ได้อ่านและเขียนสิทธิ์ในไฟล์

เช่นบน Ubuntu คุณต้องการเพิ่มผู้ใช้ในdialoutกลุ่ม: /ubuntu//a/133244/52975


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