การส่งต่อ ssh-agent และ sudo ไปยังผู้ใช้รายอื่น


153

หากฉันมีเซิร์ฟเวอร์ A ซึ่งฉันสามารถเข้าสู่ระบบด้วยคีย์ ssh ของฉันและฉันมีความสามารถในการ "sudo su - otheruser" ฉันจะสูญเสียการส่งต่อคีย์เนื่องจากตัวแปร env ถูกลบและซ็อกเก็ตสามารถอ่านได้โดยผู้ใช้ดั้งเดิมของฉันเท่านั้น มีวิธีที่ฉันสามารถเชื่อมโยงคีย์การส่งต่อผ่าน "sudo su - otheruser" ดังนั้นฉันสามารถทำสิ่งต่าง ๆ บนเซิร์ฟเวอร์ B ด้วยคีย์การส่งต่อของฉัน (git clone และ rsync ในกรณีของฉัน)?

วิธีเดียวที่ฉันคิดได้ก็คือการเพิ่มกุญแจของฉันไปที่ authorized_keys ของ otheruser และ "ssh otheruser @ localhost" แต่นั่นเป็นเรื่องยุ่งยากที่จะทำสำหรับผู้ใช้และชุดเซิร์ฟเวอร์ที่ฉันมี

ในระยะสั้น:

$ sudo -HE ssh user@host
(success)
$ sudo -HE -u otheruser ssh user@host
Permission denied (publickey). 

คำตอบ:


182

ดังที่คุณกล่าวถึงตัวแปรสภาพแวดล้อมจะถูกลบออกsudoเพื่อความปลอดภัย

แต่โชคดีที่sudoสามารถกำหนดค่าได้มาก: คุณสามารถบอกได้ว่ามันแม่นยำซึ่งเป็นตัวแปรสภาพแวดล้อมที่คุณต้องการให้ขอบคุณการกำหนดค่าตัวเลือกในenv_keep/etc/sudoers

สำหรับการส่งต่อเอเจนต์คุณต้องเก็บSSH_AUTH_SOCKตัวแปรสภาพแวดล้อม โดยแก้ไข/etc/sudoersไฟล์กำหนดค่าของคุณ(ใช้งานอยู่เสมอvisudo) และตั้งค่าenv_keepตัวเลือกให้กับผู้ใช้ที่เหมาะสม หากคุณต้องการให้ตัวเลือกนี้ถูกตั้งค่าสำหรับผู้ใช้ทุกคนให้ใช้Defaultsบรรทัดดังนี้:

Defaults    env_keep+=SSH_AUTH_SOCK

man sudoers สำหรับรายละเอียดเพิ่มเติม

ตอนนี้คุณควรจะสามารถทำอะไรเช่นนี้ (ให้user1's คีย์สาธารณะในปัจจุบันคือ~/.ssh/authorized_keysในuser1@serverAและuser2@serverBและserverAของ/etc/sudoersไฟล์มีการติดตั้งตามที่ระบุไว้ข้างต้น):

user1@mymachine> eval `ssh-agent`  # starts ssh-agent
user1@mymachine> ssh-add           # add user1's key to agent (requires pwd)
user1@mymachine> ssh -A serverA    # no pwd required + agent forwarding activated
user1@serverA> sudo su - user2     # sudo keeps agent forwarding active :-)
user2@serverA> ssh serverB         # goto user2@serverB w/o typing pwd again...
user2@serverB>                     # ...because forwarding still works

1
นี่คือคำตอบที่ถูกต้องควรถูกทำเครื่องหมาย
Xealot

41
นี้เท่านั้นงานถ้าuser2ข้างต้นเป็นroot! มิฉะนั้นuser2จะตั้งค่า SSH_AUTH_SOCK ให้ถูกต้อง แต่user2จะไม่สามารถเข้าถึงได้เช่น / tmp / ssh-GjglIJ9337 / rootจะมีการเข้าถึง ดังนั้นนี่อาจแก้ปัญหาบางส่วน แต่ไม่ใช่ OPs: " และซ็อกเก็ตสามารถอ่านได้โดยผู้ใช้ดั้งเดิมของฉันเท่านั้น"
Peter V. Mørch

6
Defaults>root env_keep+=SSH_AUTH_SOCKควรตรวจสอบให้แน่ใจว่าส่งต่อเมื่อ sudoing ไปยังรูทเท่านั้น คุณไม่ต้องการทำสิ่งนั้นกับผู้ใช้รายอื่นด้วยเหตุผลด้านความปลอดภัย เรียกใช้ ssh-agent แยกกันสำหรับคนอื่น ๆ และเพิ่มปุ่มที่เหมาะสม
พอล Schyska

1
sudo su -ใช้งานไม่ได้สำหรับฉันสันนิษฐานว่ามันไม่สามารถรักษาสภาพแวดล้อมได้เพราะมันไม่ใช่sudoเวลาเริ่มต้นของเชลล์ sudo suดูเหมือนว่าจะทำงาน
Alex Fortuna

3
ฉันไม่เคยเข้าใจว่าทำไมคนใช้sudo suอยู่แล้ว หากคุณต้องการเปลือกรากว่าเป็นสิ่งที่sudo -sหรือsudo -iสำหรับ
eaj

68
sudo -E -s
  • - E จะรักษาสิ่งแวดล้อม
  • -s รันคำสั่งเริ่มต้นที่เชลล์

สิ่งนี้จะทำให้คุณรูทเชลล์พร้อมคีย์ต้นฉบับที่โหลดอยู่


2
เช่นเดียวกับความคิดเห็นด้านบนสิ่งนี้จะตอบคำถามหากคุณกลายเป็นรูทเพราะในกรณีนั้นรูทจะสามารถรับสิทธิ์การเข้าถึงตามปกติใน $ SSH_AUTH_SOCK
doshea

35

อนุญาตให้otheruserในการเข้าถึง$SSH_AUTH_SOCKไฟล์และไดเรกทอรีเช่นโดย ACL ที่ถูกต้องก่อนที่จะเปลี่ยนให้กับพวกเขา ตัวอย่างสมมติDefaults:user env_keep += SSH_AUTH_SOCKใน/etc/sudoersเครื่องโฮสต์:

$ ssh -A user@host
user@host$ setfacl -m otheruser:x   $(dirname "$SSH_AUTH_SOCK")
user@host$ setfacl -m otheruser:rwx "$SSH_AUTH_SOCK"
user@host$ sudo su - otheruser
otheruser@host$ ssh server
otheruser@server$

ปลอดภัยยิ่งขึ้นและใช้ได้กับผู้ใช้ที่ไม่ใช่รูทด้วย ;-)


6
จำไว้ว่าเมื่อใช้วิธีนี้คนอื่น ๆ ที่เข้าสู่ระบบในขณะที่otheruserยังสามารถใช้การตรวจสอบสิทธิ์ SSH ของคุณ
gitaarik

สิ่งนี้ใช้ได้สำหรับฉันยกเว้นฉันต้องเปลี่ยน "sudo su - otheruser" เป็น "sudo su otheruser" (การลบ -)
Charles Finkel

1
ทำไมrwxและไม่rw(หรือrเลย)
Anatoly techtonik

3
@anatolytechtonik จากman 7 unix- บน Linux การเชื่อมต่อกับซ็อกเก็ตต้องใช้สิทธิ์ในการอ่านและเขียนบนซ็อกเก็ตนั้น นอกจากนี้คุณต้องค้นหา (ดำเนินการ) และเขียนสิทธิ์ในไดเรกทอรีที่คุณสร้างซ็อกเก็ตหรือค้นหาสิทธิ์ (เรียกใช้) เมื่อคุณเชื่อมต่อกับซ็อกเก็ตนี้ ดังนั้นในคำตอบข้างต้นดำเนินการอนุญาตบนซ็อกเก็ตซ้ำซ้อน
mixel

แทนที่จะต้องแก้ไข / etc / sudoers คุณสามารถใช้sudo -u otheruser --preserve-env=HOME -s
Sec

14

ฉันได้พบว่าสิ่งนี้ยังใช้งานได้

sudo su -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

ดังที่คนอื่น ๆ ระบุไว้สิ่งนี้จะไม่ทำงานหากผู้ใช้ที่คุณเปลี่ยนไปไม่มีสิทธิ์อ่านบน $ SSH_AUTH_SOCK (ซึ่งค่อนข้างผู้ใช้รายใดนอกจากราก) คุณสามารถแก้ไขได้โดยการตั้งค่า $ SSH_AUTH_SOCK และไดเรกทอรีที่อยู่ในนั้นจะมีสิทธิ์ 777

chmod 777 -R `dirname $SSH_AUTH_SOCK`
sudo su otheruser -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

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


6
นี่เป็นความเสี่ยงอย่างยิ่ง การให้สิทธิ์ผู้ใช้อื่น ๆ ทุกครั้งเพื่อใช้เอเจนต์ SSH ของคุณนั้นเทียบเท่ากับการให้ข้อมูลรับรองทั้งหมดของคุณ (และถ้าคุณเคยใช้ sudo หรือ su ให้รูทพลังแก่ผู้ใช้อื่น ๆ ในระบบรวมทั้งระบบอื่น ๆ ที่คุณ ssh!) . สิ่งนี้จะต้องไม่เคยเกิดขึ้น!
Matija Nalis

4
ฉันไม่เห็นด้วยกับข้อความที่ว่า "สิ่งนี้จะต้องไม่เคยเกิดขึ้น!" มีหลายกรณีที่ยอมรับความเสี่ยงนี้ได้ ตัวอย่างเช่นทีมเล็ก ๆ ที่ทุกคนมีสิทธิ์เหมือนกันและคุณเชื่อถือผู้ใช้รายอื่นทั้งหมด ไม่ควรทำโดยไม่เข้าใจความเสี่ยงที่เกี่ยวข้อง แต่เมื่อเข้าใจความเสี่ยงเหล่านั้นแล้วก็มีบางครั้งที่ความเสี่ยงนั้นเป็นที่ยอมรับได้
ไฟ

6

หากคุณได้รับอนุญาตsudo su - $USERคุณอาจจะมีข้อโต้แย้งที่ดีสำหรับการได้รับอนุญาตให้ทำssh -AY $USER@localhostแทนโดยใช้รหัสสาธารณะที่ถูกต้องในโฮมไดเร็กตอรี่ของ US $ จากนั้นการตรวจสอบความถูกต้องของคุณจะถูกส่งต่อไปกับคุณ


เขากล่าวว่าที่ด้านล่างของคำถามของเขาและบอกว่ามันยากที่จะทำ
Fahad Sadah

นี่อาจเป็นทางออกที่ดีที่สุด แต่จะลำบากถ้า $ USER เป็นบุคคลจริง (tm) - พวกเขาอาจลบคีย์ของ SA ออกจาก authorized_keys หรือเปลี่ยนรหัสผ่าน ...
voretaq7

คุณสามารถลบสิทธิ์การเขียนของพวกเขาไปที่ authorized_keys (แม้ว่าพวกเขาจะถูกกำหนดให้ปฏิเสธการเข้าถึง Florian จริง ๆ พวกเขาสามารถลบและสร้างใหม่ได้มันอยู่ในไดเรกทอรีที่พวกเขาเป็นเจ้าของ)
Fahad Sadah

4

คุณสามารถ ssh ไปยัง localhost ได้ตลอดเวลาพร้อมตัวแทนส่งต่อแทนที่จะใช้ sudo:

ssh -A otheruser@localhost

ข้อเสียคือคุณต้องเข้าสู่ระบบอีกครั้ง แต่ถ้าคุณใช้ในแท็บหน้าจอ / tmux นั่นเป็นเพียงความพยายามเพียงครั้งเดียวอย่างไรก็ตามหากคุณตัดการเชื่อมต่อจากเซิร์ฟเวอร์ซ็อกเก็ตจะถูกทำลายอีกครั้ง . ดังนั้นจึงไม่เหมาะถ้าคุณไม่สามารถเปิดเซสชัน / tmux เซสชันตลอดเวลา (อย่างไรก็ตามคุณสามารถอัปเดตSSH_AUTH_SOCKenv var ของคุณด้วยตนเองหากคุณยอดเยี่ยม)

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


วิธีนี้ใช้ไม่ได้หากคุณสามารถเข้าถึงotheruserผ่านsudoแทนที่จะใช้ SSH (เช่นคุณต้องการ SCP แทนwww-data)
Gert van den Berg

3

อย่าใช้sudo su - USERแต่จะดีsudo -i -u USERกว่า ใช้งานได้สำหรับฉัน!


คุณมี sudo รุ่นใด Mine (1.6.7p5, CentOS 4.8) ไม่มี -i ใน man page
David Mackintosh

Sudo version 1.6.9p17วิ่งบน Debian Lenny ลองsudo -s?
Fahad Sadah

6
ใช้งานไม่ได้สำหรับฉัน

บน Ubuntu ใช้ Sudo 1.8.9p5 ทั้งsudo -sมิได้sudo -iทำงานสำหรับฉัน ...
จอนลิตร

2

การรวมข้อมูลจากคำตอบอื่น ๆ ที่ฉันพบกับสิ่งนี้:

user=app
setfacl -m $user:x $(dirname "$SSH_AUTH_SOCK")
setfacl -m $user:rwx "$SSH_AUTH_SOCK"
sudo SSH_AUTH_SOCK="$SSH_AUTH_SOCK" -u $user -i

ฉันชอบสิ่งนี้เพราะฉันไม่จำเป็นต้องแก้ไขsudoersไฟล์

ทดสอบบน Ubuntu 14.04 (ต้องติดตั้งaclแพ็คเกจ)


1

ฉันคิดว่ามีปัญหากับ-ตัวเลือก (เส้นประ) หลังจากsuอยู่ในคำสั่งของคุณ:

sudo su - otheruser

หากคุณอ่าน man page ของsuคุณอาจพบว่าตัวเลือก-, -l, --loginเริ่มต้นสภาพแวดล้อมเชลล์เป็นเชลล์ล็อกอิน นี้จะเป็นสภาพแวดล้อมสำหรับการotheruserไม่คำนึงถึงตัวแปร env suที่คุณเรียก

sudoใส่เพียงแค่เส้นประจะทำลายสิ่งที่คุณส่งผ่านจาก

คุณควรลองคำสั่งนี้แทน:

sudo -E su otheruser

ในฐานะที่เป็น Joao-Costa @ ชี้จะเก็บตัวแปรทั้งหมดในสภาพแวดล้อมที่คุณวิ่ง-E sudoจากนั้นไม่มีเส้นประsuจะใช้สภาพแวดล้อมนั้นโดยตรง


0

น่าเสียดายที่เมื่อคุณใช้กับผู้ใช้รายอื่น (หรือแม้แต่ใช้ sudo) คุณจะสูญเสียความสามารถในการใช้คีย์ที่ส่งต่อของคุณ นี่คือคุณลักษณะด้านความปลอดภัย: คุณไม่ต้องการให้ผู้ใช้แบบสุ่มที่เชื่อมต่อกับ ssh-agent ของคุณและใช้กุญแจของคุณ :)

วิธี "ssh -Ay $ {USER} @localhost" นั้นค่อนข้างยุ่งยาก (และตามที่ระบุไว้ในความคิดเห็นของฉันเกี่ยวกับคำตอบของเดวิดที่มีแนวโน้มที่จะแตกหัก) แต่อาจเป็นวิธีที่ดีที่สุดที่คุณจะทำได้


1
อืม แต่ถ้าฉันทำสิ่งนี้ด้วย ssh ตัวแทนของฉันก็สามารถเข้าถึงได้โดยผู้ใช้รายนั้นหรือฉันผิด

หากคุณ SSH เป็นผู้ใช้เป้าหมายด้วยตัวแทนส่งต่อคำขอตัวแทนของคุณจะเด้งโซ่ไปทุกที่ตัวแทน "ของจริง" คือ เมื่อคุณอยู่หรือออกจากผู้ใช้ดั้งเดิมซ็อกเก็ตเอเจนต์ SSH ของคุณจะไม่สามารถเข้าถึง (หรือไม่ควร) ไดเรกทอรีที่อยู่ในนั้นคือโหมด 700 และเป็นเจ้าของโดยผู้ใช้ดั้งเดิม (ชัดเจน Caveat: หากคุณเปลี่ยนไปใช้รูทและรีเซ็ตสภาพแวดล้อม SSH_AUTH_SOCK มันอาจใช้งานได้ แต่ฉันจะไม่พึ่งพา)
voretaq7

1
บนเซิร์ฟเวอร์ของฉัน (Ubuntu 12.04, รุ่น ssh OpenSSH_5.9p1 Debian-5ubuntu1.1, OpenSSL 1.0.1 14 มีนาคม 2012), ssh มี-aและ-Aข้อโต้แย้ง -aไม่ตรงข้ามกับสิ่งที่ตั้งใจไว้ แต่จะปิดใช้งานการส่งต่อตัวแทน! ดังนั้นภายใต้ Ubuntu รุ่นล่าสุด (และอาจเป็นไปได้ทั้งหมด) ใช้-Aเพื่อเปิดใช้งานการส่งต่อตัวแทน
knite

@ อัศวินคุณถูกต้อง - นั่นเป็นคำสะกดผิด (3 ปี!) ในคำตอบของฉัน แก้ไขตอนนี้ :-)
voretaq7
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.