Con Linux iptables, è possibile registrare il nome del processo / comando che avvia una connessione in uscita?


27

Vorrei tenere traccia dei processi che avviano connessioni in uscita su un desktop Linux. Il meglio che posso inventare è questo:

iptables -A OUTPUT -m state --state NEW -j LOG --log-uid

Questo registra l'uid / gid che avvia la connessione, ma non il nome del processo / comando o anche il pid. Se solo potessi ottenere il pid, probabilmente potrei creare uno script che tira il nome del processo quando viene scritto il registro, ma sembra che non sia nemmeno possibile.

Idealmente, vorrei anche registrare i processi che accettano anche le connessioni in entrata.

Qualche idea su come ciò potrebbe essere possibile con iptables [o qualsiasi altra cosa] su un box Linux?


Credo (non del tutto sicuro) che questa domanda abbia avuto una risposta su serverfault, cercala.
niXar,

Personalmente, userei sysdig per questo lavoro.
Charles Duffy,

Risposte:


7

È possibile scrivere un programma per monitorare / proc / net / tcp, il cui output è simile al seguente:

obi-wan ~ # cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847458 1 e6060560 300 0 0 2 -1
   1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847477 1 f2e64da0 300 0 0 2 -1
   2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7109 1 f2e65ac0 300 0 0 2 -1
   3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 4864457 1 d2726540 300 0 0 2 -1
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847462 1 e60609c0 300 0 0 2 -1
   5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000     0        0 4982752 3 f2e64940 55 4 0 2 -1
   6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000  1000        0 2130283 1 d59cce40 21 4 1 2 -1
   7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000  1000        0 2130285 1 d59cd2a0 21 4 0 2 -1
   8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000     0        0 4982629 2 d2727260 40 4 8 2 2
   9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000     0        0 4864416 5 e6061b40 42 12 27 3 -1

È quindi possibile correlare le porte aperte agli inode, che possono essere ricondotti ai processi e ai descrittori di file facendo readlink sui descrittori di file elencati per ciascun processo:

obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]

Vedi qui che l'inode 4847458 corrisponde al primo socket tcp nell'elenco sopra. L'output di netstat -tapn lo verifica per me (e ricorda che 0x50 == 80):

obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     28850/cherokee-work

Quando il programma di monitoraggio rileva una modifica in / proc / net / tcp, analizzare i dati e determinare se la modifica è un socket appena aperto. Quindi potresti semplicemente enumerare tutti i descrittori di file per ogni processo elencato in / proc, facendo readlink su ciascuno su per trovare l'inode corrispondente. Una volta trovato questo, hai il pid proprietario, dal quale puoi ottenere tutto ciò che potresti desiderare, in particolare se hai la contabilità di processo.

Se non è necessario che la notifica sia istantanea, il programma di monitoraggio potrebbe utilizzare un polling lento (forse un periodo di 50ms o 100ms o persino 1000ms).


2
Grazie per aver fornito un'opzione! Ma richiedere il polling e l'interrogazione di ogni descrittore di file aperto ogni volta non è molto robusto ed è molto inefficiente. Spero ancora che qualcuno trovi una soluzione migliore, o chiarisca perché questo non fa più parte di iptables e perché - cmd-owner è ritenuto non risolvibile.
nealmcb,

A meno che il kernel non cambi il suo layout di / proc o che non cambi netstat e readlink o ps (improbabile), direi che è abbastanza robusto. Che tipo di problemi di efficienza ti interessano? Se vuoi un'elaborazione istantanea, dovrai scrivere un modulo del kernel da usare con iptables.
Ben Collins,

Se sto registrando connessioni rifiutate, il socket viene immediatamente distrutto dal kernel, quindi ho pochissime possibilità di vederlo in / proc. Forse cambia solo REJECT in DROP per avere il timeout della connessione ...
Marki555,

Non aiuta in questo scenario a causa della finestra temporale super-piccola, ma per quanto riguarda la fragilità dell'analisi / proc, si potrebbe anche usare "lsof -F -i" e ottenere una discarica della rete ben astratta dati. Questo può anche essere filtrato (diciamo, solo su una porta specifica) e ha già fatto tutto il mapping del nome file / pid / utente per te.
dannysauer,

9

Volete il modulo di corrispondenza proprietario, che funziona solo sulla catena OUTPUT (e forse PREROUTING ...?). Leggi i documenti, ma funzionerà in questo modo:

iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "

1
Un comando di registro iptables può impostare e interpolare una variabile in questo modo? Non sembra funzionare per me. Inoltre, sembra che l'opzione --cmd-owner sia stata rimossa nel kernel> = 2.6.15. Questo è un peccato, perché sembra un'opzione utile.

4
Sì, --cmd-owner è stato rimosso: "unsixable broken"
guettli

1
Grazie per le informazioni, @guettli. Ci sono più dettagli su permalink.gmane.org/… che cita più del log delle modifiche : "[NETFILTER]: rimuovi abuso tasklist_lock nel proprietario ipt {, 6}; strappa la corrispondenza cmd / sid / pid dal momento che non è riparabile e si trova in il modo di bloccare cambia in tasklist_lock. " Ma vorrei ancora un po 'più di background, o alternative migliori.
nealmcb,

5

Niente a che fare con iptables o registrazione; ma qui c'è un'interfaccia simile a "top" che esegue il polling della directory / proc / e mostra la larghezza di banda per programma / pid:

http://sourceforge.net/projects/nethogs

"NetHogs è un piccolo strumento" net top ". Invece di abbattere il traffico per protocollo o per sottorete, come la maggior parte degli strumenti, raggruppa la larghezza di banda per processo. NetHogs non si basa su uno speciale modulo del kernel da caricare."


Ho scoperto che nethogs fornisce statistiche inaffidabili, ma in cima 2 (+ netatop) lo fa bene.
Tobu,

1

Mentre sto esaminando una domanda simile, cercando di limitare la velocità su Skype, ho scoperto

$ netstat -p | grep <mycmdname>

è un buon modo per collegare il numero di porta a pid / cmd, ora che il proprietario del pid / il proprietario del cmd non sono più supportati direttamente in iptables; dovrai quindi analizzare il risultato, quindi aggiungere la regola iptables in base alla porta; naturalmente avrai bisogno di un codice di pulizia in seguito / all'arresto / riavvio del sistema, ecc .; salva il / i numero / i di porta in un file per riferimento al momento della pulizia

in effetti è una buona risposta alla domanda sui numeri di porta

$ sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`

potrebbe essere necessario regolare l'elemento grep tcp in base alle proprie esigenze

quindi per i miei scopi, è stato più semplice aggiungere filtri tc u32 in base ai numeri di porta, voci iptables in base a numeri di porta simili

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.