หยุดการเข้าสู่ระบบ ssh จากการพิมพ์ motd จากลูกค้าหรือไม่


43

ฉันได้ตั้งค่ารหัสผ่าน SSH ไว้แล้ว แต่จะพิมพ์ MoTD เมื่อลงชื่อเข้าใช้มีการหยุดที่เกิดขึ้นจากฝั่งไคลเอ็นต์หรือไม่

ฉันพยายามแล้วssh -qแต่ก็ใช้ไม่ได้ ฉันไม่ต้องการใช้~/.hushloginและไม่ต้องการเปลี่ยนการตั้งค่าเซิร์ฟเวอร์ >/dev/null 2>&1สิ่งเดียวที่สามารถทำงานเป็นที่เงียบสงบการส่งออกทั้งหมดที่มี อย่างไรก็ตามฉันไม่ต้องการละเว้นข้อผิดพลาดในกรณีที่มีปัญหาจริง แม้แต่การทำ>/dev/nullไม่ได้ผลsshดูเหมือนจะพิมพ์ motd ไปที่ stderr

อัปเดต & การใช้เหตุผลฉันกำลังสำรองข้อมูลใน cron ฉันไม่ต้องการรับอีเมล cron ยกเว้นว่ามีข้อผิดพลาดเกิดขึ้น อย่างไรก็ตามหากพิมพ์ motd ฉันจะได้รับอีเมลตลอดเวลา

ฉันต้องการที่จะให้ motd ถูกพิมพ์เพราะมันมีความหมายตามกฎหมาย Motd กล่าวว่า "ห้ามการเข้าถึงที่ไม่ได้รับอนุญาต" คุณต้องมีคำแถลงประเภทนี้ในที่นั่นเพื่อป้องกันไม่ให้บุคคลอื่นเข้าถึงได้โดยชอบด้วยกฎหมาย (เช่นไม่มีเครื่องหมายการบุกรุก) ดังนั้นฉันไม่ต้องการที่จะปิดการใช้งานตลอดเวลา


1
คุณสามารถเพิ่มรายละเอียดเกี่ยวกับงาน cron และ ...
ไคล์ Brandt

1
motd จะถูกพิมพ์สำหรับเซสชันแบบโต้ตอบเท่านั้น ฉันเพิ่งทดสอบและมันก็เป็นเช่นนั้น:> $ ssh host → MOTD พิมพ์> $ ssh host ls →พิมพ์เฉพาะเนื้อหาของโฮมไดเร็กตอรี่กล่าวอีกอย่างคือคุณกำลังทำอะไรผิดไปมาก; คุณเคยลองไหม
niXar

นอกจากนี้ยังควรสังเกตว่าควรเช็คอิน/etc/profile.dสคริปต์ใด ๆ ที่อาจทำงานที่นั่นและพิมพ์เอาต์พุตบางส่วนไปยังคอนโซลเมื่อเข้าสู่ระบบ
เดฟ

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

คำตอบ:


57

ฉันไม่แน่ใจว่าทำไมคุณถึงชอบทำสิ่งนี้อย่างถูกต้องไม่ว่าจะเป็นบนเซิร์ฟเวอร์

PrintMotd no
PrintLastLog no

และ

#/etc/pam.d/ssh
# Print the message of the day upon successful login.
# session    optional     pam_motd.so

หรือเพิ่ม ~ / .hushlogin สำหรับผู้ใช้แต่ละคน

คำแนะนำสำหรับ ~ / .hushlogin ให้เพิ่มไปยัง / etc / skel เพื่อสร้างโฮมไดเร็กทอรีของผู้ใช้ใหม่ด้วยไฟล์

ปรับปรุง:

หากไม่มีข้อมูลเพิ่มเติมเกี่ยวกับงาน cron สำรองของคุณข้อเสนอแนะอื่น ๆ ของฉันคือการเปลี่ยนเส้นทางเอาต์พุตของคำสั่งไปยังไฟล์ สิ่งที่ต้องการ:

0 0 * * * ssh backuphost "backup_script_that_writes_to_a_log" >/dev/null

หรือ

0 0 * * * ssh backuphost "backup_command 2>&1" >/dev/null

ฉันต้องเล่นกับคำสั่งเล็กน้อย แต่คุณควรเริ่มต้น


3
ฉันชอบที่ "ทำถูกต้อง"
เบอนัวต์

14
ฉันไม่ต้องการลบออกจากเซิร์ฟเวอร์เนื่องจากฉันต้องแจ้งให้ทราบ 'ห้ามการเข้าถึงที่ได้รับอนุญาต' ที่นั่นด้วยเหตุผลทางกฎหมาย
Rory

3
Fwiw การแจ้งเตือนไม่ได้ป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต แต่เป็นการแจ้งให้คนที่คุณสามารถ (และจะ) ดำเนินการทางกฎหมายที่เหมาะสมและอาจตรวจสอบการใช้งานของพวกเขาเช่นเดียวกับการแจ้งเตือนเกี่ยวกับการบันทึกการสนทนาทางโทรศัพท์
jtimberman

มันจะช่วยได้มากถ้าคุณวางงาน cron ที่คุณใช้อยู่
jtimberman

3
.hushloginเป็นสิ่งที่ดี
andrewtweber

15

หากคุณต้องการสิ่งนี้ต่อผู้ใช้เพียงแค่ทำtouch ~/.hushloginและคุณพร้อมที่จะใช้ OpenSSH

ปรับปรุง : เป็นแหลมออกอื่น ๆpam_motdอาจจะมีการกำหนดค่าให้ได้ใช้ต่อผู้ใช้.hushlogin; ตรวจสอบสำหรับ/etc/login.defs HUSHLOGIN_FILEอาจมีการกำหนดค่าให้มีผู้ใช้ทั้งหมดที่อยู่ในรายการ/etc/hushloginsหรือคล้ายกัน


2
ฉันลองมัน แต่มันไม่ทำงาน ตามที่คนอื่นได้ชี้ให้เห็น motd อาจถูกพิมพ์จากแพม
Rory

11

ตัวอย่าง @note ทั้งหมดถือว่าคุณได้ตั้งค่าตัวแปรกับสิ่งที่ต้องการconnectionStringconnectionString=user@server

ฉันไปถึงทางออกได้อย่างไร

การใช้ssh -Tควรทำงานกับคำสั่งง่าย ๆ ตัวอย่างเช่นสิ่งนี้จะไม่พิมพ์ข้อมูลพิเศษใด ๆ :

ssh -T $connectionString "echo 'blah'"

ปัญหาคือเมื่อคุณพยายามใช้ here-doc เพื่อเรียกใช้คำสั่งมากมาย ตัวอย่างเช่น - ร้องจะไม่ทำงาน - มันจะสะท้อนข้อความของวัน (MoTD) และยังอาจแสดงให้คุณเห็น "stdin: ไม่ใช่ tty"

somethingLocal='something local'
ssh -T $connectionString <<EOC
    echo 'blah'
    echo "blah $somethingLocal"
EOC

หากต้องการแก้ไขปัญหาคุณต้องบันทึกคำสั่งไปยังตัวแปรโลคัลก่อนและส่งไปยังเซิร์ฟเวอร์ระยะไกล

somethingLocal='something local'
read -r -d '' commands <<EOC
    echo 'blah'
    echo "blah $somethingLocal"
EOC
ssh -T $connectionString "$commands"

แต่มันยุ่ง ...

ทางออกสุดท้าย

สร้างฟังก์ชันสากล (โปรดทราบว่าสามารถใช้สตริงหรือ HEREDOC เป็นคำสั่ง)

function silentSsh {
    local connectionString="$1"
    local commands="$2"
    if [ -z "$commands" ]; then
        commands=`cat`
    fi
    ssh -T $connectionString "$commands"
}

ตัวอย่าง

ใช้สิ่งนี้เช่น:

somethingLocal='something local'
silentSsh $connectionString <<EOC
    echo 'blah'
    echo "blah $somethingLocal"
EOC

หรือชอบ:

silentSsh $connectionString "echo 'blah'"

หรือชอบ:

silentSsh $connectionString <<'EOC'
    echo 'blah'
    somethingRemote=`echo 'whatever'`
    echo "blah $somethingRemote"
EOC

หรือชอบ:

silentSsh $connectionString < getlines.sh

ฉันหวังว่าฉันจะมี upvotes มากกว่านี้ มีประโยชน์มากในการหาสคริปต์ที่เราจำเป็นต้องทำ
csexton

คำตอบที่ยอดเยี่ยม !! ขอบคุณมาก!!
Scottie H

10

แล้วแฮ็คนี้ล่ะ? ;-P

ssh -t user@machineName '/bin/bash'

ต่อไปนี้ไม่ถูกต้อง:

ส่งผ่าน-Tไปยัง ssh เพื่อปิดใช้งานการจัดสรร tty:

ssh -T machineName 'echo foo'

3
ผู้ใช้ ssh @ machine 'คำสั่งของคุณที่นี่' ไม่แสดง motd ต่อไป (ไม่ใช่เชลล์แบบโต้ตอบ)
Marie Fischer

ดีจังประเด็น ....
Kyle Brandt

แต่มันหมายถึง "มันไม่ใช่เชลล์แบบโต้ตอบ" ตั้งแต่ฉันลองและฉันสามารถเรียกใช้คำสั่งว่าฉันจะพลาดการใช้งานได้อย่างไร-t
Ciasto piekarz

โปรดทราบว่าการเพิ่ม "-t" จะเปลี่ยนพฤติกรรม (มันจะแสดงตามการตั้งค่าของคุณเพิ่มตัวควบคุมเมื่อจำเป็น ฯลฯ ) มันสามารถเปลี่ยนผลลัพธ์ของคำสั่งบางอย่าง (มันสามารถยกตัวอย่างข้อผิดพลาดใน: ssh -t somehost "tar cf - บางไฟล์"> local.tar # อย่าใช้ -t ที่นี่ ... โดยเฉพาะถ้าคุณ ssh โฮสต์ unix จาก หน้าต่างหนึ่ง แต่ปัญหาอื่น ๆ อีกมากมายอาจเกิดขึ้นในกรณีอื่น ๆ ) ดูคำตอบ@StephaneChazelas ที่
Olivier Dulac

3

นี่คือระบบปฏิบัติการอะไร ในบางระบบ (เช่น ubuntu) motd ไม่ได้ถูกพิมพ์โดยเซิร์ฟเวอร์ ssh (PrintMotd ใน / etc / ssh / sshd_config) แต่โดย pam ด้วย pam_motd หากเป็นกรณีนี้คุณอาจไม่สามารถควบคุมได้จากลูกค้า


คุณไม่สามารถควบคุมได้ในลูกค้า SSH แต่คุณสามารถทำได้สำหรับแน่ใจว่าในฝั่งไคลเอ็นต์ :) .. เห็นคำตอบของฉันสำหรับรายละเอียด
drAlberT

ไม่คุณได้เสนอการแฮ็คที่น่าสนใจ / ฉลาดรอบ ๆ motd ที่กำลังพิมพ์ไม่ใช่วิธีแก้ปัญหาที่จะหยุดพิมพ์โดยลูกค้าซึ่งเป็นคำถาม
theotherreceive

2

คุณต้องทำบนเซิร์ฟเวอร์:

PrintMotd no
PrintLastLog no

บนเดเบียน / อูบุนตูก็แฮชด้วย pam_motd.so:

#/etc/pam.d/ssh
# Print the message of the day upon successful login.
# session    optional     pam_motd.so

ไม่คุณทำไม่ได้ ดูคำตอบของ Kyle Brandt ด้านล่าง
Stobor

-1 - คำตอบไม่ได้สะท้อนคำถามที่แก้ไขแล้ว ไม่มีความเกี่ยวข้องอีกต่อไป
romandas

2

อย่าเรียกใช้คำสั่ง ssh โดยตรงโดย cron

สร้างสคริปต์ผู้ช่วยเหลือทุบตีแทนดำเนินงาน ssh และดึงข้อมูลเอาต์พุตข้อผิดพลาดและรหัสข้อผิดพลาดหากจำเป็น ในที่สุดก็แยกพวกเขาเพื่อลบสตริงที่ไม่ต้องการออกจากข้อความแสดงข้อผิดพลาด (MoTD ในกรณีของคุณ) แล้วพิมพ์บน bash script output และสตรีมข้อผิดพลาดสิ่งที่คุณได้รับในลักษณะดังกล่าว

กว่าที่จะใส่สคริปต์ทุบตีนี้ใน cron และมีความสุข :)

หมายเหตุ: นี่เป็นวิธีการแก้ปัญหาทั่วไปและจะต้องทำงานอะไรก็ตามที่คุณต้องทำผ่าน ssh มันเป็นเพียงฝั่งไคลเอ็นต์ด้วยซึ่งควรตอบสนองความต้องการของคุณ ... การพึ่งพาของไคลเอ็นต์บนเซิร์ฟเวอร์ config เท่านั้นคือความรู้เกี่ยวกับข้อความที่แน่นอนที่คุณต้องการตัดออกจาก std err หรือออกจากไคลเอ็นต์ ssh


2
นั่นไม่ใช่วิธีแก้ปัญหาที่เป็นวิธีแก้ปัญหา
niXar

ฉันไม่สามารถเห็นด้วยกับคุณขอโทษ IMHO นั่นคือสิ่งที่ควรทำอย่างหมดจด ... ฉันเห็นด้วยกับคุณหากมีวิธีกำหนดค่าไคลเอนต์ ssh อย่างชัดเจนเพื่อละเว้น motd แต่มันไม่มีอยู่จริงเพราะมันไม่ได้อยู่ภายใต้การควบคุม sshd !
drAlberT

2

เพียง sidenote (จะได้รับความคิดเห็นถ้าฉันสามารถโพสต์นั้น): เนื้อหาของ motd จะปรากฏขึ้นหลังจากที่ประสบความสำเร็จในการเข้าสู่ระบบเต็มระบบ หากฉันต้องการป้องกันไม่ให้ผู้อื่นเข้าถึงกล่องฉันควรทำโดย "แบนเนอร์" ใน sshd_config เนื้อหาจะปรากฏขึ้นหลังจากป้อนชื่อผู้ใช้ แต่ก่อนที่จะตรวจสอบความถูกต้อง


4
ใช่ แต่คุณสามารถปิดการใช้งานแบนเนอร์โดยใช้ -q บนไคลเอนต์ ssh ดังนั้นฉันไม่สามารถเห็นด้วยกับบันทึกย่อของคุณ
drAlberT

1
โอ้เด็กชายฉันเห็นได้เลยว่า "-q" เอาชนะการป้องกันทั้งหมดของทีมกฎหมายที่ทำงานเพื่อ Dynacorp Inc. Gosh แล้ว! พวกเขาไม่เห็นว่าจะมา รับจริง หากใครบางคนที่ควรจะเห็นแบนเนอร์หลบหลีกมันอย่างเด็ดขาด ... แบนเนอร์ยังคงมีผลผูกพันเนื่องจากคุณต้องรู้เพื่อหลีกเลี่ยงมัน
niXar

2

ไม่ว่าคุณจะยังไม่ได้ลองสิ่งที่คุณกำลังอธิบายหรือเซิร์ฟเวอร์ของคุณมีการกำหนดค่าผิด!

นี่คือสิ่งที่ฉันลองใช้กับ RHEL5:

workstation ~ $ ssh root@server
server ~ # echo "MOTD" > /etc/motd
server ~ # ^D
workstation ~ $ ssh root@server
MOTD
server ~ # ^D
workstation ~ $ ssh root@server echo notice the lack of motd
notice the lack of motd
workstation ~ $ 

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

แต่ในกรณีใด ๆ นี่คือสิ่งที่ฉันทำเพราะฉันไม่ชอบจดหมายจาก cron: ฉันไปป์เอาท์พุทกับคนตัดไม้ เพียงแป๊บผ่านหางเพื่อลบสองสามบรรทัดแรก (สมมติว่า 3) ของข้อจำกัดความรับผิดชอบอย่างไม่มีจุดหมายของคุณเช่นรหัสที่ยังไม่ทดลองฉันไม่สามารถเข้าถึงสคริปต์ของฉันได้:

( tail -n +3 | logger -i -t mycronjob -s -p cron.crit ) <&6 &
exec 2>&6
cron_fsckin_job

หากคุณมองหา man sshd คุณจะเห็นว่ามันบอกว่า: กระบวนการล็อกอินเมื่อผู้ใช้ล็อกอินสำเร็จ sshd จะทำสิ่งต่อไปนี้: 1. หากการล็อกอินอยู่บน tty และไม่มีคำสั่งระบุไว้พิมพ์เวลาล็อกอินครั้งสุดท้าย และ / etc / motd (เว้นแต่ป้องกันในไฟล์กำหนดค่าหรือโดย ~ / .hushlogin; ดูส่วนไฟล์) 2. ... ขอให้สังเกตว่าถ้าคำสั่งที่มีการป้อนไดเรกทอรีในการเข้าสู่ระบบ SSH ไม่มี MOTD จะปรากฏ
Katriel

ฉันรู้ว่านั่นคือสิ่งที่ฉันกำลังสาธิต ประเด็นของคุณคืออะไร?
niXar

1

ถ้าฉันเข้าใจคุณคุณต้อง motd ด้วยเหตุผลอื่น แต่ไม่จำเป็นต้อง motd สำหรับการสำรองข้อมูล ในการกำหนดค่าของ sshd ไม่สามารถตั้งค่าโดยผู้ใช้พื้นฐานเท่านั้นทั่วโลก ดังนั้นคุณต้องแก้ปัญหา motd supression ในฝั่งไคลเอ็นต์ แต่ไม่มีความแตกต่างระหว่างข้อความของ motd และข้อความแสดงข้อผิดพลาดของซอฟต์แวร์สำรองข้อมูล ทั้งคู่เป็นข้อความในเทอร์มินัล ทางออกเดียวที่ฉันเห็นเพื่อสร้างความแตกต่างระหว่างข้อความสองนี้จากนั้นกรอง motd ของหนึ่ง เนื่องจากข้อความของซอฟต์แวร์ยากที่จะแก้ไขฉันแนะนำให้แก้ไขข้อความของ motd ตัวอย่างเช่นใส่กรอบ:

*** BEGIN message from the machine room ***

motd message

*** END message from the machine room ***

จากนั้นคุณควรกรองข้อความระหว่างเฟรมและวางลง


1

ทางออกที่นี่:

ในกรณีที่คุณไม่ได้รับผิดชอบเซิร์ฟเวอร์และคุณไม่สามารถเปลี่ยน motd หรือ sshd config ให้ใช้คำสั่งดังต่อไปนี้:

เปลี่ยนเส้นทาง STDERR ไปยัง STDOUT สำหรับคำสั่งระยะไกลเพื่อให้คุณเห็น จากนั้นเปลี่ยนเส้นทาง STDERR ของ ssh ไปที่ / dev / null MOTD ไปที่ STERR และสิ้นสุดใน / dev / null ข้อความมาตรฐานและข้อผิดพลาดจากคำสั่งระยะไกลจะปรากฏขึ้น (เนื่องจากไปที่ STDOUT)

Variant 1 - ถ้าคุณสนใจสถานะทางออกของคำสั่งที่ดำเนินการจากระยะไกล:

ssh remotehost "(remote_command1 && remote_command2; remote_command3) 2>&1" 2>/dev/null || echo SSH connection or remote command failed - either of them returned non-zero exit code $?

ตัวแปร 2 - หากคุณต้องการละเว้นรหัสออกของคำสั่งระยะไกล - เพียงแค่เรียกใช้จริงเป็นคำสั่งระยะไกลล่าสุด

ssh remotehost "(remote_command; true) 2>&1" 2>/dev/null || echo SSH connection failed

ตัวอย่างข้อความผิดพลาด:

ตัวอย่างที่ 1:

ssh remotehost " ล้มเหลว _ remote_command 2> & 1" 2> / dev / null || การเชื่อมต่อ echo SSH ล้มเหลวหรือคำสั่งระยะไกลส่งคืนโค้ดการออกที่ไม่ใช่ศูนย์
 bash: failed_remote_command: ไม่พบคำสั่ง
การเชื่อมต่อ SSH หรือคำสั่งระยะไกลล้มเหลว - ทั้งคู่ส่งคืนรหัสทางออกที่ไม่ใช่ศูนย์ 127

ตัวอย่างที่ 2:

ssh remotehost " ล้มเหลว _ remote_command 2> & 1; true " 2> / dev / null || การเชื่อมต่อ echo SSH ล้มเหลว
 bash: failed_remote_command: ไม่พบคำสั่ง

ตัวอย่าง 3a:

ssh remotehost " ล้มเหลว _ remote_command 2> & 1; true" 2> / dev / null || การเชื่อมต่อ echo SSH ล้มเหลว
 # ไม่มีข้อความปรากฏขึ้น

ตัวอย่าง 3b:

ssh nonexistinghost " ล้มเหลว _ remote_command 2> & 1; true" 2> / dev / null || การเชื่อมต่อ echo SSH ล้มเหลว
 การเชื่อมต่อ SSH ล้มเหลว

0

คุณได้ลองลบข้อความในไฟล์ motd หรือไม่? แค่ความคิด

Hint: /etc/motd

4
เขากล่าวว่าจากฝั่งไคลเอ็นต์จากฝั่งเซิร์ฟเวอร์ตั้งค่า PrintMotd ไม่มีใน sshd_config อาจจะดีกว่า
ไคล์ Brandt

0

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


โอ้เช่น ฉันต้องการจริงๆค่อนข้างใช้ความคิด SSH ..
Rory

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