Linux/보안장비 운용

Nginx + PHP + MariaDB 연동 웹 서버를 설치하기

GGkeeper 2022. 3. 13. 15:27

미션> Nginx + PHP + MariaDB 연동 웹서버를 설치하기 

1. vim 설정
nginx.conf 를 컬러로 인식하기 위해서는 파일 타입을 추가한다.
# cd 
# yum -y install vim
# alias vi=vim
# echo vim=vim >> ~/.bashrc

# mkdir -p ~/.vim/syntax
# wget http://www.vim.org/scripts/download_script.php?src_id=19394 -O ~/.vim/syntax/nginx.vim

# cat > ~/.vim/filetype.vim <<EOF
au BufRead,BufNewFile /etc/nginx/*,/etc/nginx/conf.d/*,/usr/local/nginx/conf/* if &ft == '' | setfiletype nginx | endif
EOF

2. Nginx + php + php-fpm + mariadb 설치

php-fpm 통신 방법 : 소켓파일
php를 사용하기 위해서는 php-fpm을 설치한다.
php-fpm은 PHP FastCGI Process Manager의 약자로 FastCGI는 CGI보다 더 빠른 처리를 말한다.

Nginx를 설치하기 위해서 저장소를 생성한다.
# vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

패키지를 설치 설치한다.
여기서는 간단히 php 5.x를 설치하고 향후에는 php 7.x or php8.x로 설치하는 것으로 한다.
# yum -y install -y nginx php php-mysql php-fpm 

서비스 활성화
# systemctl enable php-fpm
# systemctl enable nginx

php 설정
# vi /etc/php.ini
-- /etc/php.ini --
short_open_tag = On
[Date]
date.timezone = Asia/Seoul
-- /etc/php.ini --

listen 지시어를 소켓 파일로 수정한다.
# vi /etc/php-fpm.d/www.conf
-- /etc/php-fpm.d/www.conf --
;listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock;

; .html 확장자를 php 로 인식하게 설정한다.
security.limit_extensions = .php .php3 .php4 .php5 .html
-- /etc/php-fpm.d/www.conf --

php-fpm 서비스를 시작한다.
# systemctl start php-fpm
# ls -l /var/run/php-fpm/php-fpm.sock
srw-rw-rw-. 1 root root 0  2월 10 15:55 /var/run/php-fpm/php-fpm.sock

# vi /etc/nginx/conf.d/default.conf
-- /etc/nginx/conf.d/default.conf --
server {
    listen       80;
    server_name  localhost;

    # 캐릭터셋 변경
    charset utf-8;
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;
    # WEb root 디렉터리 변경
    #root   /usr/share/nginx/html;
    root   /var/www/html;

    location / {
        index  index.html index.htm index.php;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        #root   /usr/share/nginx/html;
        root   /var/www/html;
    }

    # .php .html 확장자를 php 로 인식하게 설정한다.
   location ~ \.(php|html)$ {
    #   fastcgi_pass   127.0.0.1:9000;
        fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index  index.php;
        #fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
-- /etc/nginx/conf.d/default.conf --

# systemctl start nginx

-- index.php --
<?
phpinfo();
?>
-- index.php --

PHP연동 후 IP주소로 접속해서 php 페이지가 인식되는지 확인한다.
http://192.168.108.102 

3. DB 연동 기능 
로그인 기능 추가

DB명 : nginxuser
DB사용자 : nginxuser
DB사용자 비번 : 111111
TB명 : member
member TB's 스토리지 엔진 : MyISAM
member TB's 구조 : 
no       : 필드1 int형, 널허용 금지, 자동증가, 기본키 지정
userid   : 필드2 가변길이 문자형이며 크기는 20자 까지, 널 허용 금지, 유일한 값 지정
userpw   : 필드3 고정길이 문자형이며 크기는 41자 까지, 널 허용 금지 
username : 필드4 가변길이 문자형이며 크기는 20자 까지, 널 허용 금지 
regdate  : 필드5 datetime형
스토리지 엔진 : MyISAM 
언어셋        : utf8

not null : 널 허용 금지
auto_increment : 자동 증가
primary key : 기본 키
unique : 유일한 값
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| no       | int(11)     | NO   | PRI | NULL    | auto_increment |
| userid   | varchar(20) | NO   | UNI | NULL    |                |
| userpw   | char(41)    | NO   |     | NULL    |                |
| username | varchar(20) | NO   |     | NULL    |                |
| regdate  | datetime    | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+

insert into member values(NULL, 'test', password('111111'), '홍길동', now());
insert into member values(NULL, 'test2', password('111111'), '고길동', now());

MariaDB [user1]> select * from member;
+----+--------+-------------------------------------------+-----------+---------------------+
| no | userid | userpw                                    | username  | regdate             |
+----+--------+-------------------------------------------+-----------+---------------------+
|  1 | test   | *FD571203974BA9AFE270FE62151AE967ECA5E0AA | 홍길동      | 2021-01-21 02:39:54 |
|  2 | test2  | *FD571203974BA9AFE270FE62151AE967ECA5E0AA | 고길동      | 2021-01-21 02:40:24 |
+----+--------+-------------------------------------------+-----------+---------------------+
2 rows in set (0.00 sec)


DBMS 설정
# mysql mysql
create database nginxuser;
create user 'nginxuser'@'localhost' identified by '111111';
grant all privileges on nginxuser.* to nginxuser@'localhost' with grant option;
select host,user,password from user;
select * from db;
quit

DB 확인
# mysql -h localhost -u nginxuser -p111111 nginxuser
create table a(id int);
show tables;
insert into a values(1);
select * from a;
delete from a;
select * from a;
drop table a;
show tables;

member 테이블 생성
create table member
(
    no       int not null primary key auto_increment comment '회원번호', 
    userid   varchar(20) not null unique comment '회원아이디', 
    userpw   char(41) not null comment '회원비밀번호',
    username varchar(20) not null comment '회원이름',
    regdate  datetime not null comment '가입날짜'
)Engine=MyISAM default charset=utf8;


insert into member values(NULL, 'test', password('111111'), '홍길동', now());
insert into member values(NULL, 'test2', password('111111'), '고길동', now());


html 파일 생성 
login.html loginok.html logout.html 파일을 생성한다.

login.html    : 로그인 페이지
loginok.html  : 로그인 인증 페이지 (DB 연동 부분)
logout.html   : 로그아웃 페이지

               로그아웃 흐름도
   +--------------------------------------+
   |                                      |
   |                                      |
   |                                      v
로그인 페이지     로그인 인증        로그아웃 페이지
login.html -----> loginok.html ----> logout.html 
       로그인 흐름도   |                     |
   ^                |                     |
   |                |                     |
   +----------------+                     |
                                          |
   ^                                      |
   |                                      |
   +--------------------------------------+

# cd /var/www/html
# vi login.html
-- login.html --
<?
session_start();
?>

<html>
<head>
  <title> ::: 로그인 프로그램 ::: </title>
  <meta charset="utf-8"/>
</head>

<body>

<?
if(isset($_SESSION['userid']))  // 로그인 했다면
{
?>

<table align=center border=1 cellpadding=5 cellspacing=0>
<tr align=center>
  <td align=center> <?=$_SESSION['username'] ?> 님 환영합니다. </td>
</tr>
<tr align=center>
  <td align=center> <a href=logout.html> 로그아웃 </a> </td>
</tr>
</table>

<?
} else {  // 로그아웃 했다면 
?>
<form method=post action=loginok.html>
<table align=center border=1 cellpadding=5 cellspacing=0>
<tr align=center>
  <td> 아이디 </td> <td> <input type=text name=userid> </td>
<tr>
<tr align=center>
  <td> 비밀번호 </td> <td> <input type=password name=userpw> </td>
<tr>
<tr align=center>
  <td align=center colspan=2> <input type=submit value=로그인> </td>
<tr>
</table>
</form>

<?
}
?>

</body>
</html>
-- login.html --


# vi loginok.html
-- loginok.html --
<?
session_start();  // 세션 시작

// 디버깅 시 사용
//print_r($_POST);
//exit;

// DB를 root로 접속하면 보안상 문제가 발생되므로 일반 유저로 접속해야 한다.
$DBHOST="localhost";
$DBUSER="nginxuser";
$DBPASS="111111";
$DBNAME = "nginxuser";
$TBNAME = "member";

# DBMS 접속
#resource mysql_connect(서버명,사용자,비번)
$connect = mysqli_connect($DBHOST, $DBUSER, $DBPASS, $DBNAME) or die("DBMS에 접속 실패");

# DB 선택
# mysql_select_db(DB명, 연결정보)
//mysqli_select_db($DBNAME);

# 쿼리 실행
$query = "SELECT * FROM $TBNAME WHERE userid = '$_POST[userid]' and userpw = password('$_POST[userpw]') ";

/* 디버깅 용도
 * echo $query;
 * exit;
 */

# resource mysql_query(쿼리문, 연결정보)
# resource mysqli_query(연결정보, 쿼리문)
$result = mysqli_query($connect, $query);

# 전체 자료 수가 1이면 userid / userpw 가 일치했다는 의미이다.
$num = mysqli_num_rows($result);

if($num)
{  // 세션 생성
    $row = mysqli_fetch_array($result); // $row 변수에 연관 배열로 저장한다.
    // echo "디버깅 : $num <br>";
    // echo "디버깅 : $row[username]";
    // exit;
    $_SESSION['userid'] = $row['userid'];  // 세션변수 userid 를 생성한다.
    $_SESSION['username'] = $row['username']; // 세션변수 username 을 생성한다.
   echo " <script language=JavaScript>
          <!--
              location.href = 'login.html';
          //-->
          </script>
        ";

} else { // userid / userpw 가 틀렸다면 에러메세지를 출력하고 이제 페이지로 돌려보낸다.
   echo " <script language=JavaScript>
          <!--
              alert('아이디/비번을 확인해주세요.');
              history.go(-1);
          //-->
          </script>
        ";
}

?>
-- loginok.html --


-- logout.html --
<?

session_start();    // 세션 시작
session_destroy();  // 세션 삭제

// login.html 로 다시 돌려 보낸다.
echo " <script language=JavaScript>
       <!--
          location.href = 'login.html';
       //-->
       </script>
     ";
?>
-- logout.html --


nginx documentation
http://nginx.org/en/docs/