메뉴 건너뛰기

KIM0.COM

Linux ip_conntrack: table full, dropping packet

2014.08.21 14:44

Kim 조회 수:5095

다음은 /var/log/messages 의 내용이다. Netfilter의 conntrack 하나당 228 byte가 필요하고 최대 32760개가 가능하다는 것이다.  (약 10M)

Oct  7 15:15:22 host kernel: ip_conntrack version 2.4 (4095 buckets, 32760 max) – 228 bytes per conntrack

만약 32760이 넘으면 어떻게 될까? 다음과 같이 패킷이 drop이 된다.

Oct  7 15:16:42 host kernel: ip_conntrack: table full, dropping packet.

이런 문제는 웹 서버와 같이 동시에 수 많은 connection을 처리해야 하는 경우에 발생할 수 있고 ab와 같은 stress 발생기를 사용하는 경우에도 발생할 수 있다. 이 문제에 대한 해결책은?

  1. netfilter를 사용하지 않는다.
  2. conntrack를 최대 개수를 늘린다.
  3. iptables raw table를 이용해서 특정 패킷은 conntrack을 하지 않는다.
  4. TCP 연결과 같이 각 상태별 TTL 값을 조절해서 볼 일이 끝난 연결은 빨리빨리 conntrack에서 제거한다.

 각 경우에 대해서 좀 더 자세히 알아보자.

1. netfilter를 사용하지 않는다.

보안을 신경쓰지 않아도 된다면 그래도 좋다.

#service iptables stop

2. conntrack의 최대 개수를 늘린다.

아래와 같이 하면 가능하다.

echo “100000″ > /proc/sys/net/ipv4/ip_conntrack_max

3. NOTRACK

다음은 웹 서버(80)로 오가는 패킷은  conntrack 하지 않도록 하는 규칙이다. 들어오고 나가는 패킷 모두에 대해서 규칙을 넣어주어야 한다는 사실에 주의하시길.

# input packet to server			

iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
# output packet from server
iptables -t raw -A OUTPUT -p tcp --sport 80 -j NOTRACK

“cat /proc/net/ip_conntrack”이나 iptstate를 실행해도 이제 더 이상 80번 포트로 오가는 패킷을 기록되지 않게 된다. 당연히 NAT는 할 수 없고 “-m state –state NEW” 와 같은 stateful inspection 규칙은 사용할 수 없게 된다.raw table은 conntrack이나 filter 앞에 위치하며 packet의 내부 정보에 UNTRACKED를 표시해 둔다.이 정보는 -m state –state UNTRACKED 의 규칙을 사용해서 filter에서 이용할 수 있다.  NOTRACK을했다고 해서 그 이후의 filter 규칙을 무시하는 것은 아니다. 단지 stateful inspection을 사용할 수 없을뿐이다.

이렇게 NOTRACK을 한 패킷을 filter에서 통과시키기 위해서는 다음과 같이 명시적으로 해 줄 수도 있다. 물론 -p tcp –dport 와 같은 IP 헤더 정보를 이용한 filtering도 가능하다.

# iptables -I INPUT -m state –state UNTRACKED -j ACCEPT
# iptables -I OUTPUT -m state –state UNTRACKED -j ACCEPT

4. TIMEOUT 값 변경

Netfilter와 관련해서 변경가능한 값은 아래와 같다. Timeout과 관련한 값을 변경해서 conntrack에 자리 잡고 있는 시간을 조절할 수 있다. 특히 timout_established 의 경우에는 5일이나 된다. 물론 TCP 연결이 종료된 경우에는 그에 부응하여 TTL 값이 줄기는 하지만 만약에 연결이 된 상태에서 클라이언트가 죽는 경우와 같은 경우에는 계속 상태를 잡고 있을 가능성이 있다.

Conntrack related status :
/proc/sys/net/ipv4/ip_conntrack_max:32760
/proc/sys/net/ipv4/netfilter/ip_conntrack_buckets:4095
/proc/sys/net/ipv4/netfilter/ip_conntrack_checksum:1
/proc/sys/net/ipv4/netfilter/ip_conntrack_count:3
/proc/sys/net/ipv4/netfilter/ip_conntrack_generic_timeout:600
/proc/sys/net/ipv4/netfilter/ip_conntrack_icmp_timeout:30
/proc/sys/net/ipv4/netfilter/ip_conntrack_log_invalid:0
/proc/sys/net/ipv4/netfilter/ip_conntrack_max:32760
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal:0
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_loose:1
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_max_retrans:3
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_close:10
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_close_wait:60
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established:432000
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_fin_wait:120
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_last_ack:30
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_max_retrans:300
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_syn_recv:60
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_syn_sent:120
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_time_wait:120
/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout:30
/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout_stream:180

현재 conntrack 개수 빨리 알기

ip_conntrack_count 값을 읽으면 빨리 알 수 있다. 전체 리스트를 읽는 것은 시간이 오래 걸릴 뿐만이 아니라 전체 시스템 반응에도 심각한 영향을 줄 수 있다.

[root /proc/sys/net/ipv4/netfilter]# cat ip_conntrack_count
4887
[root /proc/sys/net/ipv4/netfilter]# wc -l /proc/net/ip_conntrack
4887 /proc/net/ip_conntrack