現在のsshセッションの発信元IPアドレスを見つけようとしています。私は次のことが有用であることがわかりましたが、それにはSudoが必要です。
$ Sudo netstat -tapen | grep ssh | awk '{ print $5}' | sed '/0.0.0.0\|::/d'
192.168.1.1:60119
99.xxx.xxx.xxx:1213
Sudoを呼び出さずに99.xxx.xxx.xxx情報を取得する方法はありますか?
(回答!質問#1:grepにパイプするとエラーのみが返されるのはどうですか?)
質問#2:netstatでWAN情報を取得するための回避策はありますか?または...
質問#3:私の目標により良い選択肢はありますか?
1と2への回答
警告はnetstat
からのものであり、grep
およびnetstat
出力のPID/Program name
列に関するものではありません。
$ netstat -tapen
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
Sudo
の使用:
$ Sudo netstat -tapen
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
アラートは自明です。他の(すべての)ユーザーが所有するプロセスIDとプログラム名を表示するにはroot
である必要があります。そうでない場合、オープンソケットリストを取得しますが、所有しているプログラムのPID /名前のみを取得しますそれらのプロセス。
区別は、基本的にman netstat
から次のように要約されます。
PID/Program name
Slash-separated pair of the process id (PID) and process name of
the process that owns the socket. --program causes this column to
be included. You will also need superuser privileges to see this
information on sockets you don't own. This identification information is
not yet available for IPX sockets.
あなたの場合、プログラムsshd
はroot
によって所有されているので、Sudo
を使用しないと、プログラム名とPIDではなく、すべてのソケット情報が出力に表示されます。その結果、netstat -taepn
の結果にgrep
を使用しているときに、警告が表示されます。
一方、Sudo
を使用すると、PID /プログラム名がnetstat -taepn
出力に表示され、grep
を使用して出力を見つけることができます。
以下により、明確になります(最後の列(PID /プログラム名)を確認してください):
$ netstat -tapen
PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 11088 -
$Sudo netstat -taepn
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 11088 1002/sshd
これをクライアントマシンから実行している場合は、無視できます。その場合のプロセスはssh
(sshd
ではなく)であり、所有者です。
への回答
たくさんの方法があります。いくつか追加します。
$ Sudo netstat -taepn | grep "ssh" | tr -s ' ' | cut -d' ' -f4 | head -1
192.168.5.3:22
$ Sudo netstat -taepn | grep -Po "\b(\d|\.)+:22(?= .*ssh)"
192.168.5.3:22
$ Sudo netstat -taepn | sed -nr '/ssh/s/.* ([^:]+:22) .*/\1/p'
192.168.5.3:22
編集:Sudo
なし:
$ netstat -taepn 2>/dev/null | grep ":22 " | tr -s ' ' | cut -d' ' -f4 | head -1
192.168.5.3:22
$ netstat -taepn 2>/dev/null | grep -Po "\b(\d|\.)+:22\b"
192.168.5.3:22
$ netstat -taepn 2>/dev/null | sed -nr '/:22 /s/.* ([^:]+:22) .*/\1/p'
192.168.5.3:22
編集2:
ssh
を使用せずにサーバーのポート22(Sudo
)に接続されたリモートIPアドレスを取得する場合、ss
コマンドを使用してソケット統計を読み取り、そこから目的の出力を取得するのが最善です。
$ ss -ant | grep -Po "(\d|\.)+:22\s+\K[^:]+"
192.168.6.4
$ ss -ant | sed -nr 's/.*([0-9]|\.)+:22 +([^:]+).*/\2/p'
192.168.6.4
$ ss -ant | grep -e "ESTAB" | grep ":22" | tr -s ' ' | cut -d' ' -f5 | cut -d':' -f1
192.168.6.4
サーバーで上記のコマンドを実行しました。192.168.6.4
は、ポート22でssh
を介してサーバーに接続されたリモートコンピューターのIPアドレスです。
SSH_CONNECTION
およびSSH_CLIENT
変数を使用できます。
$ echo $SSH_CONNECTION
10.0.0.1 42276 10.0.0.2 22
$ echo $SSH_CLIENT
10.0.0.1 42276 22
$ SSH_IP=${SSH_CONNECTION%% *}
$ echo $SSH_IP
10.0.0.1
man 1 ssh
から:
SSH_CONNECTION Identifies the client and server ends of the
connection. The variable contains four space-
separated values: client IP address, client port
number, server IP address, and server port number.
Bash配列に分割すると、SSH_CONNECTION
の各エントリに簡単にアクセスできます。
ssh_details=($SSH_CONNECTION)
次に、そのインデックスを使用して各エントリを取得できます。
$ echo $SSH_CONNECTION
127.0.0.1 55719 127.0.0.1 22
$ ssh_details=($SSH_CONNECTION)
$ echo ${ssh_details[0]}
127.0.0.1
$ echo ${ssh_details[1]}
55719
$ printf "You are logging in from Host IP %s from port # %d\n" ${ssh_details[0]} ${ssh_details[1]}
You are logging in from Host IP 127.0.0.1 from port # 55719
何らかの理由で、SSH_CLIENT
は英語のマンページに記載されていません。
行はエラー出力へのベロログ、つまりsterr
です。あなたはそれを取り除くことができます
netstat -tapen 2> /dev/null | grep ssh
参考に チェックしてください
Sudo
なしのheemaylで適切に指摘されているように、netstatは、sshクライアントによって確立された場合にのみ、sshサーバーによって接続が確立されたことを報告しません。
もちろん、ポート番号またはログインとアドレスを表示するwho -a
ユーティリティを使用して決定することはできますが、Telnetまたはリモートデスクトップアプリケーションを介して誰かがログインしていないという保証はありません。
SSH_CLIENTの回答を読む前に(ご存知のとおり簡単です)、次のこともできます。
pid=$(ps -xh -o pid,cmd | grep [s]shd | awk '{print $1}' | head -1)
cat /proc/$pid/net/tcp | while read a b c d e; do echo $b $c $d; done |
tail -n +2 | grep " 01" | while read a b c; do echo $b; done |
cut -d: -f1 | sed "s/../& /g" | while read d c b a; do
printf "%d.%d.%d.%d\n" 0x$a 0x$b 0x$c 0x$d; done
実際には、プロセスには、自分のクライアントだけでなく、すべてのクライアントの接続が含まれています。基本的にメインのSSHDプロセスです。ユーザーの下で実行される理由がわかりません。