본문 바로가기
보안/기초

솔라리스 네트워크 커널 보안 튜닝 (ndd)

by ITPro 2010. 8. 11.
Solaris Network Kernel Tunning for Security

cert@certcc.or.kr, http://www.certcc.or.kr

김상철연구원 ksch@certcc.or.kr

1. 소개

Solaris Kernel은 TCP/IP스택에 여러가지 사용자 인터페이스를 제공한다. Cache 테이블의 Lifetime 및 다수의 TCP 연결에 대한 여러가지 옵션을 통하여 Kernel Parameter의 설정 및 제어가 가능하다. 하지만 이러한 Kernel Parameter들을 Tunning하기 위하여 각각의 kernel parameter들에대한 정확한 기능들의 이해가 반드시 요구되어진다. 그리고 많은 시스템관리자들은 이러한 Kernel Parameter들을 사용 및 설정하는 등의 일련의 Security 업무에 소홀히 해왔다. 이 보고서에서는 solaris에서 제공되어지는 Network Security Kernel들에 관련하여 올바르게 이해해고 설정하여 Tunning하는 방법을 소개하고자 한다.

2. Solaris Kernel Tools

solaris에서는 TCP/IP 커널에 대한 드라이버로서 "ndd"가 유일한 도구이며 Solaris 시스템의 네트워크 커널 변수들을 Tunning하기 위한 가장 유용한 Tool이 "ndd"이다.

3. Solaris 네트워크 커널 변수들

일반적으로 TCP/IP 커널에 대한 변수들을 보는 방법은 다음과 같은 명령어를 실행함으로써 가능하다.

# ndd /dev/<driver> <parameter>

여기서 TCP/IP 커널에 대하여 <driver>는 ARP, IP, TCP, UDP중에 하나이며 각각의 드라이버에 대하여 모든 변수들을 보는 명령어는 다음과 같다.

# ndd /dev/<driver> \?

IP 드라이버에 대한 명령어를 실행하면 다음과 같이 출력된다.

[phoenix:root]:/ >ndd /dev/ip \?

? (read only)

ip_forwarding (read and write)

ip_respond_to_address_mask_broadcast(read and write)

ip_respond_to_echo_broadcast (read and write)

ip_respond_to_timestamp (read and write)

ip_respond_to_timestamp_broadcast(read and write)

ip_send_redirects (read and write)

ip_forward_directed_broadcasts(read and write)

ip_debug (read and write)

ip_mrtdebug (read and write)

ip_ire_cleanup_interval (read and write)

ip_ire_flush_interval (read and write)

ip_ire_redirect_interval (read and write)

ip_def_ttl (read and write)

ip_forward_src_routed (read and write)

ip_wroff_extra (read and write)

ip_ire_pathmtu_interval (read and write)

ip_icmp_return_data_bytes (read and write)

ip_send_source_quench (read and write)

ip_path_mtu_discovery (read and write)

ip_ignore_delete_time (read and write)

ip_ignore_redirect (read and write)

ip_output_queue (read and write)

ip_broadcast_ttl (read and write)

ip_icmp_err_interval (read and write)

ip_reass_queue_bytes (read and write)

ip_strict_dst_multihoming (read and write)

ip_addrs_per_if (read and write)

ip_ill_status (read only)

ip_ipif_status (read only)

ip_ire_status (read only)

ip_ipc_status (read only)

ip_rput_pullups (read and write)

ip_enable_group_ifs (read and write)

ndd를 사용하여 커널 변수를 설정하기 위하여는 다음과 같이 명령어를 실행하면 된다.

# ndd -set /dev/<driver> <parameter> <value>

ndd를 사용하여 커널 변수를 변경할때는 주의하여야 할 사항이 있다. 한번 설정된 parameter는 시스템을 재부팅할 경우에는 이전에 설정된 값이 원래의 기본설정값으로 변경된다는 점이다. 설정된 값을 계속적으로 사용하기 위해서는 시스템 관리자가 shell script등을 이용해서 시스템 부팅시 자동으로 시스템관리자가 원하는 설정값으로 설정되게 운영하여야 많다. 예를들어 /etc/init.d/inetinit나 개별적인 shell script로 운영하여야만 한다.

4. ARP (Address Resolution Protocol)

ARP는 Layer3의 네트워크 주소를 data-link 주소(MAC Address)로 동적 맵핑(mapping)하는데 사용된다. 하나의 시스템이 한 네트워크 상에서 다른 시스템과 통신하고자 한다면 broadcast주소인 ff:ff:ff:ff:ff:ff로 ARP 패킷을 첫번째로 보낸다. 그 패킷은 단순한 패킷으로서 해당 주소를 어떤 시스템이 사용하고 있는지에 대한 질의 패킷이다. 예를 들어 누가 주소 A를 사용하고 있느지에 대하여 ARP패킷을 broadcast하면, 한 network 상에 존재하는 모든 호스트들이 이 패킷을 수신하게 된다. 이때 시스템 A는 ARP 요구에 대한 응답으로서 답을 보내게된다. ARP Broadcast패킷을 보냈던 해당 시스템은 32bit IP주소를 layer-2인 MAC주소로 매핑하면서 table과 cache를 구성하여 운영하게 된다. 이때 해당 시스템은 network layer에의한 두번째 테이블을 구성하게 된다. 이 테이블은 data-link layer에의해 제공되어지는 정보로부터 구성되어지며, 활성화된 연결에대한 네트워크 라우팅 정보를 포함하고 있다. network layer는 data-link layer로부터 MAC주소를 요청하며, 요청된 결과로부터 수신된 이러한 주소를 네트워크 라우팅 테이블에 저장되어진다. Network layer의 정보는 20분 후에 만료된다.

하나의 네트워크에서 호스트는 다른 시스템과 통신하기 위하여 첫번째로 IP layer의 ARP cache를 체크한다. 이때 네트워크 peer에대한 엔트리가 cache에 존재하지 않으면 ARP 요청이 broadcast되어 진다. ARP Cache 엔트리는 5분후에 만료된다. ARP Cache를 이용한 공격은 두가지 종류가 있다. 하나는 ARP cache poisoning이며 다른 하나는 ARP spoofing이다.

ARP cache poisoning은 존재하지 않는 ARP주소나, 잘못된 ARP주소를 시스템의 ARP cache에 삽입시키는 것이다. 이것은 target시스템이 peer의 IP주소로 패킷을 보내지만 MAC주소가 잘못되어 있기때문에 해당 시스템으로 하여금 서비스 거부를 일으킬수 있다,

ARP spoofing은 system compromise 결과를 초래할 수 있다. IP spoofing처럼 ARP spoofing은 네트워크상에 존재하는 하나의 호스트를 네트워크 기능을 정상적으로 처리하지 못하게 해서 모든 ARP 요청 broadcast에 대한 응답을 못하도록 한다. 이것이 행해지기만 하면 공격자는 무능력해진 호스트의 IP주소를 공격 호스트로서 구성하여 사용할 수가 있게 되어진다. 피해 호스트가 무능력해진 호스트와 통신하려 할때 공격자의 시스템이 모든 ARP broadcast의 요청에 응답하게 된다. 이렇게 하면 그것의 MAC주소가 피해시스템의 ARP Cache에 저장되어지게 되서 피해시스템은 disable된 시스템이 공격자의 시스템으로 알게되서 공격시스템과 피해시스팀과의 정상적인 통신이 가능하게 되어진다.

ARP 공격에 대응하기는 매우 어렵다. ARP공격에 대한 한가지 대응방법은 cache 엔트리의 lifetime을 줄이는 것이다. cache lifetime은 네트워크 커널 변수인 arp_cleanup_interval에 의하여 결정되어 진다. IP routing 테이블 엔트리의 lifetime은 커널 변수인 ip_ire_flush_interval에 의해서 조정되어 질 수 있다. 이에 대한 커널 변수는 다음과 같은 명령어의 실행에 의해서 가능하다.

# ndd -set /dev/arp arp_cleanup_interval <time>

# ndd -set /dev/ip ip_ire_flush_interval <time>

여기서 time은 millisecond를 의미한다. ARP Cache 만료 및 IP routing 테이블의 만료시간을 줄이는 것은 공격의 피해를 줄일수 는 있으나 근본적이 해결책은 아니다. 또다른 옵션은 일부 시스템에 대하여 정적(static)인 ARP 주소를 사용하면 가능하다. 정적인 ARP cache 엔트리는 영구적이어서 만료되지 않는다. 이러한 정적인 entry는 명령어 arp -d를 사용하여 제거되어 질수 있다.

5. IP Parameters

Solaris 커널은 IP 네트워크 프로토콜의 다양한 특징들에 대한 제어방법을 제공한다. 이러한 기능들은 몇몇의 파라미터들들을 통하여 제공된다. 많이 사용되는 parameter들은 다음과 같다

ip_forwarding

ip_strict_dst_multihoming

ip_forward_directed_broadcasts

ip_forward_src_routed

IP forwarding은 동일 시스템에 두개이상의 네트워크 인터페이스사이에 IP 패킷들을 라우팅하는 것을 일컷는다. 전형적으로로 이러한 기능은 라우터의 기능과 동일하다. Solaris를 가지고 설치된 시스템은 이러한 IP Forwarding을 잘 수행한다. 이러한 IP forwarding은 ip_forwarding 파라미터을 0으로 세팅하여 차단할 수 있다. IP Forwarding기능을 차단하기 위한 명령어는 다음과 같다.

#ndd -set /dev/ip ip_forwarding 0

침입자는 IP 패킷들을 forwarding하지 않는 multihomed server에 연결된 네트워크 경로로 패킷들을 발생 시키는 또다른 공격이 있을 수 있으므로 이러한 공격을 차단하기 위해서는 시스템의 IP 커널 변수인 ip_strict_dst_multihoming을 0으로 세팅하여 차단할 수 있다. 이렇게 시스템을 설정함으로써 연결된 하나의 네트워크로부터 또다른 네트워크 인터페이스로 발생되는 모든 패킷들이 차단되게 할 수 있다. 커널 설정은 다음과 같은 명령을 실행함으로써 가능하다.

#ndd -set /dev/ip ip_strict_dst_multihoming 0

Directed Broadcast는 외부 네트워크의 한 시스템으로부터 또 다른 네트워크의 모든 시스템에 보내어지는 패킷들을 말한다. Directed Broadcast는 "smurf"공격의 근간으로써 강제된 ICMP 패킷들이 하나의 호스트로부터 리모트 네트워크의 broadcast 주소로 보내어진다. ICMP패킷들의 출발지 주소는 피해를 입히고자 하는 시스템의 주소를 갖도록 강제로 설정할 수 있다. 그러면 원격의 네트워크에 있는 시스템들은 ICMP 패킷들을 받으면 이에 대한 응답으로서 응답 패킷이 피해호스트로 전송되어 진다. 대용량의 패킷을 받은 호스트은 flooding되게 된다. IP forwarding이 설정된 모든 솔라리스 시스템은 directed broadcast역시 forwarding할 것이다. directed broadcast의 forwarding기능을 해제하기 위해서는 ip_forward_directed_broadcasts 커널변수를 0으로 설정하면 될 것이다.

#ndd -set /dev/ip ip_forward_directed_broadcasts 0

패킷들이 한 네트워크의 호스트로부터 다른 호스트로 전달되어 질때, 라우팅서비스를 제공하는 호스트들이나 전용 라우터들에 의해 그들의 경로가 결정되어 진다. 그래서 IP는 출발지와 목적지사이에서 경로를 지정하는 기능을 가지고 있다. 이러한 기능들은 두가지 형태를 취할 수 있으며 하나는 strict source routing로서 패킷의 송신시스템이 출발지와 목적지사의의 중간의 모든 HOP마다 라우팅주소를 제공해주는 경우와, 다른 하나는 loose source routing으로서 송신측의 두 시스템 사이의 모든 경로를 선택함에 있어서 일부 몇개의 HOP만 지정해주고 나머지는 자유롭게 도달하도록 하는 방법이다. source routing은 네트워크 토폴로지상에서 보안체계를 우회하도록 사용될 수 있다. 물론 하나의 네트워크상에서 source-route된 패킷은 특별한 경우를 제외하고는 사용되지 않는다. 그렇기 때문에 IP Forwarding을제공하는 모든 호스트들은 Solaris kernel 변수인 ip_forward_src_routed를 0으로 세팅하여 source-route된 패킷들이 자동으로 드롭되도록 설정하여 운영하여야 한다. 설정방법은 다음과 같다.

#ndd -set /dev/IP ip_forward_src_routed 0

6. TCP Parameters

1997년 hrack Magazine의 기사에서 SYN flood로서 알려진 하나의 서비스거부공격을 기술하였다. 이러한 공격의 목적은 특정 시스템을 파괴하기 보다는 internet이나 intranet상에서 시스템이 네트워크 서비스를 불가능하게 만드는 것이다. 이러한 서비스 거부공격은 TCP연결의 기본방법을 이용하여 개발되었다.

하나의 시스템이 한 서버에 TCP를 사용하여 연결하고자 할때 sender는 처음 TCP/IP 패킷에 SYN bit를 설정하여 목적지에 발송한다. 이 SYN패킷은 TCP헤더에 SYN과 ACK 비트가 설정된 패킷을 가지고 목적지 시스템으로부터 응답받는다. 이 때 sender는 SYN-ACK패킷에 대한 응답으로서 ACK패킷을 보낸다. 이러한 방식을 "3-way handshake"방식이라 한다. 다음은 이러한 일련의 과정을 그림으로 설명한다.

sender(client) destination(server)

SYN -------------------------->

(sequence #: X)

<-------------------------- SYN-ACK

(sequence #:X+1, sequence #: Y)

ACK -------------------------->

(sequence #: Y+1)

이러한 과정에서 목적지 시스템이 sender에게 SYN-ACK패킷을 응답하고 ACK패킷을 sender가 응답하지 않을때 발생한다. 목적지 호스트는 "half-open"상태로 connection이 확립되기를 기다린다. 이때 srouce호스트가 목적지의 모든 가능한 TCP소켓 리소스를 고갈시킬때까지 이러한 half-open connection을 계속하게되면 목적지 시스템은 더이상의 TCP SYN패킷을 처리하지 못할 것이다. Solaris 시스템이 TCP SYN공격하에 있는지를 결정하는 한가지 방법은 SYN_RCVD상태에 있는 TCP connection의 갯수를 모니터링하는 것이다. SYN_RCVD상태의 connection은 다음과 같은 명령어를 통하여 확인 할 수 있다.

#netstat -an -f inet | grep SYN_RCVD

다음은 Solaris 7시스템이 SYN Flooding공격을 받고있는 동안에 위의 명령어를 실행한 결과이다.

[search:root]/user/ksch/dos > netstat -an -f inet | grep SYN_RCVD | more

127.0.0.1.80 172.16.10.1.14059 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.33931 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.61628 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.37302 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.27227 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.8350 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.52729 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.6407 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.63538 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.5467 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.33539 0 0 9112 0 SYN_RCVD

127.0.0.1.80 172.16.10.1.59230 0 0 9112 0 SYN_RCVD

............................................................................

............................................................................

127.0.0.1.80 172.16.10.1.59230 0 0 9112 0 SYN_RCVD

시스템이 정상적인 상태에서는 SYN_RCVD상태의 connection의 횟수가 거의 0이다.

다음은 SYN flooding공격을 받고있는 상태에서 SYN_RCVD상태를 카운트 한것이다.

[search:root]/user/ksch/dos > netstat -an -f inet | grep SYN_RCVD | wc -l

898

이러한 값은 시스템이 정상적인 환경하에서 작동할때의 기본적인 값과의 비교를 통하여 수행되어 질 수 있다.

Solaris는 시스템이 TCP SYN공격하에 있는지를 결정해주는 또다른 방법이 있다. 다음과 같은 명령어를 사용해서 하나의 TCP SYN공격이 확인되어질 수 있는 tcpHalfOpenDrop, tcpTimRetransDrop, tcp_ListenDrop 파라미터들의 값을 조사하면서 가능하다.

#netstat -s -P tcp

다음은 정상적인 시스템의 상태에서 TCP SYN Flooding공격을 받고있는 상태의 파라미터값들을 조사한 결과이다.

정상적인 상태에서는 tcpTimRetransDrop = 0, tcpListenDrop = 0,

tcpHalfOpenDrop = 0의 값을 유지하고 있었으나, 공격을 받은 상태에서는 tcpTimRetransDrop = 4243

tcpListenDrop = 0, tcpHalfOpenDrop = 140336의 값을 나타내었다. 다음은 TCP SYN Flooding공격을 받고있는 Solaris 7시스템의 커널 파라미터값을 조회한 결과이다.

[search:root]:/ > netstat -s -P tcp

TCP tcpRtoAlgorithm = 4 tcpRtoMin = 200

tcpRtoMax = 60000 tcpMaxConn = -1

tcpActiveOpens = 72503 tcpPassiveOpens =207964

tcpAttemptFails = 10067 tcpEstabResets = 27

tcpCurrEstab = 18 tcpOutSegs =3220622

tcpOutDataSegs =2857020 tcpOutDataBytes =270559996

tcpRetransSegs =315847 tcpRetransBytes =577759

tcpOutAck =363525 tcpOutAckDelayed = 10315

tcpOutUrg = 3 tcpOutWinUpdate = 42

tcpOutWinProbe = 118 tcpOutControl =734882

tcpOutRsts = 14378 tcpOutFastRetrans = 353

tcpInSegs =3872088

tcpInAckSegs =2909440 tcpInAckBytes =270664796

tcpInDupAck =189991 tcpInAckUnsent = 0

tcpInInorderSegs =2845248 tcpInInorderBytes =300182637

tcpInUnorderSegs = 1428 tcpInUnorderBytes =1034420

tcpInDupSegs = 2487 tcpInDupBytes = 23404

tcpInPartDupSegs = 76 tcpInPartDupBytes = 45970

tcpInPastWinSegs = 0 tcpInPastWinBytes = 0

tcpInWinProbe = 0 tcpInWinUpdate = 118

tcpInClosed = 27 tcpRttNoUpdate = 359

tcpRttUpdate =2841174 tcpTimRetrans = 110

tcpTimRetransDrop = 4243 tcpTimKeepalive = 1498

tcpTimKeepaliveProbe= 64 tcpTimKeepaliveDrop = 1

tcpListenDrop = 0 tcpListenDropQ0 = 0

tcpHalfOpenDrop =140336 tcpOutSackRetrans = 0

파라미터 tcpTimRetransDrop은 시스템 부팅후에 SYN 요구나 연결확립된 TCP 연결에 대하여 시간만료된 패킷의 수이며, 파라미터 tcpListenDrop은 시스템이 부팅한 후에 TCP queue backlog때문에 거절된 SYN 요구의 횟수를 의미한다. 또한 tcpTimRetransDrop의 값에 따라 tcpListenDrop 및 tcpHalfOpenDrop값이 빠르게 증가하면 해당 시스템이 TCP SYN 공격을 당하고 있을 확율이 상당히 높음을 나타낸다. 이러한 공격을 상쇄하기 위해서 관리자는 다음의 두가지 작업을 수행할 수 있다. 하나는 abort timer의 값을 더 짧게 하는 것이고 다른 하나는 TCP 연결 큐(queue)를 더 길게하는 것이다. abort timer를 짧게하기 위해서는 milli-second로 설정하는 커널 변수인 tcp_ip_abort_cinterval를 사용할 수 있다. 시스템 디폴트값은 180초로 설정되어 있다. abort timer를 60초로 설정하기 위해서는 다음과 같은 명령어를 실행하면 될것이다.

#ndd -set /dev/tcp tcp_ip_abort_cinterval 60000

(60000 = 60 * 1000)

연결확립(connection established)이 이루어지지 않은 패킷에대한 큐 크기는 커널 변수인 tcp_conn_req_max_q0(Solaris 2.6이상)를 사용할 수 있다. solaris 2.5.1은 patch 103581-11를 패치하여야만 한다. tcp_conn_req_max_q0의 디폴트 값은 1024이다. queue 크기를 증가시키기 위햐여 다음의 명령어를 실행시키면 된다.

#ndd -set /dev/tcp tcp_conn_req_max_q0 2048

SYN Attack의 또다른 방법은 연결확립된 TCP의 queue를 고갈시키는 것이다. 이러한 방법은 출발지 주소가 노출되기 때문에 SYN공격으로서는 잘 사용되지 않는 방법이다. 하지만 해킹에 성공한 서버등을 사용하는 방법을 통하여 사용될 수 있는 방법이기도 하다. Solaris 2.6이상(Solaris 2.5.1은 103582-11로 패치필요)에 대하여 tcp_conn_req_max_q의 커널 변수를 통하여 queue 크기를 증가시킬수 있다.

#ndd -set /dev/tcp tcp_conn_req_max_q <size>

여기서 <size>는 호스트에서 허용하는 TCP연결확립의 총 수를 의미한다. established 및 unestablished TCP연결에 대한 queue 크기를 증가시키기 위해서는 더 많은 메모리를 필요로한다. 따라서 충분한 메모리의 확보 없이 queue 크기를 증가시키면 서버의 performance에 영향을 줄수 있다. 뿐만아니라 서버가 처리할 수 있는 것보다 더 많은양의 half-open이나 established에 대한 TCP Connections을 발생시키면 이러한 서비스 거부공격은 성공할 것이다.

7. 결론

Solaris Kernel은 많은 Security관련 환경 파라미터를 가지고 있다. 이러한 파라미터들의 조정을 통하여 시스템의 security 대응능력을 증가시킬 수 있다. 이러한 Solaris Security 커널 변수들은 ARP timeout, 패킷들의 IP forwarding, 패킷들의 IP Source routing, TCP connection queue size, network connection들을 통제하는 많은 다른 요소들로 구성된다. 커널 변수들을 올바르게 tunning함으로써 시스템관리자는 Solaris System을 외부의 Security위협에 대하여 저항력 있는 서버시스템을 구성할 수 있을것이다.

8. 참고원문 :

http://www.securityfocus.com/focus/sun/articles/kernel.html

반응형