IT보안따라잡기

우분투 APM 웹서버 구축하기 본문

정보보안/시스템

우분투 APM 웹서버 구축하기

보안바라기 2019. 2. 4. 07:34
반응형

우분투 APM 웹서버 구축하기 ]

우분투(Ubuntu)란?

- 컴퓨터에서 프로그램과 주변기기를 사용할 수 있도록 해주는 운영체제(OS:Operating System) 중 하나

- 리눅스의 데비안 계열 배포판 중 하나

- 캐노니칼(Canonical)사의 지원을 받아 무료로 배포되어 사용가능

- 우분투라는 이름은 '네가 있기에 내가 있다'라는 타인을 향한 인류애를 뜻하는 반투어


사용 가능한 패키지 및 버전들의 리스트를 업데이트 하는 명령어

# apt-get update

패키지들을 실제로 최신버전으로 업그레이드 하는 명령어

# apt-get upgrade


* 관리자(root)로 작업하기 위해 다음과 같이 관리자로 전환시켜주는 명령어를 입력한다.

# sudo su -

( sudo는 관리자 권한으로 실행을 의미, su는 계정을 스위칭하는 명령, - 는  PATH나 기타 여러가지 환경변수를 포함하여 전환 )


현재 운영체제의 버전 정보를 출력하는 명령어

# uname -a

# lsb_release -a

- 현재 우분투 4.18.0.10으 18.10 버전에서 구축할 예정


Hostname 설정하기

# vi /etc/hostname

- 해당 파일에서 자신의 서버를 대표할 도메인 이름 작성


# hostname -F /etc/hostname

- 작성한 hostname을 적용 ( -F는 file명 옵션 )


# vi /etc/hosts 

- 설정한 호스트 네임으로 127.0.1.1 우측에 사용자명으로 수정


메일 서비스를 사용하기 위해서는 다음과 같은 명령어를 이용하여 설치

# apt-get install sendmail

* Sendmail은 인터넷에서 전자메일을 전송하기 위해 사용되는 프로그램 또는 데몬 서비스


본격적으로 아파치 설치 진행

# apt-get install apache2

( 아파치란 아파치 재단에서 만든 소프트웨어로 정적인 데이터를 처리하는 웹 서버 )


아파치 버전을 확인하는 명령어

# apache2 -v


파이어폭스 웹브라우저 접속 후 URL에 localhost를 입력하여 아파치가 정상적으로 작동하는 지 확인

* 파이어폭스가 켜지지 않을 경우 # su - (사용자명) 으로 다시 전환 후 켜야 함

* localhost를 입력하여도 연결 실패가 나올 경우 # systemctl start apache2 로 아파치를 기동시켜주어야 함

* 해당 페이지는 아파치 초기 구축 시에 /var/www/html/index.html 에 기본적으로 생성되는 페이지


다음과 같이 아파치의 모듈을 활성화 또는 비활성화 시키는 명령어로 문제를 최대한 발생하지 않도록 설정

( 해당 명령이 실행되지 않을 경우 root 계정으로 진행할 것 )

# a2enmod rewrite

# a2enmod headers

# a2enmod ssl

# a2dismod -f autoindex


아파치 웹 서버에서 접근되어서는 안되는 파일들을 필터링하기 위해 해당 아파치 설정 경로에 다음과 같은 구문 추가

# vi /etc/apache2/apache2.conf


<FilesMatch “^\.ht”> 태그가 끝나는 구문 밑에 다음과 같은 내용들을 추가


# deny file, folder start with dot

<DirectoryMatch "^\.|\/\.">

    Require all denied

</DirectoryMatch>

  

# deny (log file, binary, certificate, shell script, sql dump file) access.

<FilesMatch "\.(?i:log|binary|pem|enc|crt|conf|cnf|sql|sh|key|yml|lock|gitignore)$">

    Require all denied

</FilesMatch>

  

# deny access.

<FilesMatch "(?i:composer\.json|contributing\.md|license\.txt|readme\.rst|readme\.md|readme\.txt|copyright|artisan|gulpfile\.js|package\.json|phpunit\.xml|access_log|error_log|gruntfile\.js|bower\.json|changelog\.md|console|legalnotice|license|security\.md|privacy\.md)$">

    Require all denied

</FilesMatch>

 

# Allow Lets Encrypt Domain Validation Program

<DirectoryMatch "\.well-known/acme-challenge/">

    Require all granted

</DirectoryMatch>


다음과 같은 명령어로 php 설치를 진행
# apt-get install php
* php(PHP:Personal Home Page Tools -> Hypertext Preprocessor)는 웹 서버를 동적으로 사용하기 위한 서버측 프로그래밍 언어

PHP와 아파치를 연동하기 위한 모듈 설치 (PHP 설치시 기본적으로 설치됨)
# apt-get install libapache2-mod-php7.2

특정한 패키지에 대해 확인하고 싶은 경우 다음과 같은 명령어를 입력
# apt-cache search (확인하고 싶은 패키지) -> 검색한 패키지명의 목록이 나열

마찬가지로 php에 대한 버전을 확인하기 위한 명령어
# php -v

* php 설치 완료 후 아파치 재기동

MariaDB 설치 명령어
# apt-get install mariadb-server

MariaDB 데이터베이스 초기화 작업 명령어
# /usr/bin/mysql_secure_installation

MariaDB와 PHP 연동모듈 설치 명령어
# apt-get install php-mysql

MariaDB 버전 확인 명령어
# mysql -V ( **대문자 주의** )

MariaDB 기본 언어셋 설정 ( DB가 latin1으로 생성되어, 추후 DB 작업 시 문제가 생길 수 있음 )
# vi /etc/mysql/mariadb.conf.d/50-server.cnf
해당 경로에 다음과 같은 2줄을 추가하여 utf8확장 형식으로 변환시켜줘야함


MariaDB 재시작 명령어

# service mysql restart


PHP 권한 설정
- 웹 서비스 구동 시 발생할 수 있는 Nobody 퍼미션 관련 문제를 해결하기 위한 프로그램 설치
- 해당 세팅을 적용 시에 shell 및 Web 권한이 동일하게 취급되며, 보안성이 향상
# apt-cache search mpm-itk
# apt-get install libapache2-mpm-itk
# chmod 711 /home
# chmod -R 700 /home/*


PHP 실행확장자 변경
- php를 해석하는 여러 가지 확장자들로부터의 위협을 방지하기 위해 해당 경로에 다음과 같은 필터링 설정
# vi /etc/apache2/mods-available/php7.x.conf

* 적용을 하기 위해서는 아파치 재시작


PHP Default Timezone 설정
- 기존에 시스템 Timezone을 이용하지 않고 별도로 지정
Apache2 - PHP 연동 시 참조하는 설정파일
# vi /etc/php/7.x/apache2/php.ini
Cron 및 Console에서 PHP를 직접 실행 시 참조하는 설정파일
# vi /etc/php/7.x/cli/php.ini

다음과 같이 data.timezone에 Asia/Seoul로 설정


* Apache2 재기동하기


계정생성 및 동작테스트


계정을 생성하는 명령어

# adduser myuser1

* useradd와 adduser로 2가지가 존재함

( 레드햇 계열의 경우 2가지 모두 동일하지만, 우분투의 경우는 약간의 차이점이 존재 )

useradd

- 계정을 생성할 경우 -m 옵션을 통해 별도로 홈 디렉토리를 함께 생성시켜 주어야 함

- passwd 명령어를 통해 패스워드도 별도로 생성

adduser

- 사용자 정보를 입력하는 과정이 함께 진행됨 ( 패스워드 및 기본 정보 입력 )

 

웹 루트의 경우 홈 디렉토리에 생성하지 않으며, 주로 www 디렉토리를 이용하여 관리

# su -l myuser1

# mkdir www

# exit


웹 사이트 아파치 환경설정파일 작성

- 환경설정을 쉽게하도록 도와주는 환경설정 생성기 ( https://webmaster.cafe/tools/apache-conf-generator/ )


# vi /etc/apache2/sites-available/파일명.com.conf ( 서버에서 운영할 사이트의 설정파일 )

<VirtualHost *:80>

    #main domain

    ServerName jkl.com


    #additional domain

    ServerAlias www.jkl.com

    ServerAlias my-anotherdomain.com


    #document Root

    DocumentRoot /home/myuser1/www/


    #additional setting

    <Directory /home/myuser1/www/>

        Options FollowSymLinks MultiViews

        AllowOverride All

        require all granted

    </Directory>


    AssignUserID myuser1 myuser1


    ErrorLog ${APACHE_LOG_DIR}/jkl-error.log

    CustomLog ${APACHE_LOG_DIR}/jkl-access.log combined

</VirtualHost>


SSL(https)로 암호화 통신을 적용하고 싶을 경우 다음과 같은 코드를 추가 ( VirtualHost 영역 추가 )

<VirtualHost *:443>

    ServerName jkl.com

    ServerAlias www.jkl.com

    

    DocumentRoot /home/myuser1/www


    <Directory /home/myuser1/www>

        Options FollowSymLinks MultiViews

        AllowOverride All

        require all granted


        # upload_max_filesize and post_max_size must have the same value.

        php_value upload_max_filesize 10M

        php_value post_max_size 10M


        # Enhance session security.

        php_value session.cookie_httponly 1

        php_value session.use_strict_mode 1


        # php_value memory_limit 128M

        # php_value max_execution_time 30

        # php_value max_input_time 60

    </Directory>


    AssignUserID myuser1 myuser1


    ErrorLog ${APACHE_LOG_DIR}/jkl-error.log

    CustomLog ${APACHE_LOG_DIR}/jkl-access.log combined


    Header always set Strict-Transport-Security "max-age=31536000"


    SSLEngine on


    SSLProtocol all -SSLv2 -SSLv3


    SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA


    SSLHonorCipherOrder on

    SSLCertificateFile "/etc/letsencrypt/live/myuser1.com/cert.pem"

    SSLCertificateKeyFile "/etc/letsencrypt/live/myuser1.com/privkey.pem"

    SSLCertificateChainFile "/etc/letsencrypt/live/myuser1.com/chain.pem"


    # Turn on OCSP stapling

    SSLUseStapling on

    SSLStaplingResponderTimeout 5

    SSLStaplingReturnResponderErrors off


</VirtualHost>


사이트 활성화 및 비활성화 적용 명령어

# a2ensite jkl.com

# a2dissite jkl.com


아파치 설정 재적용 명령어

# service apache2 reload ( 서버가 재기동되지 않으며, 설정만 변경 )


연동테스트 진행하기


APM를 모두 사용하는 프로그램 실행시키기

phpmyadmin 공식사이트 -> https://www.phpmyadmin.net/


압축 해제 프로그램 설치

# apt-get install unzip ( 기본적으로 설치되어 있음 )


경로 이동 후 압축 파일 다운로드 및 압축 해제

# cd /var/www/html

# wget https://files.phpmyadmin.net/phpMyAdmin/4.5.2/phpMyAdmin-4.5.2-all-languages.zip

# unzip phpMyAdmin-4.5.2-all-languages.zip

# mv phpMyAdmin-4.5.2-all-languages dbmyadmin

# rm phpMyAdmin-4.5.2-all-languages.zip

다음과 같이 자신의 웹 서버에서 dbmyadmin 디렉토리로 이동 시 APM 접속 화면이 나타남


로그인을 하기 위해서 데이터베이스에서 사용자를 추가하여 권한 설정을 해주어야 함

# mysql -u root -p

# use mysql;

# create user '사용자명'@'localhost' identified by '패스워드';

# grant all privileges on *.* to '사용자명'@'localhost';


아파치 추가 보안 설정

# vi /etc/apache2/conf-available/charset.conf


기본 언어셋 설정

다음과 같이 앞에 있는 '#' 주석을 해제하여 언어를 UTF-8로 설정

(# AddDefaultCharset UTF-8 -> AddDefaultCharset UTF-8)


추가 보안 설정

# vi /etc/apache2/conf-available/security.conf


다음과 같이 설정들의 주석을 해제


SSH 기본 포트번호 변경

- 무작위 대입공격(Brute Force Attack)으로부터 시도를 차단

- 기본적인 22번 포트를 사용할 경우 자동으로 무작위 로그인 시도를 하는 프로그램들이 많음


IPTABLES 방화벽, SSH 포트번호 변경, Fail2ban 중 한 가지를 적용

- 클라우드를 사용하고 있을 경우 -> 클라우드 방화벽 사용 권장

- 허용된 IP만 서버에 접속 설정 -> IPTABLES 설정

- 사용자의 IP를 특정지을순 없지만 무차별대입 공격 방어 -> Fail2ban

- 자신의 포트 번호로만 접근 허용 -> SSH 포트 변경


* Fail2ban

- 침입 차단 소프트웨어 프레임워크로 컴퓨터 서버를 무차별 대입 공격으로부터 보호

- 파이썬 프로그래밍 언어로 제작됨


# vi /etc/ssh/sshd_config

- 해당 부분의 '#'으로 주석을 해제한 후, 원하는 포트번호로 설정 ( 충돌되지 않는 번호 권장 )

- 포트번호 설정은 되도록 10000번 이상의 숫자를 선택


서비스 재시작

# service ssh restart


방화벽 적용하기

# iptables -L ( 설정된 iptables 확인 )


방화벽 설정 삭제

# iptables -F


INPUT - 서버로 들어오는 패킷 관리

FORWARD - 서버에서 내부망으로 연결관리

OUTPUT - 서버에서 나가는 것 관리


# mkdir firewall_rules

# cd firewall_rules


IP가 192.168.59.129에 대해 도착지 포트가 22번이면 접근 허용 ( -m state --state -> 플래그 지정 옵션 )

# iptables -A INPUT -s 192.168.59.129/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT


설정된 IPTABLES의 내용들을 파일에 저장

# iptables-save > 190209.rules(현재날짜)


파일에 저장된 IPTABLES 설정을 적용

# iptables-restore < 190209.rules(현재날짜)


재부팅 시에도 설정을 지속시키기 위한 IPTABLES 설치

# apt-get install iptables-persistent

- /etc/iptables 폴더가 생성되며, rules.v4, rules.v6 파일이 생성됨

해당 설정을 재부팅 시에도 적용시키는 명령

# iptables-save > /etc/iptables/rules.v4

커널 변수의 값을 제어하여 시스템을 최적화할 수 잇는 명령어

# sysctl


IPv6 차단설정

# vi /etc/sysctl.conf

net.ipv6.conf.all.disable_ipv6 = 1

net.ipv6.conf.default.disable_ipv6 = 1

net.ipv6.conf.lo.disable_ipv6 = 1


설정 파일 적용

# sysctl -p


계정별 트래픽 양 제한하기 ( mod_cband )

- apache2 버전에서 홈페이지의 히트(hit)수 제한 및 도메인별 대역폭 제한 등 트래픽을 관리하기 위한 모듈

- 순간속도(대역폭), 총 전송량(쿼터), 동시접속연결 등을 제한


mod cband 설치 사이트

https://fossies.org/linux/www/apache_httpd_modules/mod-cband-0.9.7.5.tgz/


설치 전 mod cband에 필요한 apxs 아파치 확장 개발 라이브러리 설치

# apt-get install apache2-dev


* apxs란?

- 아파치 하이퍼텍스트 전송 프로토콜(HTTP) 서버의 확장 모듈을 컴파일하고 설치하는 도구


웹 사이트에 접속하여 mod cband 다운

# wget https://fossies.org/linux/www/apache_httpd_modules/mod-cband-0.9.7.5.tgz/

( 현재 원활하게 진행되지 않으므로 사이트에 들어가서 직접 다운로드 해야함 )


# tar -zxvf mod-cband-0.9.7.5.tgz

# cd mod-cband-0.9.7.5


설정 파일 일부 수정해주어야함 ( apache 2.4.x 부터 소스코드를 수정 )

# vi /src/mod_cband.c

1333     p.add.sin.s_addr = inet_addr(r->connection->client_ip);


1342             fprintf(stderr,"%s leaf %s\n",r->connection->client_ip,leaf);


1362     if (c->client_ip != NULL)

1363         addr = inet_addr(c->client_ip);

1364     else

1365         addr = c->client_addr->sa.sin.sin_addr.s_addr;


컴파일 및 설치

# ./configure

# make

# make install


cband 모니터링 페이지 생성

vi /etc/apache2/mods-available/cband.load

<IfModule mod_cband.c>

    <Location /cband-status>

        SetHandler cband-status

        AuthName "adminpage"

        AuthType Basic

        AuthUserFile /home/.htpasswd

        require valid-user

    </Location>

    <Location /cband-status-me>

        SetHandler cband-status-me

        Order deny,allow

        Deny from all

        Allow from all

    </Location>

</IfModule>


관리자 패스워드 지정

# htpasswd -c -m /home.htpasswd admin


아파치 cband 모듈 켜기
# a2enmod cband

# service apache2 restart

트래픽 제어 모듈 설정하기
https://www.linux.co.kr/home/lecture/?leccode=10588
- 해당 사이트를 참조하여 생성된 sites-available 디렉토리 안에 virtualhost 파일을 수정

서버 연결당 메모리 소모량 표시 명령어
# ps -ylC apache2 | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Proccess Size (MB): "x/((y-1)*1024)}'

서버의 자원량에 대한 메모리 확인
# free -m

동시연결수 설정 변경
# vi /etc/apache2/mods-available/mpm_prefork.conf

동시 연결수를 300명으로 제한하는 예제
<IfModule mpm_prefork_module>
    StartServers 5
    MinSpareServers 5
    MaxSpareServers 10
    MaxRequestWorkers 300
    ServerLimit 300
    MaxConnectionsPerChild 0
</IfModule>

반응형