Bagaimana cara menentukan apakah saya masuk melalui SSH?

17

Saat ini saya sedang menyiapkan konfigurasi bash yang cukup kompleks yang harus digunakan pada banyak mesin. Saya mencoba mencari tahu apakah mungkin untuk menentukan apakah saya masuk melalui SSH atau pada mesin lokal. Dengan cara ini saya bisa, misalnya, menetapkan beberapa alias tergantung pada fakta itu. Seperti aliasing haltuntuk restartsejak berhenti server jauh mungkin bukan hal terbaik untuk dilakukan.

Yang saya tahu sejauh ini adalah, bahwa variabel lingkungan SSH_CLIENTdiatur ketika saya masuk melalui ssh. Sayangnya, variabel ini dibuang ketika saya memulai shell pengguna super sudo -s. Saya juga tahu bahwa saya bisa mengirimkan parameter ke sudo yang memerintahkan sudo untuk menyalin semua variabel lingkungan saya ke lingkungan shell baru, tetapi jika saya tidak ingin melakukan ini, apakah ada cara lain?

t6d
sumber

Jawaban:

14

Anda bisa menggunakan output perintah "w" atau "who". Ketika Anda terhubung melalui ssh, mereka akan menunjukkan IP sumber Anda.

facha
sumber
1
Buat tebakan yang terpelajar. Sebagai contoh, jalankan ps afxdan TTY untuk shell tidak berjalan psakan menjadi login lainnya.
Warner
6
Gunakan who am i.
Paul Tomblin
1
"uname -n" akan memberi Anda nama host
Hubert Kario
1
Pertanyaannya tampaknya lebih terkait untuk mengekstraknya who am i, sehingga Anda dapat menentukan dari sana apakah Anda SSHing atau tidak. Ini bekerja:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed
4
@ PaulTomblin Sebenarnya, Anda dapat menggunakan whodua argumen tambahan apa pun. who am isama dengan who is meatau who is awesomeatau who potato potato. Sebuah fakta yang saya temukan sedikit menarik.
kirkpatt
9

Inilah jawaban yang bagus yang saya temukan di unix.stackexchange :


  • Jika salah satu variabel SSH_CLIENTatau SSH_TTYdidefinisikan, ini adalah sesi ssh.
  • Proses induk shell login dapat diperiksa ps -o comm= -p $PPID. Jika ya sshd, ini adalah sesi 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
Nicole
sumber
Tidak bekerja untuk sudo -s
Matt
6

Anda dapat menambahkan SSH_*ke env_keepdalam sudoerssehingga ini dapat dideteksi saat beralih ke pengguna lain.

Ignacio Vazquez-Abrams
sumber
4

Jika Anda ingin tahu apakah Anda bash shell secara langsung merupakan proses anak dari sshd (tidak dalam> 1 lapisan) Anda dapat

cat / proc / $ PPID / status | kepala -1 | potong -f2

itu akan memberi Anda sshdatau apa pun nama proses induk dari shell Anda saat ini.

rhlee
sumber
Tidak bekerja untuk sudo -s
Matt
ps -o cmd= $PPIDatauawk '/^Name:/ {print $2}' /proc/$PPID/status
Enam
3

Saya pikir Anda ingin memikirkan kembali cara Anda memikirkan masalahnya. Pertanyaannya bukan "apakah saya masuk melalui SSH, karena saya ingin mematikan perintah tertentu." "Saya masuk di konsol, karena dengan begitu saya akan mengaktifkan perintah tertentu."

Andy Lester
sumber
3

Ya, seperti yang dicatat orang lain, info ada di hadapan IP Anda dalam tanda kurung di output who am i.

Anda dapat menggunakan ekspresi reguler Bash untuk mendeteksinya:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
mivk
sumber
1
Itu juga bisa menjadi nama host.
blueyed
Tidak berfungsi jika nama host berisi angka.
YoYoYonnY
1

Saya datang dengan yang berikut, berdasarkan tips dari orang lain di sini.

Ini menggunakan variabel untuk caching - Saya menggunakannya dalam tema shell saya.

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
}

Sumber: is_sshdi https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .

kebiru-biruan
sumber
0

Cari cmdline induk dan perulangan Anda. Mungkin sesuatu seperti yang berikut ini:

#!/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__
`

Diedit agar benar-benar berfungsi :)

Justin
sumber
0

Semua jawaban lain berfungsi jika Anda berada di tingkat login pertama. Tetapi jika, setelah login, Anda menjalankan 'su' atau 'sudo' (dalam kasus saya, untuk beralih ke akun pengguna tanpa shell untuk alasan keamanan, saya harus menjalankan: sudo su - <userid> -s / bin / bash - l) , solusi mereka gagal.

Mengikuti adalah solusi universal; menggunakan pstree, Anda memeriksa sshd sebagai orang tua.

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

Ini adalah output dari egrep, ketika --quiet dihapus. Ini menunjukkan seluruh hierarki yang cocok jika seseorang terhubung dari jarak jauh.

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)
Hans Deragon
sumber
0

Harap diingat bahwa jawaban ini sangat, sangat spesifik untuk Linux.

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

Ini membuat asumsi kunci: proses login tidak akan memiliki TTY yang mengontrol; Anda mungkin ingin memeriksa apakah Anda memiliki TTY yang mengendalikan sebelum menjalankan kode ini (yang, berdasarkan pada kebutuhan Anda, mungkin merupakan taruhan yang aman, toh).

Kode iterates ke atas melalui pohon proses, sampai menemukan proses yang tidak mengendalikan TTY. $initiator_nameakan menjadi nama proses ini ("sshd", misalnya).

Christian Henry
sumber