Sahte terminal aygıtının diğer ucunda kimin olduğunu nasıl bilebiliriz?


26

Eğer bir şey yaparsam:

echo foo > /dev/pts/12

Bazı işlemler bunu foo\ndosya tanıtıcısından ana tarafa kadar okuyacaktır .

Bu sürecin ne olduğunu öğrenmenin bir yolu var mı?

Başka bir deyişle, hangi xterm / sshd / script / screen / tmux / expect / socat ... 'ın diğer ucunda olduğunu nasıl öğrenebilirim /dev/pts/12?

lsof /dev/ptmxbana herhangi bir pty'nin ana tarafında dosya tanımlayıcıları olan işlemleri söyleyecektir. Bir işlemin kendisi ptsname()( TIOCGPTNioctl) kendi fd'sini ana tarafa bağlı olarak slave cihazını bulmak için kullanabilir;

gdb --batch --pid "$the_pid" -ex "print ptsname($the_fd)"

lsofbu haritalamayı oluşturmak için geri gönderilen her pid / fd için, ancak bu bilgiyi edinmenin daha doğrudan, güvenilir ve daha az müdahaleci bir yolu var mı?


İstediğin bu mu? sudo find /proc/*/fd/0 -ls | grep '/dev/pts/4', PID'lerin ( /proc/PID) listesini çıktı olarak verirdi .
slm

@slm, hayır, başka bir deyişle, hangi xterm / sshd / script / screen / tmux / expect / socat ... 'ın diğer ucunda olduğunu bulmak istiyorum /dev/pts/4. Genellikle, bu /dev/pts/4açık olan ama zorunlu olmayan süreçlerin ortak bir atası olacaktır .
Stéphane Chazelas

1
Soketlerle daha da kötü - bir çekirdek hata ayıklayıcısına ihtiyacınız var!
Gilles 'SO- kötü olmayı bırak'

1
@Falsenames - Sorunun ne anlama geldiğini - belki de yanlış olarak - okuduğum verilerden hangi işlemin geçtiğini değil - terminalde çağrılan ilk kabuk gibi - ama asıl taraftan hangi işlemin okuduğunu anlamadım. Ben de bir kabuk başlatmak Örneğin, screen, öyle screenolduğunu ayırır ve aktif cihazın ömrü boyunca Pty köle yönetir, ama - Bence gibi - kabuk olarak, böylece tty süreç lider yaptı ve sizin Çıktı gösterir, olsun bashya da psolmasın screen. Pid'e dayanarak birkaç tanesini xtermsgeri izledim ama gevşekti. xterm/proc/locks
mikeserv

Yanıtlar:


3

İlk başta bulduğum bilgilere dayanarak ihaleye xtermgeri bir kaç saniye izlemeye çalıştım ama gevşekti. Demek istediğim, işe yaradı bence, ama en iyi koşuldaydı - Dosyanın sağladığı tüm bilgileri tam olarak anlamadım ve sadece içeriği ve bilinen terminal işlemleri arasında karşılık gelen görünüme uyuyordu.xterm/proc/locks

Sonra ptys arasında lsof/straceaktif bir write/talksüreç izlemeye çalıştım . Daha önce hiç bir programı kullanmamıştım, ancak güveniyorlardı utmp. Hedef kitlemin utmpherhangi bir sebepten dolayı girişi yoksa, ikisi de var olduğunu kabul etmeyi reddetti. Belki bunun bir yolu vardır, ama onu bırakacak kadar kafam karıştı.

udevadm136 ve 128 büyük sayıdaki cihaz düğümleriyle keşfedilen ptsve ptmsırasıyla reklamı yaptığım bazı keşifleri denedim /proc/tty/drivers, ancak aynı zamanda bu araçla ilgili çok yararlı bir deneyimim olmadı ve bir kez daha önemli bir şey ortaya çıktı. İlginçtir, yine de, :minher iki cihaz türünün de bir şaşırtıcıda listelendiğini fark ettim 0-1048575.

Bu çekirdek dokümanı tekrar ziyaret edene kadar , sorun hakkında mounts açısından düşünmeye başladım . Daha önce birkaç kez okumuştum, ancak bu doğrultuda araştırmalar sürdüğü zaman beni bu 2012 /dev/ptsyamalı setine yönlendirdi :

sudo fuser -v /dev/ptmx

Düşündüm Genellikle bir ile ilişkilendirmek süreçlere ne kullanıyorsunuz mount? Ve elbette:

                     USER        PID ACCESS COMMAND
/dev/ptmx:           root      410   F.... kmscon
                     mikeserv  710   F.... terminology

Yani bu bilgilerle, örneğin terminology:

sudo sh -c '${cmd:=grep rchar /proc/410/io} && printf 1 >/dev/pts/0 && $cmd'
###OUTPUT###
rchar: 667991010
rchar: 667991011

Gördüğünüz gibi, biraz kesin bir testle, keyfi bir pty'nin usta sürecini oldukça güvenilir bir şekilde çıkarmak için böyle bir işlem yapılabilir. Soketler ile ilgili socatolarak, bir hata ayıklayıcının aksine kullanmanın o yönden yaklaşabileceğinden oldukça eminim , ancak henüz nasıl düzelttim. Yine de, ssbenden daha aşinaysanız yardımcı olabileceğinden şüpheleniyorum :

sudo sh -c 'ss -oep | grep "$(printf "pid=%s\n" $(fuser /dev/ptmx))"'

Bu yüzden, biraz daha açık testlerle ayarlamıştım, aslında:

sudo sh <<\CMD
    chkio() {
        read io io <$1
        dd bs=1 count=$$ </dev/zero >$2 2>/dev/null
        return $((($(read io io <$1; echo $io)-io)!=$$))
    }
    for pts in /dev/pts/[0-9]* ; do
        for ptm in $(fuser /dev/ptmx 2>/dev/null)
            do chkio /proc/$ptm/io $pts && break
        done && set -- "$@" "$ptm owns $pts"
    done
    printf %s\\n "$@"
 CMD

Bu yazdırır $$num \0her pty ve çekler bir önceki çek karşı her ana sürecin io kadar boş bayt. Eğer fark ise $$, pid'i pty ile ilişkilendirir. Bu daha çok işe yarıyor. Yani, benim için geri döner:

410 owns /dev/pts/0
410 owns /dev/pts/1
710 owns /dev/pts/2

Hangisi doğru, ama açıkçası, biraz açık saçık. Yani, diğerlerinden biri o zamanlar bir sürü veriyi okuyor olsaydı, muhtemelen özleyecekti. sttyÖnce durdurma ucunu ya da onun gibi bir şeyi göndermek için başka bir çukurdaki modları nasıl değiştireceğimi bulmaya çalışıyorum , böylece düzeltebilirim.


2

Sadece bağlantının kime ait olduğunu ve nereye bağlandıklarını arıyorsanız, kim komutu iyi çalışacaktır.

$ who
falsenames   tty8         Jun 13 16:54 (:0)
falsenames   pts/0        Jun 16 11:18 (:0)
falsenames   pts/1        Jun 16 12:59 (:0)
falsenames   pts/2        Jun 16 13:46 (:0)
falsenames   pts/3        Jun 16 14:10 (:0)
falsenames   pts/4        Jun 16 16:41 (:0)

Ayrıca, o bağlantıda ne dinlediğini bilmek istersen , sonunda w bunu gösterir.

$ w
 16:44:09 up 2 days, 23:51,  6 users,  load average: 0.26, 0.98, 1.25
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
falsenames   tty8     :0               Fri16    2days 53:36   0.59s x-session-manager
falsenames   pts/0    :0               11:18    5:25m  1:10   1:10  synergys -a 10.23.8.245 -c .synergy.conf -f -d DEBUG
falsenames   pts/1    :0               12:59    3:44m  0.05s  0.05s bash
falsenames   pts/2    :0               13:46    2:52m  0.11s  0.11s bash
falsenames   pts/3    :0               14:10    2:17   0.07s  0.07s bash
falsenames   pts/4    :0               16:41    1.00s  0.04s  0.00s w

Ve yardım almak için, bakmakta olduğunuz tty oturumu için bir ps sınırlayın. Başlamak için tamamen göze çarpmayan.

$ ps -t pts/0 --forest 
  PID TTY          TIME CMD
23808 pts/0    00:00:00 bash
23902 pts/0    00:03:27  \_ synergys

Bunun zamanlamaya bağlı olarak kırmızı ringalara neden olabileceğini unutmayın. Ama başlamak için iyi bir yer.

$ tty
/dev/pts/4
$ ps -t pts/4 --forest
  PID TTY          TIME CMD
27479 pts/4    00:00:00 bash
 3232 pts/4    00:00:00  \_ ps
27634 pts/4    00:00:00 dbus-launch

Teşekkürler, ama aradığım şey bu değil. Örneğin, /dev/pts/4bu wkomutu koştuğunuz yere karşılık gelen terminal uygulamasının (Xterm / gnome-terminal ...) yardımcısını bulmak istiyorum .
Stéphane Chazelas

Üzgünüz, ilk kez tararken pid bölümünü tamamen kaçırdım. Sadece son işlem adını bilmek istediğini sanıyordum.
Falsenames

2

Qemu ile aynı problemi yaşadım ve sonunda çok kötü bir çözüm buldum (ama yine de bir çözüm): İşlem hafızasını ayrıştırma.

Bu burada çalışıyor çünkü qemu'nun uzak pts'i belirli bir formatta bir dizgide sakladığını ve öbek üzerinde tahsis edildiğini biliyorum. Diğer durumlarda da birkaç değişiklikle ve pideyi kaynaştırıcı çıkışından tekrar kullanarak çalışabilir (diğer cevabı kontrol edin).

Kod buradan uyarlanmıştır .

#! /usr/bin/env python

import sys
pid = sys.argv[1]

import re
maps_file = open("/proc/" + pid + "/maps", 'r')
mem_file = open("/proc/" + pid + "/mem", 'r', 0)
for line in maps_file.readlines():
    # You may want to remove the 'heap' part to search all RAM
    m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r]).*\[heap\]', line)
    if m and m.group(3) == 'r':
        start = int(m.group(1), 16)
        end = int(m.group(2), 16)
        mem_file.seek(start)
        chunk = mem_file.read(end - start)
        # You may want to adapt this one to reduce false matches
        idx = chunk.find("/dev/pts/")
        if idx != -1:
            end = chunk.find("\0", idx)
            print chunk[idx:end]
maps_file.close()
mem_file.close()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.