back to top
0.4 C
New York
토요일, 12월 7, 2024

Buy now

IT가상서버호스팅 서버 보안 설정 방법 - Nginx +Ubuntu의 경우

가상서버호스팅 서버 보안 설정 방법 – Nginx +Ubuntu의 경우

사이트가 털리고나서 다시 복구하는 과정에 배운 내용을 기반으로 가상서버호스팅 서버 보안 설정 방법을 좀그 ㅁ더 자세하게 알아보자.

사이트가 털린 것 같다는 연락을 받고 바로 새로운 서버를 계약하고, 새로 OS 설치, Nginx, PHP7.0-FPM, MARIADB 등 기본 프로그램을 설치하고 pageSpeed, SSL 등을 설치한 다음 최종 Wordpress를 설치 후 데이타베이스 및 이미지 파일등을 복원하였다.

이러한 과정에서 해킹에 취약한 나의 사이트 보안 강화 방안에 대해서 고민하였고 아래는 그 그 과정을 간략히 정리해 보았다.

보안 관련해 이런 점을 고려했구나하는 정도로 이해해 주면 좋겠다.

1. 서버 재설치

사실 해커가 어디로 침투했는지도 모르고 (로그를 살펴보면 알 수 있다고하는데 이럴 여유조차 없어서, 바로 신규 세팅 작업에 들어갔다 ) 어디에 무슨 악성코드가 심어져있는지도 모르므로 기존 것을 전부 지우고 새로 설치하기로 했다.

vultr에서는 Servers – Setting – change hostname 을 선택해 hostname을 선택하고 reinstall을 누르면 새롭게 설치가 시작된다. 이는 기존 사이트는 그대로 둔 상태에서 서버만 준비할 수 있다는 점에서 가상서버의 장점 덕을 본 셈이다.

여기서 별도로 OS 등을 선택하는 메뉴는 없이 기존에 선택한 OS를 그대로 다시 설치해 준다.

설치 후 확인해 보니 Ubuntu 16.04 x64가 설치되어 있는 걸보니 위에서 이야기한 내용이 맞는 것 같다.

Vultr-호스트네임-변경

2. 보안 관련 조치들

서버 운영체제가 설치된 후 필요한 조치들을 해 준다. 인터넷 검색을 통해서 아래 사항들을 설정했다.

해커도 인터넷 정보를 토대로 해킹 방법을 찾는다고 한다.

그렇다면 이런 기본적인 조치들은 궁극적으로는 무용지물이겠고, 뚫리는데 걸리는 시간만을 지연해 줄 수는 있겠지만 그것만으로도 역활을 한다고 생각한다.

어느 정도 실력있는 해커가 덤빌정도로 가치있는 정보가 없는 사이트이기 때문에 너무 고난이도의 방어까지는 필요하지 않는다는 생각을 해봤다. 가치있는 정보가 있다면 그만큼 비용을 등여서 보안을 강화할 필요가 있을 것 같다.

테스트 삼아 접근하는 해커들을 방어할 정도의 순준이 필요할것으로 보여 준다.

2.1. Ubuntu 방화벽 – ufw 설정

서버를 세팅하기전에 맨먼저 해야하는게 방화벽 설정이라 할 수 있다. 사실 이 어려운 단어를 직접하게 될줄은 진정 몰랐다. 그러니 세상일이란 모르는 것이다.

우분투에서 방화벽은 iptables로 세팅하는데 이게 어렵기때문에 좀 더 쉽게 사용할 수 있도록 한 방화벽이 ufw라고 한다.

우분투를 설치하면 방화벽은 기본적으로 꺼져있다. 어떻게 세팅할지 모르기 때문에 세팅 후 이에 맞추어 방화벽을 가동하라는 의미라고..

그러므로 세팅이 끝나면 반드시 방화벽을 가동시켜야 한다.

나는 단순한것이 좋다고 ufw를 ssh 포트, 80포트, 443포트만 열어 놓았다.
이런 정보를 오픈한는 것도 보안에는 별 도움은 안되는 데 어쩔 수 없지 뭐..

ufw enable  # 방화벽을 활성화한다.
ufw allow 80/tcp  # 일반 웹 정보 관련 입출력 통로
ufw allow 443/tcp  # SSL 설치 시 웹정보 관련 입출력 통로 
ufw allow ****/tcp  # ssh를 위한 포트, 뒤에서 설명하겠지만 22번 포트는 너무 알려져 있어 여기로 공격하는 경우가 많아 포트를 바꾼다.
Code language: PHP (php)

2.2. ping 금지

해외 가성서버호스팅(VPS)를 사용하면서 ping 속도에 민감해 ping 정보를 자주 조회해 보곤 한다. 현재 속도가 얼마나 나오는지 궁금하므로..

일반적으로 서버를 구성한 경우 핑(ping)을 허용하고 있는 경우가 많다.
우분투 방화벽인 UFW의 기본 설정도 ping 요청을 허용하고 있다.

그런데 해킹 목적으로 네트워크 침입을 시도 시 핑(Ping)을 통해 특정 서버가 살아있는지 확인하는 경우가 많고, 고전적이긴 하지만 DDOS 공격 시 무한 핑(ping) 요청으로 서버를 무력화를 시도하는 경우도 있기때문에 핑(ping)을 허용하지 않는 게 좋다.

이를 위해서는 방화벽 정책을 변경해 준다. 변경해야하는 설정 파일은 아래 경로에 있는 /before.rules을 수정한다.

nano /etc/ufw/before.rulesCode language: PHP (php)

아래 명령에서 ACCEPT를 DROP으로 변경하거나 삭제해 준다.

  -A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT  → DROP으로 변경
  -A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT   → DROP으로 변경
  -A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT   → DROP으로 변경
  -A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT   → DROP으로 변경
  -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT   → DROP으로 변경
Code language: PHP (php)

2.3. ssh 포트 변경

일반적으로 ssh포트를 22번을 사용하는데 이는 너무 알려진 포트이므로 이를 이용해 공격해오는 경우가 있다고 한다. 따라서 자기만아는 포트 번호로 변경 사용하는 게 필요하다.

이를 위해서는 먼저 sshd_config에서 22번대신 사용할 포트 번호로 바꾸어 준다. 즉 /etc/ssh/sshd_config에서 Port 22 를 찾아서 자기가 사용할 포트 숫자를 기억하기 쉽고 10000자리이상에서 임의의 숫자를선택한다. 예를 들어 58722, 65322 등등

#Port 22
Port 58782
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::Code language: PHP (php)

이렇게 포트를 변경한 후 ssh 서비스를 재시작한다. 그리고 기존 ssh port로 사용했던 22번 포트는 접속할 수 없도록 막아준다.

service ssh restart
Code language: PHP (php)

그 다음 방화벽 ufw에서 정의해주고 FTP나 Terminal에서 접속 시 새로 설정한 포트 번호를 이용하면 된다.

ufw enable  # 방화벽을 활성화한다.
ufw allow 80/tcp  # 일반 웹 정보 관련 입출력 통로
ufw allow 443/tcp  # SSL 설치 시 웹정보 관련 입출력 통로 
ufw allow ****/tcp  # ssh를 위한 포트, 22번 포트는 너무 알려져 있어 여기로 공격하는 경우가 많아 포트를 바꾼다.
ufw deny 22/tcp  # ssh용으로 22포트를 사용할 수 없게 한다.
Code language: PHP (php)

2.4. Nginx 버전 숨기기

보안에 철저하려면 가능하는한 정보를 숨기는게 좋을 것 같다. 서버 시스템이 무엇이구 어떻게 구성되어 있는지 등등 물론 뚫리면 이런 정보야 쉽게 알 수 있겠지만 최소한 시간을 벌어 줄 수 있겠지.

그런 이미에서 Nginx 버젼을 숨기는 것도 필요하다. Nginx 버젼을 알면 그 버젼의 취약점을 토대로 보다 용이하게 해킹을 할 수 있다고 한다.

아무튼 Nginx 버젼을 숨기는 방법은 Nginx 환경 설정 파일에 아래 문구를 추가하는 것이다.

일반적으로 사용자가 잘못된 경로로 접근 시 에러메시지와 함께 nginx는 하단에 nginx의 버전을 표기해 준다,
앞에서 이야기한 대로 Nginx 버전 약점을 토대로 해킹을 시도하는 나쁜 해커가 있을 수 있으므로 이 문구는 에러메세지나 서버 정보 표현 시 Nginx 버전을 표기하지 않토록 하는 명령이다.

일반적인 Nginx 환경 설정 파일은 아래 경로에 있다.
/etc/nginx/nginx.conf

server_tokens off; # Nginx 버전 숨기기 활성화Code language: PHP (php)

2.5. PHP 버젼 정보 숨기기

Nginx 버젼 숨기는 것과 마찬가지로 PHP버젼을 알아서 도움이 되는게 없겠죠.

마찬가지로 이 버젼 정보를 숨기는 옵션을 선택한다. 이는 php.ini에서 expose_php = Off로 설정하면 끝.

참고 최근의 php7에서는 expose_php=off로 기본 설정되어 있다. php7을 쓴다면 별도 작업하지 않아도 된다.

; Decides whether PHP may expose the fact that it is installed on the server
; (e.g. by adding its signature to the Web server header).  It is no security
; threat in any way, but it makes it possible to determine whether you use PHP
; on your server or not.
; http://php.net/expose-php
expose_php = Off
Code language: PHP (php)

2.6. PHP-info.php 파일 지우기

이는 대단한 팁은 아닌데 일반적으로 서버 세팅을 하는 과정에서 PHP 관련 설치가 제대로 되었는지확인하기 위해 루트에 php-info.php 등의 이름이 붙은 php 파일을 올려놓아 사이트명 + php-info.php를 치면 php 관련 정보를 일목 요연하게 볼 수 있는 경우가 있다.

설치 과정이 끝나면 필요가 없는데 그냥 남겨 놓은 경우가 많은 것 같다.

나도 참고하려는 사이트에서 php-info.php, phpinfo.php 등등 몇가지 이름을 바꾸어 입력해보면 많은 사이트가 이 파일을 그대로 유지하고 있어서 php 정보를 쉽게 볼 수 있었던 많은 경험을 가지고 있다.

나처럼 초보도 이런 원시적인 방법으로 php 정보를 알아내는데 전문 해커야 두말할 필요가 없는 듯.. 그런데 이러것 말고도 인터넷에는 php 버젼등을 확인하는 방법이 널려 있는 듯..

결론 ; 설치가 끝나면 document root에 있는 php 정보를 볼 수 있는 php 파일을 삭제하자.

보안-Security관련-구글-무료-이미지

2.7. ipv6 차단하기

ipv6을 사용하겠다고 신청하긴 했지만 아직 그럴 단계가 아니라고 한다면 이를 사용하지 않토록 한다.

더우기 IPv4와 IPv6를 동시 사용 시 시스템 성능이 낮아 질 수 있으므로 굳이 사용하지 않는다면 IPv6를 사용하지 않토록 하는게 성능을 위해서도 좋다.

/etc/sysctl.conf 파일의 맨밑에 아래를 추가 한다.

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Code language: PHP (php)

여기서 0은 IPv6를 사용한다는 의미이고 1은 사용하지 않는다는 의미이다.

2.8. 특정 국가의 IP주소 일괄 차단하기

많은 해킹시도가 중국 러시아등에서 시작되고 있으므로 중국 러시아 IP는 막는것을 권장하고 있다.

중국과의 비지니스가 날로 커가고 있는 마당에 이런 정책은 필요악이라는 생각이 들지만 해킹을 당하고나니 생각이 달라졌다. 안전이 우선이라는 생각이…

그래서 중국과 러시아 IP는 막았다.

중국-해커


위 이미지는 구글에서 빌려왔다.

2.8.1. GeoIP 모듈 다운로드

Nginx를 라엘님의 블로그를 참조해서 설치했었는데 여기에서는 GeoIP 모듈은 포함되지 않았기에 추가 설치했다.

GeoIP 모듈이 설치되어 있는지 확인하는 방법은 (뭐 다 아시겠지만 한번 더 적으면) nginx -V를 치면 설치된 모듈들 리스트가 쭉 뜨는데 여기서 확인하면 된다.

GeoIP 모듈 설치는 아래와 같은 방법으로 진행한다.

wget http://www.maxmind.com/download/geoip/api/c/GeoIP.tar.gz   # 모듈 다운로드 합니다.

tar -xzvf GeoIP.tar.gz   # 압축을 풀어줍니다.

ls -l | grep GeoIP   # GeoIP 버젼 확인
Code language: PHP (php)

2.8.1. GeoIP 모듈 설치

cd GeoIP-1.4.8/   # GeoIP 버젼이 설치된 폴더로 이동
./configure
make
make install
Code language: PHP (php)

이 다음 설치 파일을 제거합니다.

cd ~
rm -rf GeoIP-1.4.8/    # GeoIP 다운로드 받는 거 삭제
Code language: PHP (php)

2.8.2. Installing The GeoIP Database

이는 GeoIP database에서 국가별 IP database를 확보하고 국가에 해당하는 IP는 막는 방법으로 nginx: How To Block Visitors By Country With The GeoIP Module (Debian/Ubuntu)라는 글을 토대로 작업하였다.

우분투에 GeoIP Database를 설치한다.

apt-get install geoip-database libgeoip1
Code language: PHP (php)

이 설치된 database는 /usr/share/GeoIP/GeoIP.dat에 저장됩니다.

가이드에서는 최신 dat로 업데이트하는 과정을 설명하고 있는데 여기서는 skip한다.

2.8.2. Configuring nginx

이번에는 Nginx 설정 파일에 관련 내용을 반영해 본다.
효과가 있으려면 http의 맨 앞에 위치하는 게 좋으며 특히 include 앞에 와야 한다.

http {
    #특정국가 IP 차단하기 
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    map $geoip_country_code $allowed_country {
        default yes;
        RU no;
        CN no;
    }
    include /etc/nginx/conf.d/*.conf;
Code language: PHP (php)

그리고 Location 설정 부분에서 허용되지않은 국가에서 접속 시 보여줄 화면을 지정한다. 예를 들어 403 (“Forbidden”) 또는 444 error code 등등

   location / {
       try_files $uri $uri/ /index.php?$args;
       index index.php index.html index.htm;
       if ($allowed_country = no) {
           return 444;
           }
    }
Code language: PHP (php)

마지막으로 Nginx를 다시 가동시킨다.

/etc/init.d/nginx reload
Code language: PHP (php)

2.9 Fail2ban을 설치하여 보안을 강화

로그를 분석해 의심스러운 접근을 금지시키는 방법이 DenyHosts나 Fail2Ban이라는 프로그램입니다.

이 중 Fail2ban은 DenyHosts보다 훨씬 진보된 방식으로 SSH, Apache, Courier, FTP 등등에서 의심스러운 접근을 차단할 수 있는 프로그램입니다.

Fail2ba은 로그 파일을 모니터링해서 넘 많은 패스워드 입력 실패나 공격 감행 징후들이 보이면 IP를 차단합니다.

먼저 Fail2Ban을 설치하자.

apt-get install fail2ban
Code language: PHP (php)

그 다음 설정을 변경한다. 이는 jail.conf 파일을 수정해야 한다.

vi /etc/fail2ban/jail.conf
Code language: PHP (php)

여기에서 ignoreip, bantime, findtime , maxretry 등을 수정해서 재구성한다.

  • ignoreip에는 ban을 하면 않되는 IP를 적는다. 10.100.102.103/32 형식으로 적으며, 추가는 스페이스바로 구분한다.
  • bantime은 접속 차단 시간으로 기본이 600(10분)으로 되어 있음
  • findtime은 통계를 찾을 시간.
  • maxretry 는 fail 횟수이다. 기본으로 5가 세팅되어 있는데 이 정도면 충분하다고 보고 유지했다.

3. 마치며

아파치에서는 Directory Indexing 비활성화 방안이 많아 소개되고 있는데 Nginx에서는 기본으로 비활성화되어 있는 것으로 보인다.

인터넷에서는 Nginx에서 어떻게하면 Directory Indexing을 보여줄 수 있는 팁이 많이 존재하는 것을 알 수 있다.

이상으로 간략히 Ubuntu + Nginx Server의 보안 설정에 대해서 살펴 보았는데 기본적으로 이야기되는 사항을 정리해 본것으로 처음 접근 시 개략 방향을 잡는데 도움이 되었으면 한다.

참고

7 COMMENTS

Subscribe
Notify of
guest
7 Comments
Oldest
Newest
Inline Feedbacks
View all comments