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

| Updated

사이트가 털리고나서 다시 복구하는 과정에 새로 추가한 내용들을 공유해 본다.

새로 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번 포트는 너무 알려져 있어 여기로 공격하는 경우가 많아 포트를 바꾼다.

2.2. ping 금지

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

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

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

이를 위해서는 방화벽 정책을 변경해 준다.
변경해야하는 설정 파일은 아래 경오를 참조

/etc/ufw/before.rules

아래 명령에서 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으로 변경

2.3. ssh 포트 변경

일반적으로 ssh포트를 22번을 사용하는데 이는 너무 알려진 포트이므로 이를 이용해 공격해오는 경우가 있다고 한다.

따라서 자기만아는 포트 번호로 변경 사용하는 게 필요하다.

이를 위해서는 먼저 sshd_config에서 22번대신 사용할 포트 번호로 바꾸어 준다. 즉

/etc/ssh/sshd_config 에서
Port 22 를 찾아서 자기가 사용할 포트 숫자를 기억하기 쉽고 10000자리이상에서 임의의 숫자를선택한다. 예를 들어 58722, 65322 등등

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

service ssh restart

그 다음 방화벽 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포트를 사용할 수 없게 한다.

2.4. Nginx 버전 숨기기

보안에 철저하려면 가능하는한 정보를 숨기는게 좋을 것 같다.

서버 시스템이 무엇이구 어떻게 구성되어 있는지 등등
물론 뚫리면 이런 정보야 쉽게 알 수 있겠지만 최소한 시간을 벌어 줄 수 있겠지.

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

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

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

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

server_tokens off; # Nginx 버전 숨기기 활성화

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

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

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

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

저도 참고하려는 사이트에서 php-info.php, phpinfo.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

여기서 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 버젼 확인
2.8.1. GeoIP 모듈 설치
cd GeoIP-1.4.8/   # GeoIP 버젼이 설치된 폴더로 이동
./configure
make
make install

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

cd ~
rm -rf GeoIP-1.4.8/    # GeoIP 다운로드 받는 거 삭제
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

이 설치된 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;

그리고 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;
           }
    }

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

/etc/init.d/nginx reload

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

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

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

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

먼저 Fail2Ban을 설치하자.

apt-get install fail2ban

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

vi /etc/fail2ban/jail.conf

여기에서 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의 보안 설정에 대해서 살펴 보았는데 기본적으로 이야기되는 사항을 정리해 본것으로 처음 접근 시 개략 방향을 잡는데 도움이 되었으면 한다.

서울에 생긴 Vultr 서버 100$ 프로모션 안내

안녕하세요?
새로운 사이트 구축을 위한 신규 서버를 고민하신다면 , 서울 리젼이 생겨 더욱 빨라진 Vultr 서버를 Vultr 100$ 프로모션으로 이용해 보세요.

아래 프로모션 코드 링크를 통해 Vultr에서 서버 구축 후 1달 이상 사용 및 $25이상 결제 時 추가 100$을 주는 프로모션을 진행 中입니다.

아래 이미지를 클릭해 등록할 수 있습니다.

Vultr는 서울에도 리젼이 있어 매우 빠르고, 아마존 웹 서비스(AWS)보다 성능이 높으며 가장 가성비가 뛰어납니다.

거기다 사용자 UI도 좋고, 15개까지 스냅샷을 무료로 제공하기 때문에 관리하기 좋습니다. 그리고 지금 100$ 프로모션처럼 가격적인 메리트도 있습니다.

저는 2016년부터 Vultr 서버를 사용했는데요. 지금까지 잘 사용해 오고 있습니다. 아래 사용기도 참고해 보세요.

도쿄 리젼과 비교해 본 Vultr 서울 리젼 사용기

가성비가 뛰어난 Vultr 가상서버호스팅(클라우드호스팅,VPS) 사용기

Vultr 가상서버호스팅의 새상품 High Frequency 사용기

가상 서버를 운영하고픈 勇者에게 전하는 가상 서버 운영 입문 노하우 – Vultr 가상서버호스팅(VPS)를 중심으로

해외 가상서버호스팅(VPS)이 국내 호스팅보다 빠르다? – 아이비호스팅과 해외 가상서버호스팅 VULTR간 비교

사이트 운영을 위한 안내 – 웹서버 세팅에서 워드프레스 설치까지(우분투 17.10, NGINX 1.13.6, Marian DB 10.2, PHP7.2)

워드프레스 최적화를 위한 18개월간의 고민, 그 노하우를 담다.

Subscribe
Notify of
guest
14 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Matthew

다른분들이 유용하게 사용할 수 있는 좋은 내용들을 많이 소개해 주셨네요.

server_tokens off; # Nginx 버전 숨기기 활성화

이것도 좋지만, 아예 허위정보를 제공하는 방법이 좋다고 합니다.

서버header 를 임의로 수정해서 완전 엉뚱한 내용이 표시되도록 하는거죠.

http://stackoverflow.com/questions/246227/how-do-you-change-the-server-header-returned-by-nginx

Nginx 인지도 모르게. 그리고 실제로 이렇게 하는 경우가 많습니다.

php extension 이 보이는걸 다른 extension 으로 바꾸는 것도 아주 좋은 방법입니다.

예를 들면 해커들이/해킹 스크립트 들이 이 주소를 찍어서 여기서 brute force 공격을 감행하거든요.

https://happist.com/wp-login.php

이걸 이렇게 바꿔 버리면,

https://happist.com/wp-login.html

접속이 안되고, 해킹스크립트 같은 경우 오류가 나버리죠.

http://robmalon.com/run-php-under-a-different-file-extension-in-nginx/

마지막으로, 유용한 정보를 공유해주고 계신데, 자스 (javascript) 으로 드래그, 우클릭 방지를 해 놓고 계셔서, 그 부분이 조금 아쉽습니다.

이건 웹이나 워드프레스 정신이 아니라서요…

http://hackya.com/kr/공유는-사랑입니다/

Matthew

타인이 내 글을 복사해서 올려주면 고마운겁니다. 왜냐하면 구글은 이런 사실을 인지하고 원글을 더욱더 부각시켜주거든요.

누가 제글을 퍼다가 대형커뮤니티 사이트에 올린걸 또 누가 이걸 퍼다가 다른 대형커뮤니티 사이트에 올리고. 그래도 원글이 가장 상위에 보여집니다. 그래서 고마워 해야 합니다. 방지할게 아니라.

https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=%EC%B2%9C%EC%A1%B0%EA%B5%AD%EC%9D%B4%20%EC%A7%88%EC%88%98

단지 네이버가 문제죠. 그런데 네이버는 검색bot 으로 정보수거를 거의하지 않습니다. 네이버는 검색엔진이라고 보기 어렵죠.

저도 nginx 각 환경 설정의 원리를 이해하지 않고
(이러면 서버 전문가되어야 하는것인가요?)모르고 모범답안이라고 불리는 환경설정 여러개를 copy & paste한 휴유증으로 보입니다.

미국에서 서버관리자, 서버전문가의 평균 월급이 다른 개발자들보다 낮습니다. 그 이유는 서버쪽 일은 돈이 안되는 일이라 그렇습니다.

워드프레스.com 의 경우도 서버관리인력은 겨우 4명이고, 이들은 큰 돈을 벌지 못합니다.

저번에 어느 젊은 개발자에게 제가 한소리 했는데, “생각없이 뭘 만들지 마라. 일단 내가 이 일을 해서, 내가 이 제품을 만들어 내서 어떤 금전적 이득이 생기는지 부터 생각하고 뭘 해라.” 라고 했거든요.

인생은 짧고, 시간은 몹시 소중합니다. 한번 지나간 시간은 다시 찾아올 수 없습니다.

이 짧은 인생을 의미있는 일만 해도 시간이 모자랍니다.

서버일을 생업으로 해도 금전적으로 별로 매력적인 일도 아닌데, 이걸 취미삼아 배우는거면, 극단적으로 인생낭비라고 까지 말할 수 있습니다.

물론 이쪽일이 재미있으시면 나름 의미있는 취미생활이 되겠죠. 그런데 저는 서버보다는 훨씬 더 재미있고, 흥미롭고, 결정적으로 돈이 되는 일들이 넘쳐나서요… ㅎㅎㅎ

Matthew

“이 어려운 서버를” – 서버쪽 친구들은 서버 무지 쉬운 기술이라고, 배울것도 없다고 합니다. ㅋㅋㅋㅋ

저도 똑같은 말을 합니다. 자스 (javascript) 는 몰라도 css 무지 쉽거든? 나는 왜 너가 아직도 css 를 못 익히는지 이해가 안가.

라고 합니다. 그냥 눈으로 보면 이해가 되는거거든? 왜 이해가 안되지?ㅋㅋㅋㅋ

제 친구는 제가 작업하는 내용을 하나도 몰라요. 이해도 안된데요. 그런데 그건 저도 마찬가지. ㅋㅋㅋㅋ

우성군

와우 좋은 정보들 많네요.

저도 적용해봐야겠습니다.

감사합니다.

[…] 내용은 q style=”text-align: left; color: #2196f3 ; font-size: 1.2em; “>가상서버호스팅에서 서버 보안 설정 방법 – Nginx +Ubuntu 16.04의 경우의 내용을 […]

[…] 내용은 q style=”text-align: left; color: #2196f3 ; font-size: 1.2em; “>가상서버호스팅에서 서버 보안 설정 방법 – Nginx +Ubuntu 16.04의 경우의 내용을 […]

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

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

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

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