Làm cách nào để xác định xem tôi đã đăng nhập qua SSH chưa?


17

Tôi hiện đang thiết lập một cấu hình bash khá phức tạp sẽ được sử dụng trên nhiều máy. Tôi cố gắng tìm hiểu xem có thể xác định xem tôi đã đăng nhập qua SSH hoặc trên máy cục bộ hay không. Bằng cách này, tôi có thể, ví dụ, đặt một số bí danh tùy thuộc vào thực tế đó. Giống như răng cưa haltđể restarttừ dừng một máy chủ từ xa có thể không phải là điều tốt nhất để làm.

Những gì tôi biết cho đến nay là, biến môi trường SSH_CLIENTđược đặt khi tôi đăng nhập qua ssh. Thật không may, biến này bị loại bỏ khi tôi bắt đầu một siêu người dùng với sudo -s. Tôi cũng biết rằng tôi có thể truyền tham số cho sudo để hướng dẫn sudo sao chép tất cả các biến môi trường của tôi sang môi trường shell mới, nhưng nếu tôi không muốn làm điều này, có cách nào khác không?

Câu trả lời:


14

Bạn có thể sử dụng đầu ra lệnh "w" hoặc "who". Khi bạn kết nối qua ssh, họ sẽ hiển thị IP nguồn của bạn.


1
Hãy đoán. Ví dụ: chạy ps afxvà TTY cho shell không chạy pssẽ là thông tin đăng nhập khác.
Warner

6
Sử dụng who am i.
Paul Tomblin

1
"uname -n" sẽ cung cấp cho bạn tên máy chủ
Hubert Kario

1
Câu hỏi dường như có liên quan nhiều hơn để trích xuất nó từ đó who am i, để bạn có thể xác định từ đó nếu bạn có SSH hay không. Điều này hoạt động:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed

4
@PaulTomblin Trên thực tế, bạn có thể sử dụng whovới bất kỳ hai đối số bổ sung nào. who am igiống who is mehoặc who is awesomehoặc who potato potato. Một thực tế tôi thấy một chút thú vị.
kirkpatt

9

Đây là một câu trả lời tuyệt vời tôi tìm thấy trên unix.stackexchange :


  • Nếu một trong các biến SSH_CLIENThoặc SSH_TTYđược xác định, đó là phiên ssh.
  • Quá trình cha của shell đăng nhập có thể được kiểm tra với ps -o comm= -p $PPID. Nếu có sshd, đó là một phiên 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

Không hoạt động cho sudo -s
Matt

6

Bạn có thể thêm SSH_*vào env_keeptrong sudoersđể điều này có thể được phát hiện trong khi chuyển sang người dùng khác.


4

Nếu bạn muốn biết nếu bash shell của bạn trực tiếp là một quá trình con của sshd (không phải n> 1 lớp sâu), bạn có thể

mèo / Proc / $ PPID / trạng thái | đầu -1 | cắt -f2

nó sẽ cung cấp cho bạn sshdhoặc bất cứ tên nào là tên tiến trình cha của shell hiện tại của bạn.


Không hoạt động cho sudo -s
Matt

ps -o cmd= $PPIDhoặcawk '/^Name:/ {print $2}' /proc/$PPID/status
Sáu

3

Tôi nghĩ rằng bạn muốn suy nghĩ lại về cách bạn nghĩ về vấn đề. Câu hỏi không phải là "tôi đã đăng nhập qua SSH, vì tôi muốn tắt một số lệnh nhất định." Đó là "tôi đã đăng nhập tại bàn điều khiển, vì sau đó tôi sẽ kích hoạt một số lệnh nhất định."


3

Có, như những người khác lưu ý, thông tin có sự hiện diện của IP của bạn trong ngoặc đơn ở đầu ra của who am i.

Bạn có thể sử dụng biểu thức chính quy Bash để phát hiện nó:

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

1
Nó cũng có thể là một tên máy chủ.
xanh

Không hoạt động nếu tên máy chủ chứa số.
YoYoYonnY

1

Tôi đã đưa ra những điều sau đây, dựa trên những lời khuyên từ những người khác ở đây.

Nó sử dụng một biến để lưu vào bộ đệm - tôi đang sử dụng nó trong chủ đề shell của mình.

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
}

Nguồn: is_sshtrong https://github.com/blueyed/oh-my-zsh/blob/master/theme/blueyed.zsh-theme#L51-63 .


0

Tìm kiếm cmdline cha của shell của bạn và tái diễn. Có thể một cái gì đó như sau:

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

Chỉnh sửa để làm cho nó thực sự hoạt động :)


0

Tất cả các câu trả lời khác hoạt động nếu bạn ở cấp đăng nhập đầu tiên. Nhưng nếu, sau khi đăng nhập, bạn chạy 'su' hoặc 'sudo' (trong trường hợp của tôi, để chuyển sang tài khoản người dùng không có vỏ vì lý do bảo mật, tôi phải chạy: sudo su - <userid> -s / bin / bash - l) , giải pháp của họ thất bại.

Sau đây là một giải pháp phổ quát; sử dụng pstree, bạn kiểm tra sshd với tư cách là cha mẹ.

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

Đây là đầu ra của egrep, khi --quiet bị xóa. Nó hiển thị toàn bộ hệ thống phân cấp phù hợp nếu một được kết nối từ xa.

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

0

Xin lưu ý rằng câu trả lời này rất, rất cụ thể về 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

Điều này đưa ra một giả định chính: quá trình đăng nhập sẽ không có TTY kiểm soát; bạn có thể muốn kiểm tra xem bạn TTY kiểm soát hay không trước khi chạy mã này (điều này, dựa trên yêu cầu của bạn, dù sao, có lẽ là đặt cược an toàn).

Mã lặp đi lặp lại lên trên qua cây quy trình, cho đến khi tìm thấy quy trình không có TTY kiểm soát. $initiator_namesẽ là tên của quá trình này ("sshd" chẳng hạn).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.