LINUX.ORG.RU

Запись pid процесса в логах iptables

 


1

1

Всем привет, подскажите по такому вопросу - хочу чтобы все входящие и исходящие соединения iptables выводились в логи, причем с pid'ом процесса, создал в iptables отдельные цепочки в которые передаются цепочки INPUT и OUTPUT, к этим цепочкам применяется действие LOG

:WALL-FORW - [0:0]
:WALL-INPUT - [0:0]
:WALL-OUTPUT - [0:0]
-A INPUT -j WALL-INPUT
-A INPUT -j LOG -m owner --pid-owner 0:65535 --log-level debug --log-prefix "CHAIN=WALL-INPUT-REJECT "
-A FORWARD -j WALL-FORW
-A FORWARD -j LOG  -m owner --pid-owner 0:65535 --log-prefix "CHAIN=WALL-FORW-REJECT "
-A OUTPUT -j WALL-OUTPUT
-A OUTPUT -j LOG  -m owner --pid-owner 0:65535 --log-prefix "CHAIN=WALL-OUTPUT-REJECT "

Но в /var/log/syslog я потом наблюдаю строчки следующего вида:

May 24 20:00:00 user kernel: [16316.803782] CHAIN=WALL-OUTPUT-REJECT IN= OUT=wlan0 SRC=192.168.1.1 DST=210.130.149.177 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=15470 DF PROTO=TCP SPT=443 DPT=443 WINDOW=64240 RES=0x00 SYN URGP=0 

Что только ни пробовал но PID процесса в логи не попадает, как заставить iptables его туда выводить?

Пропатчить ядро? Хотя если вы хотите такую дичь, как pid в цепочке FORWARD, то тут правка кода ядра не поможет.

mky ★★★★★ ()
Ответ на: комментарий от mky

Для forward - это как раз просто - pid = 1.

Для output это можно сделать (свой модуль написать).

Для input это нельзя сделать со 100% достоверностью. Порт может слушать одновременно несколько процессов. На момент приема пакета неизвестно какой процесс его получит.

vel ★★★★★ ()
Ответ на: комментарий от vel

Для forward - это как раз просто - pid = 1.
Для output это можно сделать (свой модуль написать).
Для input это нельзя сделать со 100% достоверностью

Да для output как раз и надо, сразу недосмотрел - да для этого спец.модуль нужен и он уже давно есть - CONFIG_IP_NF_MATCH_OWNER https://www.opennet.ru/docs/RUS/iptables/ только вот где его взять? sudo modprobe CONFIG_IP_NF_MATCH_OWNER мне выдаёт ошибку - модуль ненайден

barmaley99 ()
Ответ на: комментарий от barmaley99

CONFIG_IP_NF_MATCH_OWNER и "-j LOG" почти никак не связаны. Ты же не собираешься писать правила для каждого uid ?

-A OUTPUT -j LOG  -m owner --pid-owner 0:65535 --log-prefix "CHAIN=WALL-OUTPUT-REJECT "

Это каша из тебя сбивает с толку. У тебя вперемешку match и target.

"-A OUTPUT " - это где проверять

"-m owner --pid-owner 0:65535" - это что проверять

'-j LOG --log-prefix «CHAIN=WALL-OUTPUT-REJECT »' - это что делать.

"-j LOG" не знает про uid.

vel ★★★★★ ()
Ответ на: комментарий от vel

pid = 1

systemd занимается форвардингом пакетов?

На момент приема пакета неизвестно какой процесс его получит.

А в случае raw-сокета, ЕМНИП, получат все процессы.

Тут ещё вобще вопрос, что хочет ТС, может он хочет логировать весь трафик...

mky ★★★★★ ()
Ответ на: комментарий от barmaley99

У вас очень старое руководство по iptables. Уже давно вместо ″nf_″ стало ″xt_″ , то есть xt_match_owner. Но --pid-owner выкинули, ЕМНИП, ещё до переименования модулей из-за сложностей в его работе на SMP (многопроцессорность).

И диапазон возможных pid'ов больше, чем 0:65535, если какие процессы запускаются в отдельном pid namespace...

mky ★★★★★ ()
Последнее исправление: mky (всего исправлений: 1 )
Ответ на: комментарий от mky

Тут ещё вобще вопрос, что хочет ТС, может он хочет логировать >>весь трафик… Да весь исходящий с pid’ами процессов, вот уж неверится что это невозможно в наше время, в винде это возможно давно но мне нужно в линуксе У вас очень старое руководство по iptables а где самое актуальное найти? Но –pid-owner выкинули так его теперь что вообще нет?

barmaley99 ()
Ответ на: комментарий от mky

Мдаа почитал man iptables-extensions

owner
       This module attempts to match various characteristics of the packet creator, for locally generated packets. This match is only valid in the OUTPUT and POSTROUTING chains. Forwarded packets do not have  any  socket  associated
       with them. Packets from kernel threads do have a socket, but usually no owner.

       [!] --uid-owner username

       [!] --uid-owner userid[-userid]
              Matches if the packet socket's file structure (if it has one) is owned by the given user. You may also specify a numerical UID, or an UID range.

       [!] --gid-owner groupname

       [!] --gid-owner groupid[-groupid]
              Matches if the packet socket's file structure is owned by the given group.  You may also specify a numerical GID, or a GID range.

       [!] --socket-exists
              Matches if the packet is associated with a socket.

и действительно похоже --pid-owner давно выкинули а жаль, для десктопного ПК такая фильтрация крайне необходима, другое дело на сервере но у меня не сервер

barmaley99 ()
Последнее исправление: barmaley99 (всего исправлений: 1 )
Ответ на: комментарий от vel

Можно. Его можно написать.

Еще как вариант pid процесса можно извлечь из файла /proc/net/netlink покопался в /proc/net и обнаружил в этом файле содержимое следующего вида:

sk               Eth Pid        Groups   Rmem     Wmem     Dump  Locks    Drops    Inode
ffff8bb571d99000 0   736        00000111 0        0        0     2        0        19997   
ffff8bb5fb6b0800 0   725        00000001 0        0        0     2        0        29882   
ffff8bb5efc65000 0   24624      00000001 0        0        0     2        0        295865  
ffff8bb5f937e800 0   3711       00000440 0        0        0     2        0        37054   
ffff8bb5fcb08000 0   0          00000000 0        0        0     2        0        16      
ffff8bb5fa4c7000 0   784        00000110 0        0        0     2        0        21468   
ffff8bb5fabd4000 0   1610613451 00000559 0        0        0     2        0        19351   
ffff8bb5fa43c800 0   820        00000440 0        0        0     2        0        23001   
ffff8bb5f6c88000 0   18004      00000440 0        0        0     2        0        267566  
ffff8bb5f7ba7800 0   29663      00000555 0        0        0     2        0        321564  
ffff8bb5fb593000 0   600        00000111 0        0        0     2        0        17855   
ffff8bb573af1000 4   0          00000000 0        0        0     2        0        14793   
ffff8bb5fc1cb800 7   0          00000000 0        0        0     2        0        14309   
ffff8bb5fcbb9800 9   1          00000001 0        0        0     2        0        594     
ffff8bb5735a7000 9   2962479525 00000000 0        0        0     2        0        15570   
ffff8bb5fb6b1000 9   715        00000000 0        0        0     2        0        29924   
ffff8bb5fcb0d800 9   0          00000000 0        0        0     2        0        17      
ffff8bb5fc1cb000 10  0          00000000 0        0        0     2        0        11352   
ffff8bb5fcb9d800 11  0          00000000 0        0        0     2        0        1031    
ffff8bb5f937e000 12  0          00000000 0        0        0     2        0        47789   
ffff8bb5efc65800 12  24624      00000000 0        0        0     2        0        295856  
ffff8bb5f7616000 15  3836794873 00000002 0        0        0     2        0        20824   
ffff8bb571d99800 15  723        00000002 0        0        0     2        0        20005   
ffff8bb5f7606800 15  1511       00000002 0        0        0     2        0        26005   
ffff8bb5fabd4800 15  2636889160 00000002 0        0        0     2        0        18758   
ffff8bb5fcbba000 15  2291138884 00000001 0        0        0     2        0        602     
ffff8bb5fcaae800 15  0          00000000 0        0        0     2        0        1025    
ffff8bb5f7601000 15  1594       00000002 0        0        0     2        0        26454   
ffff8bb5fa43c000 15  1191       00000002 0        0        0     2        0        25012   
ffff8bb5fa43e000 15  1535       00000002 0        0        0     2        0        26721   
ffff8bb5f7613800 15  5082       00000002 0        0        0     2        0        40617   
ffff8bb5fa4c3800 15  774        00000002 0        0        0     2        0        23727   
ffff8bb5f7614800 15  2191364862 00000002 0        0        0     2        0        20853   
ffff8bb5fabd6000 15  719        00000002 0        0        0     2        0        18757   
ffff8bb5fabd3800 15  3233224358 00000002 0        0        0     2        0        18759   
ffff8bb5fa4c2000 15  1442       00000002 0        0        0     2        0        25812   
ffff8bb571d9d800 15  738        00000002 0        0        0     2        0        20013   
ffff8bb5fa4c1000 15  1173       00000002 0        0        0     2        0        24165   
ffff8bb571d9e800 15  2726952585 00000002 0        0        0     2        0        20068   
ffff8bb5fabd1000 15  715        00000002 0        0        0     2        0        19350   
ffff8bb5fa4c4800 15  2516813335 00000002 0        0        0     2        0        24176   
ffff8bb5fabd0000 15  3603749704 00000002 0        0        0     2        0        18760   
ffff8bb5fa4c1800 15  1465       00000002 0        0        0     2        0        25821   
Из них содержимое столбца pid действительно соответствует pid'ам запущенных в системе процессов как я проверил, и как только я запустил Mozilla Firefox он запустился с пидом 29663 и строчка с этим пидом сразу появилась в этом файле, только вот значения всех остальных столбцов, особенно столбца sk, мне пока неясны, к тому же неясно что это за процессы с длинными пидами вроде 2962479525 - процессовс такими пидами я в системе необнаружил

barmaley99 ()
Последнее исправление: barmaley99 (всего исправлений: 1 )
Ответ на: комментарий от barmaley99

Да, вот нагуглилось, 2005 год: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id...

и у ″-j LOG″ выкинули ″--log-pid″. Не знаю, в чём именно причина и насколько обширные правки нужны. Но, видимо, особо никому не нужно, раз за столько лет никто за это не взялся. А сейчас и не возмётся, сейчас nftables, в которых тоже есть только UIG и GID.

Для логгирования есть такая фиготень: https://github.com/mk-fg/conntrack-logger , но она заброшена и не видит не всё — не замечает если процесс отправил данные и быстро завершил работу.

Ну ещё есть возможность использовать auditd, но это страшно: https://serverfault.com/questions/352259/finding-short-lived-tcp-connections-...

mky ★★★★★ ()
Ответ на: комментарий от mky

Но, видимо, особо никому не нужно, раз за столько лет никто за >>это не взялся

Просто так как линукс - изначально серверная система то и iptables был написан для серверов (и роутеров), там такая фильтрация вполне годится, т.к. на серверах ставится только проверенное нужное ПО, ну а с компов в локальной сети подключенной к серверу пид итак не получить все равно (без доработок) но на десктопном ПК где на компе целый зоопарк из разношерстного ПО фильтрация по процессам просто необходима, и в винде она приносит немало пользы т.к. там это возможно очень давно, но опять же не все там ей пользуются и не все про нее там даже знают но впрочем это их проблемы, Но и в линуксе за это тоже взялись, есть проект opensnitchd: https://github.com/evilsocket/opensnitch вот они там и сделали фильтрацию по pid'ам, но только во первых они там не очень удобный интерефейс сделали, во вторых он тормозной, поджирает ЦПУ заметно, потому что писать надо было на С а не на питоне и го, вот пытаюсь изучить исходники чтобы понять как они определяют pid процесса инициирующего соединения, явно они там дописали этот нужный модуль, но пока понять не могу, синтаксис го вроде простой и понятный но нехватает знаний в линуксе чтобы понять что они там делают, похоже что модули отвечающие за определение pid находятся в

opensnitch-master\daemon\procmon\ 
В
opensnitch-master\daemon\conman\
соединение обрабатывается в connection.go, в частности вот эта функция
func newConnectionImpl(nfp *netfilter.Packet, c *Connection) (cr *Connection, err error) {
	// no errors but not enough info neither
	if c.parseDirection() == false {
		return nil, nil
	}

	// 1. lookup uid and inode using /proc/net/(udp|tcp)
	// 2. lookup pid by inode
	// 3. if this is coming from us, just accept
	// 4. lookup process info by pid
	if c.Entry = netstat.FindEntry(c.Protocol, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort); c.Entry == nil {
		return nil, fmt.Errorf("Could not find netstat entry for: %s", c)
	} else if pid := procmon.GetPIDFromINode(c.Entry.INode); pid == -1 {
		return nil, fmt.Errorf("Could not find process id for: %s", c)
	} else if pid == os.Getpid() {
		return nil, nil
	} else if c.Process = procmon.FindProcess(pid); c.Process == nil {
		return nil, fmt.Errorf("Could not find process by its pid %d for: %s", pid, c)
	}
	return c, nil

}
Получает пиды через функции из parse.go:
func GetPIDFromINode(inode int) int {
	expect := fmt.Sprintf("socket:[%d]", inode)
	found := -1

	forEachProcess(func(pid int, path string, args []string) bool {
		// for every descriptor
		fdPath := fmt.Sprintf("/proc/%d/fd/", pid)
		if descriptors, err := ioutil.ReadDir(fdPath); err == nil {
			for _, desc := range descriptors {
				descLink := fmt.Sprintf("%s%s", fdPath, desc.Name())
				// resolve the symlink and compare to what we expect
				if link, err := os.Readlink(descLink); err == nil && link == expect {
					found = pid
					return true
				}
			}
		}
		// keep looping
		return false
	})

	return found
} 
и
func FindProcess(pid int) *Process {
	linkName := fmt.Sprintf("/proc/%d/exe", pid)
	if core.Exists(linkName) == false {
		return nil
	}

	if link, err := os.Readlink(linkName); err == nil && core.Exists(link) == true {
		proc := NewProcess(pid, link)

		parseCmdLine(proc)
		parseEnv(proc)

		return proc
	}
	return nil
}

barmaley99 ()
Ответ на: комментарий от barmaley99

Как еще прочитал на гитхабе в описании этого проекта opensnitchd для определения pid'а инициировавшего соединение они использовали ftrace:

How Does It Work

OpenSnitch is an application level firewall, meaning then while running, it will detect and alert the user for every outgoing connection applications he's running are creating. This can be extremely effective to detect and block unwanted connections on your system that might be caused by a security breach, causing data exfiltration to be much harder for an attacker. In order to do that, OpenSnitch relies on NFQUEUE, an iptables target/extension which allows an userland software to intercept IP packets and either ALLOW or DROP them, once started it'll install the following iptables rules:

OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass

This will use conntrack iptables extension to pass all newly created connection packets to NFQUEUE number 0 (the one OpenSnitch is listening on), and then:

INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass

This will also redirect DNS queries to OpenSnitch, allowing the software to perform and IP -> hostname resolution without performing active DNS queries itself.

Once a new connection is detected, the software relies on the ftrace kernel extension in order to track which PID (therefore which process) is creating the connection.

If ftrace is not available for your kernel, OpenSnitch will fallback using the /proc filesystem, even if this method will also work, it's vulnerable to application path manipulation as described in this issue, therefore it's highly suggested to run OpenSnitch on a ftrace enabled kernel.

barmaley99 ()

Нетфильтр здесь ни к чему. Самые простые решения – auditd и strace. Они будут генерировать много лишнего и сильно просаживать производительность. По-хорошему, это лучше организовать средствами DTrace/BPFTrace, если он доступен.

i586 ★★★★ ()
Ответ на: комментарий от barmaley99

писать надо было на С а не на питоне и го,

Да, писать надо было на С, но не потому что питон медленный, а потому что нужен модуль на уровен ядра, а не userspace фигня, которая всё время читает весь /proc, пытаясь определить чей пакет. И обычно не успевает для корокоживущих процессов.

там такая фильтрация вполне годится

Ошибочно считать, что iptables это только фильтрация. Это и счётчики и маркировка пакетов, позволяющая реализовать более сложную маршрутизацию. У меня когда-то работал pid-owner, и даже, вроде, ядро патчили, чтобы -m owner как-то кривно, но работал в INPUT. Просто pid крайне не удобно, основное понятие это «задача», а не «процесс». Запускаемое пользователм приложение может форкать кучу процессов...

mky ★★★★★ ()
Ответ на: комментарий от i586

По-хорошему, это лучше организовать средствами DTrace/BPFTrace, если он доступен.

Ура!!!!!!!!!!!!!!!! Установил в убунту Bpftrace по инструкции

https://habr.com/en/company/itsumma/blog/441258/
с
https://github.com/iovisor/bpftrace
Инструмент - tcpconnect.bt в папке tools - реально показывает все открытые соединения источник-назначение с ip адресами портами и pid'ами!!! Все что нужно, теперь можно запилить интерактивный фаерволл на баше для процессов!!! Спасибо!

barmaley99 ()
Ответ на: комментарий от mky

Ошибочно считать, что iptables это только фильтрация. Это и >>счётчики и маркировка пакетов, позволяющая реализовать более >>сложную маршрутизацию

Про всё остальное это понятно но у меня в данном случае остро встал вопрос фильтрации, я как то уже давно в винде привык что у меня процессы в инет лазят только с моего разрешения и под моим контролем, и в линухе на это закрывать глаза не собираюсь

Просто pid крайне не удобно, основное понятие это «задача», а не >>«процесс». Запускаемое пользователм приложение может форкать >>кучу процессов...

Понятно - к тому же при каждом новом запуске и pid у проги новый, но это можно решить с помощью баш скрипта Впрочем проблема уже решена,человек сверху помог - инструмент bpftrace отслеживает соединения и пиды показывает да и еще много чего там нужного есть

barmaley99 ()
Ответ на: комментарий от barmaley99

tcpconnect.bt

Это скрипт, выполняемый bpftrace. Есть еще python-прокладка для eBPF, на python написан аналогичный (tcpconnect, … ) набор скриптов. Можете расковырять, посмотреть, как оно устроено.

Я еще не до конца освоился с eBPF, как по мне – DTrace проще и удобнее (привычка, синдром утенка и т.д.), но это ораклоспецифичная штука, которую, видимо, скоро закопают.

i586 ★★★★ ()
Последнее исправление: i586 (всего исправлений: 1 )
Ответ на: комментарий от i586

Это скрипт, выполняемый bpftrace

Это было сразу ясно, кстати на каком языке эти скрипты чтото в упор непойму, такое ощущение что это интерпретируемый Си

Есть еще python-прокладка для eBPF

А где их найти?

barmaley99 ()
Ответ на: комментарий от barmaley99

на каком языке эти скрипты

Некий новый «язык». С используется в SystemTap, который, я думаю, тоже закопают.

интерпретируемый

JIT-компилируемый.

А где их найти?

https://github.com/iovisor/bcc/blob/master/tools/tcpconnect.py

Не знаю, какая у вас система и где это лежит. Поищите, в каком пакете BCC и куда он ставится.

i586 ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.