검색 엔진의 방문이 늘어나고 있군...

Posted
Filed under 프로그램과 명령어/네트워크와 보안
참조 원문 : Linux Network IP Accounting
관련 문서 : IptablesHowTo

  네트워크에서 IP 어카운팅(Accounting)이란 네트워크 트래픽을 모니터링하는 것을 뜻합니다. 대략 아래와 같은 것이 IP 어카운팅이라고 할 수 있습니다.
  • eth0 인터넷 링크의 데이터 전송량 확인.
  • 특정 IP 주소를 통한 데이터 전송량 확인.
  • 아파치 버추얼 도메인별 데이터 전송량 확인.
  • 서비스 포트(HTTP, SMTP 등)와 프로토콜(TCP, UDP, ICMP)별 데이터 전송량 확인.
  이러한 기능은 별도의 프로그램을 사용하지 않고도 리눅스의 기본 방화벽 프로그램인 iptables를 통해 구현이 가능합니다.(물론 사용하기에 그리 편하진 않지만...) 생각해보면 방화벽은 네트워크 트래픽을 모두 검사하기 때문에 이런 기능을 갖고 있기에 안성맞춤이라 할 수 있습니다.

  iptables에는 다수의 체인이 있고 체인은 다시 기본 체인과 유저가 정의할 수 있는 체인으로 나눠지는데 이 글에서는 INET_IN과 INET_OUT이라는 별도의 체인을 정의하여 사용합니다.

  먼저 현재 iptables의 테이블과 체인을 보기 위해 아래의 명령어를 사용합니다.
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        
  -L 옵션은 내용을 출력하는 옵션이고 -n은 DNS 조회를 방지하는 옵션입니다. 만약 -n 옵션이 없으면 체인에 있는 각 IP마다 도메인 조회를 하기 때문에 경우에 따라서 출력에 상당한 시간이 소요됩니다.

  이제 여기에 -v 옵션을 추가하면 유용한 정보가 속속들이 나오기 시작합니다.
$ sudo iptables -L -n -v
Chain INPUT (policy ACCEPT 1635K packets, 320M bytes)
 pkts bytes target     prot opt in    out    source   destination        

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in    out    source   destination        

Chain OUTPUT (policy ACCEPT 1756K packets, 473M bytes)
 pkts bytes target     prot opt in    out    source   destination 
  위에서 눈여겨봐야 할 것은 체인을 거친 총 패킷 및 바이트와 체인 내에 있는 각 엔트리별 패킷 및 바이트 칼럼입니다. 이후 아래에서 설명하는 방법으로 체인을 설정하고 위의 값을 보면 원하는 자료를 얻을 수 있습니다.


IP 어카운팅 설정 방법
  아래의 명령어로 IP 어카운팅에 사용할 사용자 정의 체인을 만듭니다. INET_OUT이라는 이름의 체인은 바깥으로 나가는 트래픽의 양을 저장, INET_IN이란는 이름의 체인은 바깥에서 들어오는 트래픽의 양을 저장하기 위해 쓸 예정입니다.
$ sudo iptables -N INET_OUT
$ sudo iptables -N INET_IN
$ sudo iptables -v -n -L
Chain INPUT (policy ACCEPT 1645K packets, 321M bytes)
 pkts bytes target     prot opt in    out    source    destination        

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in    out    source    destination        

Chain OUTPUT (policy ACCEPT 1765K packets, 477M bytes)
 pkts bytes target     prot opt in    out    source    destination        

Chain INET_IN (0 references)
 pkts bytes target     prot opt in    out    source    destination        

Chain INET_OUT (0 references)
 pkts bytes target     prot opt in    out    source    destination      
  이제 IP, 포트, 프로토콜별 모니터링 설정 방법을 보겠습니다.

설정1. IP별 설정 방법
  아래는 자신과 192.168.1.1, 192.168.1.2 사이의 트래픽에 대한 설정입니다.
### 새로운 체인 생성 ###
$ /sbin/iptables -N INET_IN
$ /sbin/iptables -N INET_OUT

### 생성한 체인 장착 ###
$ /sbin/iptables -A INPUT -j INET_IN
$ /sbin/iptables -A OUTPUT -j INET_OUT

### 입력에 대한 규칙 설정 ###
$ /sbin/iptables -A INET_IN -s 192.168.1.1
$ /sbin/iptables -A INET_IN -s 192.168.1.2

### 출력에 대한 규칙 설정 ###
$ /sbin/iptables -A INET_OUT -d 192.168.1.1
$ /sbin/iptables -A INET_OUT -d 192.168.1.2

### 저장 ###
$ /sbin/service iptables save

### 결과 출력(레드햇 계열만 가능) ###
$ sudo iptables -v -n -L INET_IN
Chain INET_IN (2 references)
 pkts bytes target   prot opt in  out  source      destination        
  155 11594          all  --  *   *    192.168.1.2 0.0.0.0/0          
    6   504          all  --  *   *    192.168.1.1 0.0.0.0/0          

$ sudo iptables -v -n -L INET_OUT
Chain INET_OUT (2 references)
 pkts bytes target   prot opt in  out  source      destination        
    6   504          all  --  *   *    0.0.0.0/0   192.168.1.1        
   50  9474          all  --  *   *    0.0.0.0/0   192.168.1.2   

설정2. 포트별 설정 방법
  아래는 eth0의 22 포트(SSH)의 트래픽에 대한 설정입니다. eth0를 지정한 것은 인터페이스별로 설정하는 것도 가능하다는 것을 보여주기 위한 것일 뿐 필수적인 것은 아닙니다.
### 새로운 체인 생성 ###
$ /sbin/iptables -N INET_IN_PORT
$ /sbin/iptables -N INET_OUT_PORT

### 생성한 체인 장착 ###
$ /sbin/iptables -A INPUT -j INET_IN_PORT
$ /sbin/iptables -A OUTPUT -j INET_OUT_PORT

### 입력에 대한 규칙 설정 ###
$ /sbin/iptables -A INET_IN_PORT -i eth0 -p tcp --dport 22

### 출력에 대한 규칙 설정 ###
$ /sbin/iptables -A INET_IN_PORT -o eth0 -p tcp --dport 22

### 저장 ###
$ /sbin/service iptables save

### 결과 출력(레드햇 계열만 가능) ###
$ sudo iptables -v -n -L INET_IN_PORT
Chain INET_IN_PORT (1 references)
 pkts bytes target  prot opt in   out  source      destination
  965 75916         tcp  --  eth0 *    0.0.0.0/0   0.0.0.0/0  tcp dpt:22

$ sudo iptables -v -n -L INET_OUT_PORT
Chain INET_OUT_PORT (1 references)
 pkts bytes target  prot opt in   out  source      destination
  462 49192         tcp  --  *    eth0 0.0.0.0/0   0.0.0.0/0  tcp spt:22

설정3. 프로토콜별 설정 방법
  TCP, UDP, ICMP 프로토콜별 트래픽에 대한 설정입니다.
### 새로운 체인 생성 ###
$ /sbin/iptables -N INET_IN_PROTOCOL
$ /sbin/iptables -N INET_OUT_PROTOCOL

### 생성한 체인 장착 ###
$ /sbin/iptables -A INPUT -j INET_IN_PROTOCOL
$ /sbin/iptables -A OUTPUT -j INET_OUT_PROTOCOL

### 입력에 대한 규칙 설정 ###
$ /sbin/iptables -A INET_IN_PROTOCOL -i eth0 -m tcp -m tcp
$ /sbin/iptables -A INET_IN_PROTOCOL -i eth0 -m udp -m udp
$ /sbin/iptables -A INET_IN_PROTOCOL -i eth0 -m icmp -m icmp

### 출력에 대한 규칙 설정 ###
$ /sbin/iptables -A INET_IN_PROTOCOL -o eth0 -m tcp -m tcp
$ /sbin/iptables -A INET_IN_PROTOCOL -o eth0 -m udp -m udp
$ /sbin/iptables -A INET_IN_PROTOCOL -o eth0 -m icmp -m icmp

### 저장(레드햇 계열만 가능) ###
$ /sbin/service iptables save

### 결과 출력 ###
$ sudo iptables -v -n -L INET_IN_PROTOCOL
Chain INET_IN_PROTOCOL (1 references)
 pkts bytes target  prot opt in   out  source     destination        
  134 10232         tcp  --  eth0 *    0.0.0.0/0  0.0.0.0/0  tcp
    1   229         udp  --  eth0 *    0.0.0.0/0  0.0.0.0/0  udp
    3   308         icmp --  eth0 *    0.0.0.0/0  0.0.0.0/0  icmp type 255

$ sudo iptables -v -n -L INET_OUT_PROTOCOL
Chain INET_OUT_PROTOCOL (1 references)
 pkts bytes target  prot opt in   out  source     destination        
    3   252         icmp --  *    eth0 0.0.0.0/0  0.0.0.0/0  icmp type 255
    0     0         udp  --  *    eth0 0.0.0.0/0  0.0.0.0/0  udp
   67  8837         tcp  --  *    eth0 0.0.0.0/0  0.0.0.0/0  tcp


iptables를 이용한 IP 어카운팅 관련 팁 모음

팁1. 패킷과 바이트의 정확한 값을 보는 방법
  패킷과 바이트 값이 작을 때는 정확한 정수로 나오지만 값이 커지면 3기가바이트의 경우 '3G'처럼 보기 좋게 출력됩니다. 하지만 정확한 값이 필요할 경우에는 -x 옵션을 추가하면 됩니다.
$ sudo iptables -v -n -L INPUT
Chain INPUT (policy ACCEPT 1653K packets, 322M bytes)
...

$ sudo iptables -v -n -x -L INPUT
Chain INPUT (policy ACCEPT 1652848 packets, 321877443 bytes)
...

팁2. 패킷과 바이트 값 초기화 방법
  -Z 옵션을 사용하면 값을 초기화할 수 있습니다.
$ sudo iptables -v -n -L OUTPUT
Chain OUTPUT (policy ACCEPT 1771639 packets, 480398495 bytes)
...
$ sudo iptables -Z OUTPUT
$ sudo iptables -v -n -L OUTPUT
Chain OUTPUT (policy ACCEPT 15 packets, 1428 bytes)
...

팁3. 실시간으로 트래픽 모니터링 방법
  주기적으로 특정 명령어를 실행하게 만드는 watch 프로그램을 사용하면 간단히 해결할 수 있습니다.
$ sudo watch -n 1 iptables -v -n -L OUTPUT

팁4. iptables의 룰과 패킷&바이트 값을 저장 및 복구하는 방법
  리붓을 하면 기본적으로 iptables에 설정한 값들은 모두 사라지게 됩니다. 따라서 리붓전에 설정한 룰과 기록된 패킷 및 바이트 값을 리붓 후에도 그대로 사용하고 싶다면 별도의 명령어를 사용해야 합니다.
$ sudo iptables-save -c > /path/to/iptables.rules     ; 저장
$ sudo iptables-restore -c < /path/to/iptables.rules  ; 불러오기
  이걸 응용해서 부팅마다 지정한 위치에 있는 파일을 읽어오도록 /etc/rc.local 파일에 iptables-restore 명령어를 넣을 수도 있고 한 단계 더 진화해서 아래와 같이 시스템 V 서식의 스크립트를 만들어 /etc/init.d 디렉토리에 넣어 종료와 부팅 시 자동으로 저장과 불러오기를 하게 만들 수도 있습니다. 아래 스크립트는 레드햇 계열 기준의 스크립트이지만 윗 부분의 함수 라이브러리와 네트워크 설정을 불러오는 줄을 지우고 경로 변수($path)의 값만 적절히 원하는 디렉토리 이름으로 고쳐도 다른 배포판에서 아무 문제 없이 사용할 수 있습니다.
#!/bin/sh
#
# save-restore-iptables-counter
#
# chkconfig:  2345 08 92
# description:  Save and restore iptables counters
# processname: none
# Note: See how to use this script :
# http://www.cyberciti.biz/faq/linux-configuring-ip-traffic-accounting/
# Source function library.
. /etc/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
path="/etc/sysconfig/iptables.rules.counter"
_restorecmd="/sbin/iptables-restore"
_savecmd="/sbin/iptables-save"
prog="save-restore-iptables-counter"
 
start() {
    echo -n $"Starting $prog: "
    $_restorecmd -c < "$path"
    retval=$?
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    $_savecmd -c > "$path"
    retval=$?
    return $retval
}
 
restart(){
    stop
    start
}
 
case "$1" in
    start)
        start;;
    stop)
        stop;;
    restart)
        restart;;
    *)
        echo $"Usage: $0 {start|stop|restart}"
        exit 3
esac
  물론 만들기만 하면 자동으로 적용되는 것은 아니고 데비안 계열의 경우 'sudo update-rc.d 스크립트_파일명 defaults', 레드햇 계열의 경우 'sudo chkconfig --level 345 스크립트_파일명 on'을 통해 스크립트가 부팅과 종료 시 자동으로 작동하도록 등록을 해야 합니다.

팁5. 게이트웨이용 리눅스를 위한 명령어 문법 정리
  공유기 역할을 하고 있는 리눅스에서 IP 어카운팅을 하기에 적절한 명령어 목록입니다. 인터넷과 내부 컴퓨터 사이에서 패킷을 반대편으로 전달하기 때문에 FORWARD 체인을 이용한다는 것이 가장 큰 특징입니다.
iptables -N 체인이름
iptables -A FORWARD -j 체인이름
iptables -A 체인이름 -d IP주소
iptables -A 체인이름 -s IP주소
iptables -A 체인이름 -i ppp0 -p tcp -m tcp  --sport PORT
iptables -A 체인이름 -o ppp0 -p tcp -m tcp  --dport PORT

팁6. 일반 서버용 리눅스를 위한 명령어 문법 정리
  일반적인 리눅스 서버에서 IP 어카운팅을 하기에 적절한 명령어 목록입니다.
iptables -N 체인이름
iptables -N 체인이름
iptables -A INPUT -j 체인이름
iptables -A OUTPUT -j 체인이름
iptables -A 체인이름 -d IP주소
iptables -A 체인이름 -s IP주소


2010/12/06 18:36 2010/12/06 18:36
Posted
Filed under 프로그램과 명령어/네트워크와 보안
참조 원문 : 7 Uncommon uses of Iptables
관련 문서 : IptablesHowTo

  여러 소스를 통해 수집한 봇넷, 스패머, 브루트포서 등 악성 호스트의 IP 리스트를 제공하는 infiltrated.net이라는 곳이 있습니다. 참고로 저 사이트의 해당 리스트는 1시간에 1번씩 업데이트된다고 합니다. 이 글은 이곳에서 리스트를 끌어와 iptables에 적용시키는 팁입니다. 나중에 반전이 있으니 너무 흥미진진하게 읽진 마세요.

  일단 아래는 awk를 이용하여 IP 목록을 iptables 문법에 맞게 적용시킨 명령어를 화면에 출력하는 명령어입니다. 그냥 화면에만 출력하는 겁니다.
wget -qO - http://infiltrated.net/blacklisted|awk '!/#|[a-z]/&&/./{print "iptables -A INPUT -s "$1" -j DROP"}'
  그냥 화면에만 출력하는 거기 때문에 실제로 적용하려면 맨 뒤에 '| sh'을 붙여 화면에 출력하는 대신 진짜로 실행하게 만들어야 합니다. 단! iptables를 사용하려면 루트 권한이 필요하다는 걸 잊으시면 안 됩니다. 따라서 애초에 루트로 사용자를 변경한 후 실행하시거나 위 명령문 앞의 'iptables' 앞에 'sudo'를 추가로 넣어주셔야 합니다. 그럼 아래와 같이 되겠지요.
wget -qO - http://infiltrated.net/blacklisted|awk '!/#|[a-z]/&&/./{print "sudo iptables -A INPUT -s "$1" -j DROP"}' | sh
  아니면 리다이렉션을 통해 파일로 만든 다음에 해당 파일을 루트 권한으로 실행하는 방법도 있겠습니다.
wget -qO - http://infiltrated.net/blacklisted|awk '!/#|[a-z]/&&/./{print "iptables -A INPUT -s "$1" -j DROP"}' > black.lst
sudo sh black.lst
  또한 리스트는 1시간마다 업데이트되므로 일정 시간마다 cron으로 업데이트시키는 것이 좋겠지요.

  그런데 이 팁은 문제가 많습니다. 먼저 적용이 너무 오래 걸린다는 겁니다. 제가 실제로 실행을 해본 결과, 적용에 대략 1시간이 걸리더군요. 아무리 적용하는 줄이 4만 줄을 넘고 작업에 CPU를 많이 사용하지 않더라도 이렇게 오래 걸리면 사용하기 곤란하지요. 한 명령줄에 여러 IP를 등록하도록 스크립트를 좀 수정하면 훨씬 빨라질 것 같기는 한데 문제는 속도뿐만이 아닙니다. 몇 일 사용해보고 원문에 리플을 단 사람의 말에 따르면 자신이 가진 1달 분량의 데이터(어떤 데이터가 어느 정도인지 자세히 밝히진 않았습니다)와 해당 사이트의 리스트를 비교 분석한 결과 리스트 중 겨우 18개(그 중 스팸 메일 관련이라고 할 수 있는 25번 포트 건수는 겨우 2건)만이 일치했다고 합니다. 물론 그 사람이 가진 악성 호스트 데이터가 얼마나 있었는지 알 수 없으므로 그걸 통해 제가 효용성을 평가하기엔 무리가 있습니다. 하지만 그뿐만이 아닙니다. 며칠 후 또 리플을 달았는데 방화벽의 CPU 사용률이 100%를 찍기 시작했다고 합니다. 따라서 전 이 팁을 비추합니다 -_-;; 애초에 요즘 시대에 단순 IP 필터링만으로 뭘 막기엔 한계가 있죠. 그냥 이런 것도 있다는 정도로만 알고 넘어가는 것이 좋겠습니다.

2010/12/02 19:28 2010/12/02 19:28