JNB
rss

skin by 이글루스

보안

손에 잡히는 리눅스 시큐리티 ② 06.10.02 18:42
[활용특집-리눅스 시큐리티] 손에 잡히는 리눅스 시큐리티 ②
  출판일 :2005년 4월호

 리눅스는 오픈소스의 장점으로 인해, 중소기업의 서버 플랫폼으로 사용되고 있다. 리눅스는 오픈소스이기 때문에 사용자들 스스로 신속하게 버그나 취약점을 발견해 업데이트하기 때문에 더 안정적일 수 있다는 의견이 있다. 하지만 관리자가 리눅스의 파워 유저가 아니라면, 리눅스의 보안 문제가 발생했을 때 좀처럼 관리하기 힘들다. 이 글을 통해, 리눅스 보안에 적합한 몇가지 명령어와 툴을 이용해 리눅스 보안에 접근해 본다.



홍석범_오늘과내일 네트워크사업본부 차장

Part 2.
사용자 접근 제어 설정


리눅스에서의 접근 제어는 클라이언트 IP나 접속하는 username 등을 기준으로 애플리케이션 계층, 커널(시스템) 계층으로 분류해 설정할 수 있는데, 먼저 애플리케이션 수준에서의 접근 제어에 대해 알아보자.

 

·MySQL 접근 제어
기본적으로 mysql은 3306/tcp에서 리슨하는데, 웹 서버와만 통신하면 되므로 외부에서의 직접 접속을 허용하지 않는 것이 좋다. 이를 위해서는 TCP/IP 포트 대신 유닉스 도메인 소켓을 이용하는 방법이 있는데, /etc/my.cnf 파일에 다음과 같이 추가하면 된다.

# cat /etc/my.cnf
[mysqld]
skip-networking

이후 MySQL을 재가동하면 로컬에서 MySQL을 사용할 수 있으면서도 3306/tcp에서 리슨하지 않는 것을 알 수 있으며 당연히 외부에서 3306/tcp로 접근하는 것이 불가능하다.

 

·OpenSSH 접근 제어
평문 데이터 전송의 위험성에 대해 사용자들의 인식이 확산되면서 최근에는 telnet 대신 ssh를 많이 사용하고 있는 추세다. 얼마 전까지만 해도 OpenSSH와 암호화 라이브러리인 OpenSSL에서 심각한 보안 취약성이 자주 발견돼 큰 문제가 되기도 했는데, 최근 버전에서는 상당 부분 안정화가 된 것으로 보인다. OpenSSH는 기본적으로 /etc/ssh/sshd_config 설정 파일을 참고하는데, 접근 통제와 관련된 설정을 알아보자.

① AllowGroups group1 group2
기본적으로 OpenSSH는 모든 사용자와 그룹에 대해 접근을 허용한다. 만약 특정한 그룹(Group)에 속한 사용자만 로그인을 허용하도록 하려면 이 옵션을 사용할 수 있다. 허용하고자 하는 그룹명을 지정하고 여러 개인 경우에는 이와 같이 스페이스바를 기준으로 추가로 나열하면 된다. 위와 같이 지정했을 경우 group1과 group2에 속하지 않은 사용자는 접근이 거부된다. 그룹명을 지정시 '*'나' ?' 등을 사용해 정규식을 이용할 수도 있다. 단, 그룹명 대신 553과 같은 GID는 지원하지 않는다.

② AllowUsers user1 user2
그룹과 마찬가지로 접속을 허용하고자 하는 사용자를 지정할 수 있다. 만약 특정한 사용자만 로그인을 허용하도록 하려면 이 옵션을 사용할 수 있다. 허용하고자 하는 사용자명을 지정하고 여러 개인 경우에는 스페이스바를 기준으로 추가로 나열하면 된다. 위와 같이 지정했을 경우 user1과 user2 이외의 사용자는 접근이 거부된다. 사용자명을 지정시 '*'나 '?' 등을 사용해 정규식을 이용할 수도 있다. 단, username 대신 553과 같은 UID는 지원하지 않는다. 만약 USER@HOST와 같이 지정했을 경우에는 특정한 호스트(IP)에서 특정한 사용자명으로의 접속만 허용된다.

③ DenyGroups group3 group4
기본적으로 OpenSSH는 모든 사용자와 그룹에 대해 접근을 허용하는데, 만약 특정한 그룹(group)에 속한 사용자들만 접속을 거부하고자 할 때에는 이 옵션을 사용할 수 있다. 거부하고자 하는 그룹명을 지정하면 되고 여러 개인 경우에는 스페이스바를 기준으로 추가로 나열하면 된다. 이와 같이 지정했을 경우 group3과 group4에 속한 사용자는 접근이 거부된다. 그룹명을 지정시 '*'나 '?' 등을 사용해 정규식을 이용할 수도 있다. 단, 그룹명 대신 553과 같은 GID는 지원하지 않는다.

④ DenyUsers user3 user4
그룹과 마찬가지로 접속을 거부하고자 하는 사용자를 지정할 수 있다. 만약 특정한 사용자만 로그인을 거부하도록 하려면 이 옵션을 사용할 수 있다. 거부하고자 하는 사용자명을 지정하면 되고 여러 개인 경우에는 위와 같이 스페이스바를 기준으로 추가로 나열하면 되는데, 이와 같이 지정했을 경우 user3과 user4 이외의 사용자는 접근이 허용된다. 사용자 명을 지정시 '*'나 '?' 등을 사용해 정규식을 이용할 수도 있다. 단, username 대신 553과 같은 UID는 지원하지 않는다. 만약 USER@HOST와 같이 지정했을 경우에는 특정한 호스트(IP)에서 특정한 사용자명으로의 접속만 거부된다.

⑤ PasswordAuthentication     yes
암호 기반의 인증을 허용할 것인지 지정한다. 기본값은 yes이다.

⑥ PermitEmptyPasswords    no
암호가 없는 계정에 대한 접근을 허용할 것인지에 대한 설정이다. 암호가 없는 계정은 보안상 위험할 수 있으므로 허용하지 않는 것이 좋다. 기본값인 no로 설정한다.

⑦ PermitRootLogin    no
root 계정의 직접 접근을 허용할 것인지에 대한 설정이다. 외부에서 root로 직접 로그인하는 것은 보안상 좋지 않으므로 이 옵션은 no로 설정하는 것이 좋다. 충분히 신뢰할 수 있는 네트워크이고 root로의 직접 접근에 문제가 없다면 yes로 설정해도 된다.

 

아파치 웹 서버의 접근 제어
많은 관리 프로그램이 클라이언트/서버 환경에서 웹 기반으로 옮겨가면서 더불어 웹 해킹도 증가하고 있다. 이를 위해 보안을 고려한 웹 애플리케이션을 개발하는 것도 중요하지만 웹을 통한 접근 제어를 엄격하게 유지하는 것 역시 중요하다. 특히, 관리자 모드 등에 대해서는 아무리 ID와 패스워드로  보호한다 하더라도 무작위 대입법으로 로그인이 가능할 수 있으므로 접근할 수 있는 IP 등을 엄격하게 제한하는 것이 좋다.
아파치(Apache)에서는 특정 파일이나 특정 디렉토리 이하에 대해 클라이언트의 IP나 ID/패스워드에 대한 접속 제한을 설정할 수 있는데, 아파치 설정 파일인 httpd.conf나 .htaccess 파일을 이용해 구현할 수 있다.
우선 httpd.conf에서의 설정 방법에 대해 알아보자. 만약 abc.com의 홈디렉토리가 /home/user1/html이고 관리자 모드가 http://abc.com/admin/이라면 /home/user1/html/admin 디렉토리 이하에 대한 접근 제어를 하면 될 것이다. 

 

<Directory /home/user1/html/admin>
Order deny, allow
Deny from all
Allow from 172.16.10.5   
</Directory>

 

이를 위해서는 httpd.conf 파일에 이와 같은 설정 후 웹 데몬을 재실행(killall -HUP httpd) 하면 관리자 모드에 접근할 수 있는 IP는 172.16.10.5만 가능하게 될 것이다.
또는 httpd.conf를 사용하지 않고 .htaccess 파일을 이용하는 방법도 있다. 이를 위해서는 접근 통제를 할 디렉토리에 다음과 같이 설정하면 되는데, 먼저 Limit에서 지정한 GET과 POST는 접근 제어를 할 방법(Method)를 뜻한다. GET은 html이나 이미지 등 서버의 데이터를 읽을 때 사용되고, POST는 파일을 업로드하거나 게시판에 글을 쓰는 등 서버에 데이터를 전송할 때 사용된다.

 

<Limit GET POST>
  order deny,allow                                                      
  allow from 192.168.1.6                
  deny from all
</Limit>

 

이같은 예는 해당 디렉토리 이하에 대해서 192.168.1.6에서만 GET이나 POST Method를 허용한다는 의미가 된다.

(화면 12)는 허용되지 않은 IP에서 접속했을 때 접속이 거부된 것을 보여주고 있다. 이 때의 error_log를 보면 다음과 같이 보이게 된다.

[Thu Mar 10 17:13:11 2005] [error] [client 222.235.xx.xxx] client denied by server configuration: /usr/local/apache/htdocs/index.html

IP 뿐만 아니라 ID/패스워드로도 인증하도록 설정할 수 있다. 이는 접근 제어를 할 디렉토리에 .htaccess 파일을 생성하고 다음과 같이 설정하면 된다. 이후 다음과 같이 htpasswd라는 프로그램을 이용해 ID/패스워드를 생성하도록 한다.

 

# htpasswd -c /var/data/.htpasswd onthenet
New password: xxxx
Re-type new password: xxxx
Adding password for user onthenet

 

(화면 12) 허용되지 않은 IP 접속 거부

 

이때 -c는 create의 의미로 .htpasswd 파일을 처음 생성할 때만 사용하는 옵션이다. 이 옵션을 사용하면 지정한 파일을 초기화하므로 기존에 이미 존재하는 파일에 추가하고자 할 경우에는 -c를 빼고 설정하면 된다.
이후 웹으로 .htaccess가 있는 디렉토리에 접속을 시도하면 다음과 같이 ID/패스워드를 입력하는 창이 뜨게 되고 이미 생성된 ID/패스워드를 입력해야만 해당 사이트에 접속할 수 있게 된다(화면 13). httpd.conf를 이용하던지 .htaccess등을 이용하는지는 각자의 환경에 따라 적당한 방법으로 이용하면 된다.
  
(화면 13) ID/패스워드를 묻는 화면

 

proftpd 접근 제한
최근에는 ftp 서버로서 속도나 안정성이 뛰어난 proftpd를 많이 사용하고 있는 추세다. proftpd의 설정 파일은 앞에서 살펴본 아파치와 매우 유사한 지시자(directive)를 제공하고 있는데, 다음에서 설명하는 몇 가지만 알면 된다.

 

·RootLogin off
telnet이나 다른 서비스와 마찬가지로 root 계정으로 ftp를 접속하는 것은 보안상 좋지 않은 방법이다. 특히 ftp로의 접속 과정은 평문으로 전송되기 때문에 스니핑을 통해 암호가 유출될 수 있기 때문이다. 따라서 ftp를 통한 root 로그인은 허용하지 않도록 하기 위해 proftpd.conf 파일에 설정하는 것이 좋다.

 

·DefaultRoot                    
ftp로 접속시 초기 접속한 홈디렉토리 이외의 상위 디렉토리에 대해서는 접근을 제한하고자 할 때 사용된다. 위와 같이 설정후 ftp로 접속하면 현재 디렉토리가 최상위인 /으로 보이게 된다.

 

·IP 대역 접속 제한하기  
ftp 서버에 접속을 허용할 IP를 제한 설정할 수 있다. 따라서 아무리 ID/패스워드를 알고 있다 하더라도 사전에 허용된 IP 이외에서의 접속은 거부될 것이다. 이를 설정하려면 아파치에서와 같이 <Limit>를 이용하면 되는데, 한 가지 아파치와는 allow와 deny의  순서가 반대라는 점을 주의하기 바란다.

 

<Limit LOGIN>
  Order allow,deny
  Allow from 192.168.10.5
  Allow from 192.168.10.6
  Deny from all
</Limit>

 

이를테면 이와 같이 설정됐을 경우 192.168.10.5나 192.168.10.6에서의 ftp 접속은 허용되지만 이외의 모든 접속은 거부된다. 

Bind DNS 접근통제
DNS는 인터넷 서비스의 가장 기본적인 서비스이며 따라서 DNS에 장애가 유발될 경우에는 그 피해가 매우 크다. 따라서 DNS 역시 엄격한 접근 통제를 설정해 꼭 필요한 서비스만 허용하는 것이 좋다.

 

·순환 질의 제한
DNS 프로토콜 자체의 취약성으로 인해 캐시 포이즈닝(Cache poisoning) 공격은 언제나 존재할 수 있다. 최근에도 몇몇 DNS에서 글로벌 캐시 포이즈닝 공격이 있었는데, 이를 차단하기 위해서는 물론 안정한 버전의 프로그램을 이용하는 것도 중요하지만 가급적 허용된 IP 이외에서의 순환 질의를 제한하는 것이 좋다. 물론 ISP 등과 같이 불특정 다수에게 DNS 서비스를 제공하는 경우라면 어쩔 수 없겠지만 그렇지 않은 경우에는 엄격하게 제한해 설정하기 바란다.
이를 위해서는 다음과 같이 named.conf 파일에 순환 질의를 허용할 IP 대역을 지정하면 되는데, IP 대역이나 IP가 더 있을 경우에는 ;을 기준으로 계속 추가하면 된다. 

options {
        directory "/var/named";
        allow-recursion {127.0.0.1; 192.168.10.0/24; };
};

 

이와 같이 설정 후 허용되지 않는 IP에서 해당 DNS에 정의되지 않은 도메인에 대해 질의하면 다음과 같이 응답하지 않는 것을 알 수 있다.

(화면 14) 순환 질의 응답 화면

·zone transfer 제한
zone transfer는 master와 slave 서버간에 zone 파일을 동기화하기 위해 사용되는 것으로, master/slave를 사용하지 않는다면 이 설정을 차단하는 것이 좋으며 만약 slave를 운영한다면 slave에서만 zone transfer가 가능하도록 설정하는 것이 좋다. 만약 그렇지 않을 경우에는 불필요한 정보를 유출할 수 있어 보안에 악영향을 끼칠 수 있다.
먼저 /etc/named.conf 파일에 다음과 같이 설정하면 192.168.10.3에서만 zone transfer를 허용하겠다는 의미가 되며 이외에서의 zone transfer는 차단하게 된다.

 

options {
        allow-transfer { 192.168.10.3; };
};

 

만약 slave없이 1개의 DNS만 운영한다면 zone transfer 자체를 허용할 필요가 없으므로 다음과 같이 zone transfer 자체를 거부하도록 설정하는 것이 좋다.

 

options {
        allow-transfer { none; };
};

 

xinetd 접근 통제
xinetd는 기존의 inetd에 대한 확장된 기능을 제공하는 수퍼서버 데몬으로서 telnet이나 pop3등의 서비스를 제어하며 xinetd 자체에서 접근 통제를 설정할 수 있다. 예전에 inetd에서는 자체적인 접근 제어 기능이 없어 tcp wrapper와 연동해 /etc/hosts.allow나 /etc/hosts.deny 파일에서 제어했으나 xinetd에서는 자체적으로 접근 제어를 제공하고 있다. 물론 xinetd도 tcp wrapper와 연동할 수 있다.
xinetd에서는 특정한 IP에서만 접근을 허용하는 only_from과 특정한 IP에서의 접근을 거부하는 no_access를 사용할 수 있는데, 간단한 예를 들어 살펴보도록 하자. 다음의 경우 pop3 서비스에 대한 설정인데, 먼저 only_from에서 localhost와 198.72.5.0를 허용했다. 여기에서 198.72.5.0는 198.72.5.0/24라는 의미로서 198.72.5. 대역의 모든 IP를 의미한다. 그 다음으로 no_access에서는 192.168.10.3과 198.72.5.10이 설정돼 있는데, 먼저 only_from이 설정돼 있으면 이 곳에서 허용된 IP 이외의 모든 IP에서의 접근은 거부되므로 사실상 192.168.10.3은 의미가 없다. 다만, 198.72.5.10의 경우 198.72.5.0 대역은 이미 허용돼 있지만 198.72.5.10이 거부돼 있다면 더 구체적인 IP 설정이 적용되므로 198.72.5.10은 접근이 거부된다.

service pop3
{
    socket_type    = stream
    protocol       = tcp
    wait           = no
    user           = root
    only_from      = 198.72.5.0 localhost
    no_access      = 192.168.10.3 198.72.5.10
    server         = /usr/sbin/ipop3d
}

이외 다른 애플리케이션이 있다면 각각의 config에서 접근할 수 있는 IP나 ID 등에 대한 설정이 있으므로 이 설정을 최대한 이용하기 바란다. 그러나 프로그램에 따라 접근 제어 기능이 존재하지 않거나 설정 기능이 미약한 경우도 많다. 또한 기존의 접근 제어 설정이 존재한다해도 애플리케이션 수준의 제한이다 보니 짧은 시간에 계속적인 접근 시도를 할 경우 부하 상승 등의 문제가 유발될 수 있다. 이같은 경우를 대비해 커널 레벨의 접근 제어 기능도 함께 사용하는 것이 좋은데 가장 대표적인 프로그램은 netfilter 기반의 iptables이다. iptables는 기본적으로 커널에 내장돼 있어 별도의 설정없이 사용할 수 있는데, 혹 커널에 포함되어 있지 않다면 모듈로 올리거나 커널에 정적으로 포함시켜야 한다.

 

iptables를 이용한 접근 통제
iptables의 사용법은 매우 복잡하므로 자세한 사용 방법은 man 페이지나 iptables 홈페이지(http://iptables.org/)를 참고하기 바라며 여기에서는 간략한 사용 방법만 살펴보도록 하자.

#!/bin/sh

iptables -F
iptables -P INPUT ACCEPT
iptables -A INPUT -p tcp -s 0/0 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 0/0 --dport 25 -j ACCEPT
iptables -A INPUT -p udp -s 0/0 --sport 53 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 110 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 22 -j ACCEPT
iptables -P INPUT DROP
 
이와 같이 설정해 파일을 실행하면 단순하지만 기능은 강력한 파이어월로 작동하게 된다. 먼저 iptables -F는 기존에 룰이 있을 수 있으니 기존의 룰을 모두 초기화하는 것이다. iptables를 실행할 때 제일 먼저해야 할 부분이다. 두 번째는 INPUT 즉 파이어월이 가동중인 서버에 들어오는 트래픽에 대한 기본 정책을 허용해 설정하는 것이다. 이는 만약에 기본 정책이 DROP으로 설정돼 있을 경우에 -F로 초기화하면 기본 정책만 남게 되므로 일체의 접속이 끊기게 되므로 주의해야 한다. 따라서 -F 대신 -P를 먼저 실행하는 것도 좋다. 이제 세 번째 줄부터 본격적인 룰 설정에 들어가게 되는데, 세 번째 줄은 tcp 트래픽중에서 소스 IP에 관계없이(-s 0/0) 목적지 포트가 80번인 즉 웹 트래픽을 허용하겠다는 의미다. 여기에서 0/0은 any의 의미이며 모든 IP 어드레스를 뜻한다. 그 다음줄 역시 25(smtp) 트래픽을 허용한다는 의미로서 외부에서 들어오는 전자우편을 받으려면 설정이 돼있어야 한다. 다음 줄은 내부에서 외부 DNS에 질의를 요청했을 때 응답하는 트래픽을 허용하는 것으로 설정하지 않으면 DNS 트래픽도 차단하게 돼 일체의 DNS가 작동하지 않게 된다. 만약 내부에 DNS 서버를 가동해 서비스한다면 --dport 53도 추가적으로 허용해야 한다. 다음으로는 110(pop3)과 22(ssh) 서비스에 대해 10.0.0.0/24 대역에서만 접근할 수 있도록 설정한 것으로 다른 서비스에 대해서도 같은 방식으로 계속 추가할 수 있을 것이다. 마지막으로 룰에 설정되지 않은 트래픽에 대해서는 마지막에 설정한 기본 정책에 따라 차단하게 된다. 참고로 지금까지는 인풋(input) 트래픽에 대해서만 설정했는데, 이는 아웃풋(output) 트래픽은 기본적으로 허용돼 있기 때문이며, 만약 아웃풋 트래픽도 설정하려면 룰이 다소 복잡해진다.
iptables에 대해 간략하게 알아봤지만, 문서를 보면 상태 추적 등 더 많은 기능과 다양한 옵션이 존재한다. 따라서 문서를 살펴보고 100% 파이어월을 활용할 것을 권장한다.

 

-온더넷 2005년 4월호


        

    
Copyright 1999-2018 Zeroboard / skin by JY