본문 바로가기
교육

[34일 차] 21.09.06 : Linux Server 13

by ballena 2021. 9. 6.

1교시

 

1. postfix

2. dovecot

3. 웹 서버 구축에서 PHP 설정

4. SSL/TLS

5. MariaDB

 

지난주까지 1, 2를 했으니 이제 PHP 구축.

 

 

우선 PHP 관련 패키지 설치 : yum install -y php-pear

/etc/php.ini 들어가서 날짜, 시간 값 수정

 

/etc/pki/tls/certs/에 키 생성

make mail.key 실행. 없으면 설치

oopenssl genrsa -out mail.key 2048 : 개인 키 하나 만들기

openssl req -new -key mail.key -out mail.csr : 요청서 만들기

openssl x509 -in mail.csr -out mail.crt -req -signkey mail.key -days 365

vim /etc/postfix/main.cf 들어가서

아래 내용 수정(경로, 파일값)

smtpd_tls_cert_file = /etc/pki/tls/certs/mail.crt

smtpd_tls_key_file = /etc/pki/tls/certs/mail.key

vim /etc/postfix/master.cf 들어가서

29, 30, 31행 주석 해제 : smtps 활성화

smtps     inet  n       -       n       -       -       smtpd
 -o syslog_name=postfix/smtps
 -o smtpd_tls_wrappermode=yes

 

vim /etc/dovecot/conf.d/10-master.conf : 수신용 메일 서버 설정

inet_listener imaps 블록 안의 포트, ssl 주석 해제

inet_listener pop3s 블록 안의 포트, ssl 주석 해제

 

vim /etc/dovecot/conf.d/10-ssl.conf 들어가서 

8행의 ssl = no를 yes로

ssl_cert = </etc/pki/tls/certs/mail.crt
ssl_key = </etc/pki/tls/certs/mail.key

두 값을 수정

이제 postfix, dovecot 두 서비스를 재시작 후 상태 확인

tcp:465, tcp:993, tcp:995 포트 작동 확인.

텔넷 포트 그래이빙으로 작동 확인 : telnet localhost 25 -> ehlo master -> 250-STARTTLS가 있으면 작동 중인 것. -> starttls 입력해서 에러 안 나면 성공.

 

openssl s_client -starttls smtp -crlf -connect 192.168.111.100:25

-> 클라이언트가 있다고 가정하고 smtp에 tls 연결

 

(리눅스 클라이언트)썬더버드 계정 설정 > 서버 설정에서 포트 993, 보안 연결 SSL/TLS

보내는 서버 편집 > 보안 연결 STARTTLS, 인증 방식은 인증 없음

(Windows 클라이언트) 위와 동일하게 수정


2교시

 

수정하고 보내면 에러 발생. 인증서를 좀 날림으로 해서 당연한 것. 보안 예외 확인하고 보낸다.

받는 쪽에서도 동일하게 보안 예외 확인

 

웹 상으로 보내고 받기 with roundcube. 처음에 언급한 4번까지 설정했으니 이제 MariaDB 설정

mariadb-server와 mariadb 설치

yum -y install mariadb-server mariadb 설치 후 mariadb 서비스 시작

root 패스워드 설정 : mysql -u root -p

이제 DB 설정

create database roundcube;

grant all privileges on roundcube.* to 'roundcube'@'localhost' identified by 'p@ssw0rd';

-> 계정 생성과 동시에 권한 부여

flush privileges;

-> 설정 변경 저장

여기까지만 하면 알아서 해준다.

 

이제 roundcube 패키지 설치

wget https://github.com/roundcube/roundcubemail/releases/download/1.4.8/roundcubemail-1.4.8-complete.tar.gz

tar xvzf roundcubemail-1.4.8-complete.tar.gz 

mv roundcubemail-1.4.8 roundcube : 이름 너무 기니까 바꾸고

mv roundcube /var/www/html : 옮긴다

chown -R apache:apache /var/www/html : 소유자와 그룹 바꾸고 httpd 재시작


3~4교시

 

버전 미스매칭 문제 발생해서 다시

 

mysql -u root -p roundcube < /var/www/html/roundcube/SQL/mysql.initial.sql
-> roundcube에서 사용하는 정보들을 저장해놓은 백업본을 복제

dnf module reset php
dnf module enable php:remi-7.4 -y
dnf install php-ldap php-imagick php-common php-gd php-imap php-json php-curl php-zip php-xml php-mbstring php-bz2 php-intl php-gmp php-mysql

chcon -t httpd_sys_content_t /var/www/html/roundcube/ -R
chcon -t httpd_sys_rw_content_t /var/www/html/roundcube/temp/ /var/www/html/roundcube/logs/ -R
setfacl -R -m u:apache:rwx /var/www/html/roundcube/temp/ /var/www/html/roundcube/logs/

 

이제 httpd, mariadb 재시작하고 192.168.111.100/roundcube/installer 진입

환경 확인은 넘기고, 설정 생성에서 Database setup 필드로 간다.

db type은 mysql

grant all privileges on roundcube.* to 'roundcube'@'localhost' identified by 'p@ssw0rd';

-> 여기서 설정했듯이

db server는 localhost, db name과 user는 roundcube, 비밀번호도 작성

 

IMAP Settings 필드로 가서 default_host와 default_port를 ssl://ms.chul.com과 993 작성

SMTP Settings도 동일하게 ssl://ms.chul.com과 465 작성

 

cp /var/www/html/roundcube/config/config.inc.php.sample /var/www/html/roundcube/config/config.inc.php

-> 샘플 설정 파일 복사

 

이제 쭉 내려가서 create config후 continue

 

수정 사항

/var/www/html/roundcube/config/config.inc.php 파일에서 

28행에 있는 기본 설정을 내가 설정했던 정보대로 수정

53행에 $config['smtp_server'] = 'ssl://ms.chul.com';로 수정

$config['smtp_port'] = 465;로 수정

 

 

저장소 서버에 연결을 실패했습니다, 라는 에러에서 막혔다.

이리저리 알아보는 중이지만 아직 해결 못했다. 나중에 다시 진행한다고 한다.


5교시

 

VM들 모두 스냅샷 돌리고

웹과 DB의 연동 실습(DNS는 하지 않고)

 

일단 httpd 패키지 설치

PHP 패키지들 설치 : PHP는 언제나 버전에 주의할 것.

dnf -y install php56

dnf -y install php56-php-fpm php56-php-imagick php56-php-mbstring php56-php-pdo php56-php-pear php56-php-mysqlnd php56-php-pecl-jsonc php56-php-pecl-zip php56-php-pecl-geoip php56-php-soap php56-php-imap php56-php-mcrypt php56-php-mbstring php56-php-pecl-pdflib php56-php-pecl-jsond

http 서비스 방화벽 열어주고 재시작, httpd 재시작.

 

mysql 설치

dnf module -y install mysql:8.0

vim /etc/my.cnf.d/mysql-server.cnf 하단에 character-set-server=utf8 추가 : 한글 설정

systemctl enable --now mysqld

mysql 서비스 방화벽 열어주고 재시작

 

mysql 초기 설정

mysql_secure_installation 실행하면 여러 가지를 물어본다

-> 패스워드 정책(길이, 복잡성 등) 사용 여부 : yes

-> 사용한다면, 레벨은? : 0

-> root 패스워드는? : p@ssw0rd

-> 패스워드 설정 유지 여부 : yes

-> 익명의 사용자 삭제 여부 : yes

-> root의 원격 접속 비활성화 여부 : yes

-> 테스트 DB/접근 삭제 여부 : yes

-> 변경 사항 즉각 적용 : yes

 

 

Mysql 로컬 로그인 시

mysql -u 계정명 -p 

-> 패스워드 물어보고 접속

mysql -u 계정명 -p 접속할DB명

-> 해당 DB로 바로 접속

mysql -u 계정명 -p'패스워드' 접속할DB명

-> 패스워드 따로 안 물어보고 해당 DB로 바로 접속. 쉘에 기록이 남아서 보안 상으로는 좋지 않다.

 

 

mysql.user 테이블의 authentication_string 칼럼이 비밀번호

create user user1@'%' identified by 'p@ssw0rd'; : 원격 접속을 위한 사용자 생성

grant all privileges on *.* to user1@'%' with grant option; : 원격 접속하는 user1에게 모든 권한 부여

GRANT ALL PRIVILEGES ON *.* TO 'user1'@'localhost' with grant option; : 로컬 접속자 user1에게 모든 권한 부여

FLUSH PRIVILEGES; : 변경 사항 저장

 

권한 제거

REVOKE ALL ON DB명.TABLE명 FROM 사용자; : 특정 테이블에 대한 사용자의 권한 모두 제거

변경 사항 저장은 동일하게 FLUSH PRIVILEGES;

 

패스워드 변경

UPDATE user SET password=password('변경할 비밀번호') WHERE user='사용자명';

mysqladmin -u user1 -p password 신규패스워드 : 실행하면 기존 패스워드 입력 후 변경됨


6~7교시

 

 

외부에서 DB 만들기

vim temp.sql : 안에 DB 만드는 구문을 작성하고

mysql -u root -p mysql < ./temp.sql : 실행하면 DB가 생긴다.

mysql -u root -p test_db < ./temp3.sql : 특정 DB에 작성한 구문을 실행

mysql -u root -p -e 'SELECT * FROM temptable' test_db : 특정 DB의 특정 테이블에 작성한 구문 실행

 

명령어로 특정 DB 백업

mysqldump -u root -p sqlDB > sqlDB.sql : sqlDB라는 DB를 sqlDB.sql이라는 파일로 백업

-> sqlDB.sql 파일을 보면 쭉 나와있다.

 

해당 DB 삭제 : drop database sqlDB;

 

백업해둔 파일로 복구하기

mysqladmin -u root -p create sqlDB : (mysql 들어가지 않고) DB를 만들어 두고 

mysql -u root -p sqlDB < sqlDB.sql : 그 DB에 sql 파일 실행시켜서 복구

mysql -u root -p -e 'select * from userTBL' sqlDB : mysql 들어가지 않고 확인하기

 

 

웹 서버 - DB 서버 연동

/var/www/html/test.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "p@ssw0rd", "sqlDB");
   if ( mysqli_connect_error($con) ) {
      echo "MySQL 접속 실패 !!", "<br>";
      echo "오류 원인 : ", mysqli_connect_error();
      exit();
   }
   echo "MySQL 접속 완전히 성공!!";
   mysqli_close($con);
?>

db가 다른 서버에 있다면? : localhost를 해당 서버의 주소로 변경해야 한다.

-> 접속하는 계정을 설정할 때에도 호스트를 변경해야 한다.

 

실습 : 웹 가입 홈페이지

main.html

더보기

<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 회원 관리 시스템 </h1>

<a href='select.php'> (1) 회원 조회 (조회 후 수정/삭제 가능) </a> <br><br>
<a href='insert.php'> (2) 신규 회원 등록 </a> <br><br>
<FORM METHOD="get"  ACTION="update.php">
(3) 회원 수정 - 회원 아이디 : <INPUT TYPE ="text" NAME="userID"> 
<INPUT TYPE="submit"  VALUE="수정">
</FORM>
<FORM METHOD="get"  ACTION="delete.php">
(4) 회원 삭제 - 회원 아이디 : <INPUT TYPE ="text" NAME="userID"> 
<INPUT TYPE="submit"  VALUE="삭제">
</FORM>

</BODY>
</HTML>

 

select.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "", "sqlDB") or die("MySQL 접속 실패 !!");

   $sql ="SELECT * FROM userTBL";
 
   $ret = mysqli_query($con, $sql);   
   if($ret) {
   //echo mysqli_num_rows($ret), "건이 조회됨..<br><br>";
   $count = mysqli_num_rows($ret);
   }
   else {
   echo "userTBL 데이터 조회 실패!!!"."<br>";
   echo "실패 원인 :".mysqli_error($con);
   exit();
   } 
   
   echo "<h1> 회원 조회 결과 </h1>";
   echo "<TABLE border=1>";
   echo "<TR>";
   echo "<TH>아이디</TH><TH>이름</TH><TH>출생년도</TH><TH>지역</TH><TH>극번</TH>";
   echo "<TH>전화번호</TH><TH>키</TH><TH>가입일</TH><TH>수정</TH><TH>삭제</TH>";
   echo "</TR>";
   
   while($row = mysqli_fetch_array($ret)) {
  echo "<TR>";
  echo "<TD>", $row['userID'], "</TD>";
  echo "<TD>", $row['name'], "</TD>";
  echo "<TD>", $row['birthYear'], "</TD>";
  echo "<TD>", $row['addr'], "</TD>";
  echo "<TD>", $row['mobile1'], "</TD>";
  echo "<TD>", $row['mobile2'], "</TD>";
  echo "<TD>", $row['height'], "</TD>";
  echo "<TD>", $row['mDate'], "</TD>";
  echo "<TD>", "<a href='update.php?userID=", $row['userID'], "'>수정</a></TD>";
  echo "<TD>", "<a href='delete.php?userID=", $row['userID'], "'>삭제</a></TD>";
  echo "</TR>";   
   }   
   mysqli_close($con);
   echo "</TABLE>"; 
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
?>

 

insert.php

더보기

<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 신규 회원 입력 </h1>
<FORM METHOD="post"  ACTION="insert_result.php">
아이디 : <INPUT TYPE ="text" NAME="userID"> <br>
이름 : <INPUT TYPE ="text" NAME="name"> <br> 
출생년도 : <INPUT TYPE ="text" NAME="birthYear"> <br>
지역 : <INPUT TYPE ="text" NAME="addr"> <br>
휴대폰 국번 : <INPUT TYPE ="text" NAME="mobile1"> <br>
휴대폰 전화번호 : <INPUT TYPE ="text" NAME="mobile2"> <br>
신장 : <INPUT TYPE ="text" NAME="height"><br>
<BR><BR>
<INPUT TYPE="submit"  VALUE="회원 입력">
</FORM>

</BODY>
</HTML>

 

insert_result.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "", "sqlDB") or die("MySQL 접속 실패 !!");

   $userID = $_POST["userID"];
   $name = $_POST["name"];
   $birthYear = $_POST["birthYear"];
   $addr = $_POST["addr"];
   $mobile1 = $_POST["mobile1"];
   $mobile2 = $_POST["mobile2"];
   $height = $_POST["height"];   
   $mDate = date("Y-m-j");
   
   $sql =" INSERT INTO userTBL VALUES('".$userID."','".$name."',".$birthYear;
   $sql = $sql.",'".$addr."','".$mobile1."','".$mobile2."',".$height.",'".$mDate."')";
   
   $ret = mysqli_query($con, $sql);
 
    echo "<h1> 신규 회원 입력 결과 </h1>";
   if($ret) {
   echo "데이터가 성공적으로 입력됨.";
   }
   else {
   echo "데이터 입력 실패!!!"."<br>";
   echo "실패 원인 :".mysqli_error($con);
   } 
   mysqli_close($con);
   
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
?>

 

update.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "", "sqlDB") or die("MySQL 접속 실패 !!");
   $sql ="SELECT * FROM userTBL WHERE userID='".$_GET['userID']."'";

   $ret = mysqli_query($con, $sql);   
   if($ret) {
   $count = mysqli_num_rows($ret);
   if ($count==0) {
   echo $_GET['userID']." 아이디의 회원이 없음!!!"."<br>";
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
   exit();
   }    
   }
   else {
   echo "데이터 조회 실패!!!"."<br>";
   echo "실패 원인 :".mysqli_error($con);
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
   exit();
   }   
   $row = mysqli_fetch_array($ret);
   $userID = $row['userID'];
   $name = $row["name"];
   $birthYear = $row["birthYear"];
   $addr = $row["addr"];
   $mobile1 = $row["mobile1"];
   $mobile2 = $row["mobile2"];
   $height = $row["height"];   
   $mDate = $row["mDate"];      
?>

<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 회원 정보 수정 </h1>
<FORM METHOD="post"  ACTION="update_result.php">
아이디 : <INPUT TYPE ="text" NAME="userID" VALUE=<?php echo $userID ?> READONLY> <br>
이름 : <INPUT TYPE ="text" NAME="name" VALUE=<?php echo $name ?>> <br> 
출생년도 : <INPUT TYPE ="text" NAME="birthYear" VALUE=<?php echo $birthYear ?>> <br>
지역 : <INPUT TYPE ="text" NAME="addr" VALUE=<?php echo $addr ?>> <br>
휴대폰 국번 : <INPUT TYPE ="text" NAME="mobile1" VALUE=<?php echo $mobile1 ?>> <br>
휴대폰 전화번호 : <INPUT TYPE ="text" NAME="mobile2" VALUE=<?php echo $mobile2 ?>> <br>
신장 : <INPUT TYPE ="text" NAME="height" VALUE=<?php echo $height ?>> <br>
회원가입일 : <INPUT TYPE ="text" NAME="mDate" VALUE=<?php echo $mDate ?> READONLY><br>
<BR><BR>
<INPUT TYPE="submit"  VALUE="정보 수정">
</FORM>

</BODY>
</HTML>

 

update_result.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "", "sqlDB") or die("MySQL 접속 실패 !!");

   $userID = $_POST["userID"];
   $name = $_POST["name"];
   $birthYear = $_POST["birthYear"];
   $addr = $_POST["addr"];
   $mobile1 = $_POST["mobile1"];
   $mobile2 = $_POST["mobile2"];
   $height = $_POST["height"];   
   $mDate = $_POST["mDate"]; 
   
   $sql ="UPDATE userTBL SET name='".$name."', birthYear=".$birthYear;
   $sql = $sql.", addr='".$addr."', mobile1='".$mobile1."',mobile2='".$mobile2;
   $sql = $sql."', height=".$height.", mDate='".$mDate."' WHERE userID='".$userID."'";
   
   $ret = mysqli_query($con, $sql);
 
    echo "<h1> 회원 정보 수정 결과 </h1>";
   if($ret) {
   echo "데이터가 성공적으로 수정됨.";
   }
   else {
   echo "데이터 수정 실패!!!"."<br>";
   echo "실패 원인 :".mysqli_error($con);
   } 
   mysqli_close($con);
   
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
?>

 

delete.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "", "sqlDB") or die("MySQL 접속 실패 !!");
   $sql ="SELECT * FROM userTBL WHERE userID='".$_GET['userID']."'";

   $ret = mysqli_query($con, $sql);   
   if($ret) {
   $count = mysqli_num_rows($ret);
   if ($count==0) {
   echo $_GET['userID']." 아이디의 회원이 없음!!!"."<br>";
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
   exit();
   }    
   }
   else {
   echo "데이터 조회 실패!!!"."<br>";
   echo "실패 원인 :".mysqli_error($con);
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
   exit();
   }   
   $row = mysqli_fetch_array($ret);
   $userID = $row['userID'];
   $name = $row["name"];
   
?>

<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 회원 삭제 </h1>
<FORM METHOD="post"  ACTION="delete_result.php">
아이디 : <INPUT TYPE ="text" NAME="userID" VALUE=<?php echo $userID ?> READONLY> <br>
이름 : <INPUT TYPE ="text" NAME="name" VALUE=<?php echo $name ?> READONLY> <br> 
<BR><BR>
위 회원을 삭제하겠습니까?
<INPUT TYPE="submit"  VALUE="회원 삭제">
</FORM>

</BODY>
</HTML>

 

delete_result.php

더보기

<?php
   $con=mysqli_connect("localhost", "root", "", "sqlDB") or die("MySQL 접속 실패 !!");

   $userID = $_POST["userID"];
     
   $sql ="DELETE FROM userTBL WHERE userID='".$userID."'";
   
   $ret = mysqli_query($con, $sql);
 
    echo "<h1> 회원 삭제 결과 </h1>";
   if($ret) {
   echo $userID." 회원이 성공적으로 삭제됨..";
   }
   else {
   echo "데이터 삭제 실패!!!"."<br>";
   echo "실패 원인 :".mysqli_error($con);
   } 
   mysqli_close($con);
   
   echo "<br><br> <a href='main.html'> <--초기 화면</a> ";
?>


8교시

 

종합 실습

웹 서버는 master, DB 서버는 slave로.

DB 접근 사용자 : user1 사용자 생성

-> 사용자 생성 시 user1이 접속할 주소를 설정하므로

-> CREATE USER user1@'192.168.111.100' IDENTIFIED BY 'p@ssw0rd';

-> GRANT ALL PRIVILEGES ON *.* TO user1@'192.168.111.100' WITH GRANT OPTION ;

 

다른 서버로 접속해야 하므로 master 쪽에서 SELinux 설정 필요.

setsebool -P httpd_can_network_connect 1

 

다 동일하지만 

php에서 DB 연결 시 접속 주소는 DB 서버 주소로 수정하고, 사용자도 수정.

 


일단 오늘 수업 내용 중 다시 들어야 할 부분은 없다. 굳!

 

내일 오후부터 Ansible 시작이다. 교육 시작할 때부터 예습해야지, 했는데 결국 안 하고 시작한다. 

 

SELinux는 반드시 다시 복습할 것. 아직도 헷갈린다. 

댓글