ฉันจะลงชื่อเข้าใช้ผ่าน SSH ได้อย่างไร


17

ขณะนี้ฉันกำลังตั้งค่าการกำหนดค่า bash ที่ค่อนข้างซับซ้อนซึ่งจะใช้กับเครื่องหลายเครื่อง ฉันพยายามที่จะตรวจสอบว่ามันเป็นไปได้ที่จะตรวจสอบว่าฉันเข้าสู่ระบบผ่านทาง SSH หรือบนเครื่องท้องถิ่น เช่นนี้ฉันสามารถตั้งค่านามแฝงบางอย่างขึ้นอยู่กับความจริงที่ว่า เช่นเดียวกับ aliasing haltการrestartตั้งแต่หยุดเซิร์ฟเวอร์ระยะไกลไม่อาจจะเป็นสิ่งที่ดีที่สุดที่จะทำ

สิ่งที่ฉันรู้จนถึงตอนนี้คือตัวแปรสภาพแวดล้อมSSH_CLIENTถูกตั้งค่าเมื่อฉันเข้าสู่ระบบผ่านทาง ssh แต่น่าเสียดายที่ตัวแปรนี้จะถูกยกเลิกเมื่อฉันเริ่มต้นเปลือกใช้ super sudo -sกับ ฉันก็รู้ว่าฉันสามารถส่งพารามิเตอร์ไปยัง sudo ที่สั่งให้ sudo เพื่อคัดลอกตัวแปรสภาพแวดล้อมทั้งหมดของฉันไปยังสภาพแวดล้อมเชลล์ใหม่ แต่ถ้าฉันไม่ต้องการทำสิ่งนี้จะมีวิธีอื่นหรือไม่?

คำตอบ:


14

คุณสามารถใช้เอาต์พุตคำสั่ง "w" หรือ "who" เมื่อคุณเชื่อมต่อผ่าน ssh พวกเขาจะแสดง IP ต้นทางของคุณ


1
ทำการทายผลการศึกษา ตัวอย่างเช่นการรันps afxและ TTY สำหรับเชลล์ที่ไม่ได้ทำงานpsจะเป็นการเข้าสู่ระบบอื่น
วอร์เนอร์

6
who am iใช้
Paul Tomblin

1
"uname -n" จะให้ชื่อโฮสต์แก่คุณ
Hubert Kario

1
ดูเหมือนว่าคำถามจะเกี่ยวข้องกับการดึงข้อมูลออกมาwho am iเพื่อให้คุณสามารถพิจารณาได้จากที่นั่นหากคุณเป็น SSHing หรือไม่ งานนี้:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed

4
@PaulTomblin จริงๆแล้วคุณสามารถใช้whoกับอาร์กิวเมนต์พิเศษสองตัว who am iเป็นเช่นเดียวกับwho is meหรือหรือwho is awesome who potato potatoความจริงฉันพบว่าน่าสนใจเล็กน้อย
kirkpatt

9

นี่คือคำตอบที่ดีที่ฉันพบในunix.stackexchange :


  • หากหนึ่งในตัวแปรSSH_CLIENTหรือSSH_TTYกำหนดไว้มันเป็นเซสชัน ssh
  • กระบวนการหลักของล็อกอินเชลล์สามารถตรวจสอบps -o comm= -p $PPIDได้ ถ้าเป็นsshdมันคือเซสชั่น ssh
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
  SESSION_TYPE=remote/ssh
else
  case $(ps -o comm= -p $PPID) in
    sshd|*/sshd) SESSION_TYPE=remote/ssh;;
  esac
fi

ไม่ทำงานสำหรับ sudo -s
แมตต์

6

คุณสามารถเพิ่มSSH_*การenv_keepในsudoersเพื่อที่ว่านี้สามารถตรวจพบได้ในขณะที่เปลี่ยนไปของผู้อื่น


4

หากคุณต้องการทราบว่าคุณทุบตีเปลือกเป็นกระบวนการลูกของ sshd โดยตรง (ไม่ n> 1 ชั้นลึก) คุณสามารถ

cat / proc / $ PPID / สถานะ | หัว -1 | ตัด -f2

มันควรให้คุณsshdหรืออะไรก็ตามที่เป็นชื่อกระบวนการหลักของเชลล์ปัจจุบันของคุณ


ไม่ทำงานสำหรับ sudo -s
แมตต์

ps -o cmd= $PPIDหรือawk '/^Name:/ {print $2}' /proc/$PPID/status
หก

3

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


3

ใช่เป็นคนอื่นสังเกตเห็นข้อมูลที่อยู่ในการปรากฏตัวของ IP who am iของคุณในวงเล็บในการส่งออกของ

คุณสามารถใช้นิพจน์ทั่วไปของ Bash เพื่อตรวจจับได้:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi

1
มันอาจเป็นชื่อโฮสต์ได้
blueyed

ไม่ทำงานหากชื่อโฮสต์มีตัวเลข
YoYoYonnY

1

ฉันคิดวิธีต่อไปนี้ตามเคล็ดลับจากคนอื่นที่นี่

มันใช้ตัวแปรสำหรับแคช - ฉันใช้มันในธีมเชลล์ของฉัน

is_ssh() {
    (( $+SSH_CLIENT )) && return
    if ! (( $+_ZSH_IS_SSH )); then
        # "who am i" displays current user from utmp(5).  This will be empty for
        # a "normal" terminal.  With Konsole, it is ":0" for display :0,
        # for ssh it is the hostname and with tmux sth like "tmux(PID).ID".
        local whoami="$(who am i)"}
        local host="${whoami#*\(*}"
        [[ -n $host && $host != tmux* && $host != :* ]]
        _ZSH_IS_SSH=$?
    fi
    return $_ZSH_IS_SSH
}

ที่มา: is_sshในhttps://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63


0

มองหา cmdline หลักของเชลล์และเรียกคืน อาจจะเป็นสิ่งต่อไปนี้:

#!/usr/bin/env bash

## Find out how I'm logged in
# Tested on RHEL5.5

PD=${1:-$$}
ME=`basename $0`

## Read the shell's PPID
PAR=`ps --no-headers -p $PD -o ppid`

## CMDLINE can contain stuff like the following:
# /sbin/getty-838400tty4 // logged in at a console
# gnome-terminal         // logged in Gnome Terminal
# -bash                  // in a subshell
# su-                    // we became another user using su
# sshd: jc@pts/1         // logged in over ssh
# login                  // logged in terminal or serial device

eval `python - << __EOF__
import re
f = open("/proc/${PAR}/cmdline", 'r')
ln = f.readline()
if re.search(r'^ssh', ln): 
    print "echo Logged in via ssh"
if re.search(r'getty.*?tty', ln):
    print "echo Logged in console"
if re.search("gnome-terminal", ln):
    print "echo Logged in Gnome"
if re.search(r'^login', ln):
    print "echo Logged in console"
if re.search(r'^-?bash', ln) or re.search(r'^su', ln): 
    print "./$ME $PAR"
f.close()
__EOF__
`

แก้ไขเพื่อให้ใช้งานได้จริง :)


0

คำตอบอื่น ๆ ทั้งหมดจะทำงานหากคุณอยู่ในระดับแรกของการเข้าสู่ระบบ แต่ถ้าเมื่อเข้าสู่ระบบคุณเรียกใช้ 'su' หรือ 'sudo' (ในกรณีของฉันเพื่อสลับไปยังบัญชีผู้ใช้ที่ไม่มีเชลล์เพื่อเหตุผลด้านความปลอดภัยฉันต้องเรียกใช้: sudo su - <userid> -s / bin / bash - l)การแก้ปัญหาล้มเหลว

ต่อไปนี้เป็นทางออกสากล ใช้ pstree คุณตรวจสอบ sshd เป็นผู้ปกครอง

if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then
  echo "I am remote."
else
  echo "I am local."
fi

นี่คือผลลัพธ์ของ egrep เมื่อ - เงียบถูกลบออก มันแสดงลำดับชั้นทั้งหมดที่ตรงกับถ้ามีการเชื่อมต่อจากระยะไกล

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)

0

กรุณาเก็บไว้ในใจว่าคำตอบนี้เป็นอย่างมากมากลินุกซ์ที่เฉพาะเจาะจง

parent_pid=$$
while [[ -z "${tty_bits-}" || $tty_bits -ne 0 ]]; do
  read initiator_name parent_pid tty_bits < <(
    awk '{ print substr($2, 2, length($2) - 2) " " $4 " " $7 }' /proc/$parent_pid/stat
  )
done

echo $initiator_name

นี่เป็นข้อสันนิษฐานที่สำคัญกระบวนการเข้าสู่ระบบจะไม่มีการควบคุม TTY คุณอาจต้องการตรวจสอบว่าคุณมีการควบคุม TTY ก่อนที่จะเรียกใช้รหัสนี้หรือไม่ (ซึ่งตามความต้องการของคุณ

รหัสวนซ้ำผ่านทรีกระบวนการจนกระทั่งพบกระบวนการที่ไม่มีการควบคุม TTY $initiator_nameจะเป็นชื่อของกระบวนการนี้ ("sshd" เป็นต้น)

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