Linux iptables를 사용하면 아웃 바운드 연결을 시작하는 프로세스 / 명령 이름을 기록 할 수 있습니까?


27

Linux 데스크톱에서 아웃 바운드 연결을 시작하는 프로세스를 추적하고 싶습니다. 내가 생각해 낼 수있는 최선은 다음과 같습니다.

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

연결을 시작하지만 프로세스 / 명령 이름 또는 pid는 아닌 uid / gid를 기록합니다. 내가 pid를 얻을 수 있다면 아마도 로그가 작성 될 때 프로세스 이름을 가져 오는 스크립트를 채울 수는 있지만 가능하지 않은 것처럼 보입니다.

이상적으로는 들어오는 연결을 수락하는 프로세스도 기록하고 싶습니다.

리눅스 상자에서 iptables (또는 다른 것)로 어떻게 이것이 가능할 수 있습니까?


나는이 질문이 serverfault에서 답변되었다고 생각합니다.
niXar

개인적 으로이 작업에 sysdig 를 사용 합니다.
Charles Duffy

답변:


7

/ proc / net / tcp를 모니터링하는 프로그램을 작성할 수 있으며 출력은 다음과 같습니다.

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

그런 다음 열린 포트를 inode에 연결할 수 있으며, 각 프로세스에 대해 나열된 파일 디스크립터에서 readlink를 수행하여 프로세스 및 파일 디스크립터와 다시 관련 될 수 있습니다.

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

여기서 inode 4847458은 위 목록의 첫 번째 tcp 소켓에 해당합니다. netstat -tapn의 출력은 나를 위해 이것을 확인합니다 (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

모니터 프로그램이 / proc / net / tcp에서 변경 사항을 발견하면 데이터를 구문 분석하고 변경 사항이 새로 열린 소켓인지 판별하십시오. 그런 다음 / proc에 나열된 각 프로세스에 대한 모든 파일 설명자를 열거하고 각각에 대해 readlink를 수행하여 일치하는 inode를 찾을 수 있습니다. 일단 당신이 그것을 발견하면, 당신은 소유하고있는 pid를 가지고 있습니다.

즉각적인 알림이 필요하지 않으면 모니터 프로그램에서 느린 폴링 (아마도 50ms 또는 100ms 또는 1000ms)을 사용할 수 있습니다.


2
옵션을 제공해 주셔서 감사합니다! 그러나 매번 열려있는 모든 파일 설명자를 폴링하고 쿼리해야하는 것은 그리 강력하지 않고 비효율적입니다. 나는 여전히 더 나은 해결책을 찾거나 iptables의 일부가 아닌 이유와 --cmd-owner를 해결할 수없는 이유를 분명히 밝히기를 바라고 있습니다.
nealmcb

커널이 / proc의 레이아웃을 변경하지 않거나 netstat 및 readlink 또는 ps가 변경되지 않는 한 (아마도) 이것이 강력하다고 말할 것입니다. 어떤 종류의 효율성 문제가 있습니까? 즉각적인 처리를 원한다면 iptables와 함께 사용할 커널 모듈을 작성해야합니다.
벤 콜린스

거부 된 연결을 로깅하면 소켓이 커널에 의해 즉시 파괴되므로 / proc에서 볼 수있는 기회가 거의 없습니다. 연결 시간이 초과되도록 REJECT 만 DROP으로 변경하는 경우도 있습니다.
Marki555

이 시나리오에서는 초소형 시간대 때문에 도움이되지 않지만 구문 분석 / proc의 취약성이 진행되는 한 "lsof -F -i"를 사용하여 네트워크의 추상화 된 덤프를 얻을 수 있습니다 데이터. 또한 특정 포트에서 필터링 할 수 있으며 이미 모든 파일 이름 / pid / 사용자 매핑을 수행했습니다.
dannysauer

9

소유자 일치 모듈은 OUTPUT 체인에서만 작동하며 PREROUTING ...?)에서만 작동합니다. 문서를 읽으십시오. 그러나 다음과 같이 작동합니다.

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

1
iptables log 명령이 이런 식으로 변수를 설정하고 보간 할 수 있습니까? 그것은 나를 위해 작동하지 않는 것 같습니다. 또한 --cmd-owner 옵션이 커널> = 2.6.15에서 제거 된 것 같습니다. 유용한 옵션처럼 보이기 때문에 불행한 일입니다.

4
예, --cmd-owner가 제거되었습니다 : "고칠 수없는 고장"
guettli

1
정보, @guettli 주셔서 감사합니다. permalink.gmane.org/에 더 자세한 내용이 있습니다 . "[NETFILTER] : ipt {, 6} 소유자에서 tasklist_lock 남용을 제거하십시오. cmd / sid / pid 일치는 수정 불가능하고 깨져서 제거됩니다. tasklist_lock 변경 사항을 잠그는 방법 " 그러나 나는 여전히 더 많은 배경이나 더 나은 대안을 원합니다.
nealmcb

5

iptables 또는 logging과는 아무런 관련이 없습니다. 그러나 다음은 / proc / 디렉토리를 폴링하고 프로그램 / pid 당 대역폭을 표시하는 인터페이스와 같은 "상위"입니다.

http://sourceforge.net/projects/nethogs

"NetHogs는 작은 'net top'도구입니다. 대부분의 도구와 마찬가지로 프로토콜 또는 서브넷 당 트래픽을 분류하는 대신 프로세스별로 대역폭을 그룹화합니다. NetHogs는로드 할 특수 커널 모듈에 의존하지 않습니다."


nethogs가 신뢰할 수없는 통계를 제공한다는 것을 알았지 만 2 위 (+ netatop) 가이를 잘 수행합니다.
Tobu

1

비슷한 질문으로 스카이프 속도 제한을 시도하면서

$ netstat -p | grep <mycmdname>

포트 번호를 pid / cmd에 연결하는 좋은 방법입니다. 이제 pid-owner / cmd-owner는 더 이상 iptables에서 직접 지원되지 않습니다. 그런 다음 결과를 구문 분석 한 다음 포트에 따라 iptables 규칙을 추가해야합니다. 당연히 나중에 / 시스템 종료 / 재시작 등의 정리 코드가 필요합니다. 정리시 참조 할 수 있도록 포트 번호를 파일에 저장

실제로 포트 번호 질문에 대한 좋은 대답은

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

필요에 따라 grep tcp 요소를 조정해야 할 수도 있습니다.

그런 다음 내 목적을 위해 포트 번호에 따라 tc u32 필터를 추가하는 것이 가장 간단했으며 포트 번호에 따라 iptables 항목을 유사하게 만들었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.