ค้นหาที่อยู่ IP ของลูกค้าในเซสชัน SSH


166

ฉันได้สคริปต์ที่เป็นที่จะต้องดำเนินการโดยบุคคลที่บันทึกในเซิร์ฟเวอร์ด้วยSSH

มีวิธีการค้นหาโดยอัตโนมัติที่อยู่ IP ที่ผู้ใช้เชื่อมต่อจากอะไร

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


5
เสนอที่จะย้ายไป ServerFault ยังคงคำถามที่ดีแม้ว่า
BozoJoe

คำตอบ:


267

ตรวจสอบว่ามีตัวแปรสภาพแวดล้อมที่เรียกว่า:

$SSH_CLIENT 

หรือ

$SSH_CONNECTION

(หรือตัวแปรสภาพแวดล้อมอื่น ๆ ) ซึ่งได้รับการตั้งค่าเมื่อผู้ใช้เข้าสู่ระบบจากนั้นดำเนินการโดยใช้สคริปต์การเข้าสู่ระบบของผู้ใช้

แยก IP:

$ echo $SSH_CLIENT | awk '{ print $1}'
1.2.3.4
$ echo $SSH_CONNECTION | awk '{print $1}'
1.2.3.4

@cwd ฉันต้องการแทนที่ ip ในคำสั่งนี้ "iptables -A INPUT -s 93.203.118.251 -p tcp --destination-port 443 -j DROP" เป็นไปได้หรือไม่
wutzebaer

2
นี่คือ REMOTEHOST สำหรับฉัน
dramzy

5
ใช้ได้กับผู้ใช้ที่ไม่ใช่ sudoed เท่านั้น เช่นถ้าคุณมีผู้ใช้ ssh แล้วเลื่อนระดับเป็นรูทเชลล์ใหม่จะถูกสร้างขึ้นและตัวแปรเหล่านี้จะหายไปเว้นแต่ว่าคุณสามารถสืบค้นกลับผ่านต้นไม้เพื่อค้นหา ssh pid ดั้งเดิมและรับตัวแปรจาก / proc / $ PID / environ
Andrej

5
ขอบคุณstackoverflow.com/questions/428109/extract-substring-in-bashคำตอบนี้สามารถปรับปรุงให้ง่ายขึ้น${SSH_CLIENT%% *}
Jeff

@ Andrej ดูsudo -E
Jeff

105

คุณสามารถใช้คำสั่ง:

server:~# pinky

ที่จะให้คุณบางอย่างเช่นนี้:

Login      Name                 TTY    Idle   When                 Where 

root       root                 pts/0         2009-06-15 13:41     192.168.1.133

13
นั่นมันยอดเยี่ยม :-) Nerd humor ftw อีกครั้ง อ้างอิงจากpinky --help:A lightweight 'finger' program; print user information. The utmp file will be /var/run/utmp.
Chris Woods

ทำไม 'Where' ในเอาท์พุทของฉันแสดงเฉพาะชื่อเครื่องไม่ใช่ที่อยู่ IP?
isaganiesteron

อาจเป็นไปได้ว่าคุณได้กำหนดค่าเนมเซิร์ฟเวอร์ในเครื่องของคุณ
vncprado

pinky จะแสดงผู้ใช้ที่ล็อกอินทั้งหมดไม่ใช่แค่ตัวคุณเอง
Andrej

33

ลองต่อไปนี้เพื่อรับที่อยู่ IP:

who am i|awk '{ print $5}'

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

15
who am i! = whoamiบน Linux อย่างน้อย มีสิ่งที่ห้าและเป็นชื่อโฮสต์ของลูกค้า
kbulgrien

5
สำหรับคนอื่นสงสัยเกี่ยวกับwho am iการ manpage สำหรับพูดว่า:who If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual.ดังนั้นทุกอย่างที่มีสองคำทำงานเช่นwho likes icecreamเดียวกัน
jmiserez

3
เมื่อสร้างคำตอบนี้ฉันลดมันลงเพื่อwho -m --ips|awk '{print $5}'ให้มี IP เท่านั้นและไม่มีคำตอบแบบย้อนกลับ ขอบคุณสำหรับความช่วยเหลือwho am i!
วาน

1
ล้มเหลวด้วย tmux: who am i|awk '{ print $5}' (tmux(2445).%3)
Alexx Roche



5
who am i | awk '{print $5}' | sed 's/[()]//g' | cut -f1 -d "." | sed 's/-/./g'


export DISPLAY=`who am i | awk '{print $5}' | sed 's/[()]//g' | cut -f1 -d "." | sed 's/-/./g'`:0.0

ฉันใช้สิ่งนี้เพื่อกำหนดตัวแปร DISPLAY ของฉันสำหรับเซสชันเมื่อเข้าสู่ระบบผ่าน ssh และจำเป็นต้องแสดง X ระยะไกล


มีประโยชน์หนึ่งซับในการเพิ่ม IP ของฉันไปยังไฟล์. htaccess ขอบคุณ. ฉันได้ทำการดัดแปลงสำหรับ FreeBSD: who am i | awk '{print $6}' | sed 's/[()]//g' | sed 's/\./\\./g' ส่วนสุดท้ายหนีจุดต่างๆ
Olivier - ยุ่ง

5

การปรับปรุงคำตอบก่อนหน้า ให้ที่อยู่ ip แทนชื่อโฮสต์ - ไม่สามารถใช้งานริมฝีปากใน OS X

who am i --ips|awk '{print $5}' #ubuntu 14

เป็นสากลมากขึ้นเปลี่ยน $ 5 เป็น $ 6 สำหรับ OS X 10.11:

WORKSTATION=`who -m|awk '{print $5}'|sed 's/[()]//g'`
WORKSTATION_IP=`dig +short $WORKSTATION`
if [[ -z "$WORKSTATION_IP" ]]; then WORKSTATION_IP="$WORKSTATION"; fi
echo $WORKSTATION_IP


2

คุณสามารถรับได้ด้วยวิธีการเขียนโปรแกรมผ่านทางห้องสมุด SSH ( https://code.google.com/p/sshxcute )

public static String getIpAddress() throws TaskExecFailException{
    ConnBean cb = new ConnBean(host, username, password);
    SSHExec ssh = SSHExec.getInstance(cb);
    ssh.connect();
    CustomTask sampleTask = new ExecCommand("echo \"${SSH_CLIENT%% *}\"");
    String Result = ssh.exec(sampleTask).sysout;
    ssh.disconnect();   
    return Result;
}

1

netstat จะทำงาน (ที่ด้านบนบางอย่างเช่นนี้) tcp 0 0 10.x.xx.xx: ssh someipaddress.or.domainame: 9379 ESTABLISHED


ขอบคุณมากสำหรับคำตอบนี้ฉันลงเอยด้วยการทำ 'netstat | grep ssh '
Ross Aiken

ด้วยเหตุผลด้านความปลอดภัยนี่เป็นสิ่งที่ไม่ดีเพราะทุกคนสามารถเชื่อมต่อกับพอร์ตนั้นไม่ใช่แค่คุณ
CrazyCasta

1
netstat -tapen | grep ssh | awk '{ print $10}'

เอาท์พุท:

two # ในการทดลองของฉัน

netstat -tapen | grep ssh | awk '{ print $4}' 

ให้ที่อยู่ IP

เอาท์พุท:

127.0.0.1:22 # in my experiment

แต่ผลลัพธ์จะถูกนำไปผสมกับผู้ใช้และสิ่งของอื่น ๆ มันต้องการงานมากกว่านี้


netstat ของฉันให้เฉพาะที่อยู่ที่ถูกตัดทอนสำหรับ IPv6 และ "127.0.0.1:22" เป็นเซิร์ฟเวอร์แทนที่จะเป็นไคลเอนต์ (ซึ่งระบุไว้ในคำถาม)
Alexx Roche

1

เธรดที่เก่ากว่าพร้อมคำตอบมากมาย แต่ไม่มีสิ่งใดที่ฉันกำลังมองหาดังนั้นฉันจึงมีส่วนร่วมกับฉัน:

sshpid=$$
sshloop=0
while [ "$sshloop" = "0" ]; do
        if [ "$(strings /proc/${sshpid}/environ | grep ^SSH_CLIENT)" ];
then
                read sshClientIP sshClientSport sshClientDport <<< $(strings /proc/${sshpid}/environ | grep ^SSH_CLIENT | cut -d= -f2)
                sshloop=1
        else
                sshpid=$(cat /proc/${sshpid}/status | grep PPid | awk '{print $2}')
                [ "$sshpid" = "0" ] && sshClientIP="localhost" && sshloop=1
        fi
done

วิธีนี้ใช้ได้กับ direct ssh ผู้ใช้ sudoed และเซสชันหน้าจอ มันจะติดตามผ่านแผนผังกระบวนการจนกว่าจะพบ pid ที่มีตัวแปร SSH_CLIENT จากนั้นบันทึก IP เป็น $ sshClientIP ถ้ามันอยู่ห่างจากต้นไม้มากเกินไปมันจะบันทึก IP เป็น 'localhost' และออกจากลูป


0

โดยปกติจะมีรายการบันทึกใน / var / log / messages (หรือคล้ายกันขึ้นอยู่กับระบบปฏิบัติการของคุณ) ซึ่งคุณสามารถ grep ด้วยชื่อผู้ใช้


0

Linux: ฉันคือใคร | awk '{พิมพ์ $ 5}' | sed 's / [()] // g'

AIX: ฉันคือใคร | awk '{พิมพ์ $ 6}' | sed 's / [()] // g'


0

ค้นหาการเชื่อมต่อ SSH สำหรับบัญชี "myusername"

รับสตริงผลลัพธ์แรก

ใช้คอลัมน์ที่ 5

แยกโดย ":" และส่งคืนส่วนที่ 1 (ไม่จำเป็นต้องใช้หมายเลขพอร์ตเราต้องการแค่ IP):

netstat -tapen | grep "sshd: myusername" | หัว -n1 | awk '{แยก ($ 5, a, ":"); พิมพ์ [1]} '


อีกวิธีหนึ่ง:

ฉันคือใคร awk '{l = ความยาว ($ 5) - 2; พิมพ์ย่อย ($ 5, 2, l)} '


sudo ss -tapen | grep "sshd: $(whoami)"|head -n1|awk '{split($5, a, ":"); print a[1]}'กล่าวว่าลูกค้า ssh ของฉันมาจาก2a02และของคุณ "วิธีอื่น:" พูดว่าtmux(2445).%3
Alexx Roche

0

สมมติว่าเขาเปิดเซสชันแบบโต้ตอบ (นั่นคือจัดสรรเทอร์มินัลหลอก ) และคุณมีสิทธิ์เข้าถึง stdin คุณสามารถเรียกใช้ ioctl บนอุปกรณ์นั้นเพื่อรับหมายเลขอุปกรณ์ (/ dev / pts / 4711) และลองค้นหาสิ่งนั้นใน/ var / run / utmp (โดยที่จะมีชื่อผู้ใช้และที่อยู่ IP ที่เชื่อมต่อมาจาก)


0

หนึ่งนิ้วหัวแม่มือสำหรับคำตอบของ @Nikhil Katre:

คำสั่งที่ง่ายที่สุดที่จะได้รับในช่วง 10 last|headผู้ใช้เข้าสู่ระบบในเครื่องอยู่

ในการรับผู้ใช้ทั้งหมดเพียงแค่ใช้lastคำสั่ง

คนที่ใช้whoหรือpinkyทำสิ่งที่ถามโดยทั่วไป แต่ แต่พวกเขาไม่ได้ให้ข้อมูลการประชุมทางประวัติศาสตร์

ซึ่งอาจน่าสนใจถ้าคุณต้องการรู้จักใครบางคนที่เพิ่งเข้าสู่ระบบและออกจากระบบแล้วเมื่อคุณเริ่มการตรวจสอบนี้

ถ้ามันเป็นระบบผู้ใช้หลายคน ฉันแนะนำและเพิ่มบัญชีผู้ใช้ที่คุณกำลังมองหา:

last | grep $USER | head

แก้ไข:

ในกรณีของฉันไม่มีทั้ง $ SSH_CLIENT และ $ SSH_CONNECTION


0

คำสั่งที่ง่ายที่สุดที่จะได้รับในช่วง 10 last|headผู้ใช้เข้าสู่ระบบในเครื่องอยู่ ในการรับผู้ใช้ทั้งหมดเพียงแค่ใช้lastคำสั่ง


0

ฉันได้รับผลลัพธ์ต่อไปนี้จากwho -m --ipsบน Debian 10:

root pts / 0 Dec 4 06:45 123.123.123.123

ดูเหมือนว่ามีการเพิ่มคอลัมน์ใหม่ดังนั้น{print $5}หรือ " ใช้คอลัมน์ที่ 5 " ความพยายามจะไม่ทำงานอีกต่อไป

ลองสิ่งนี้:

who -m --ips | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'

ที่มา:

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