AWS로 서버구축을 해보자!
AWS 서버 구축
가상머신에서 리눅스기반 서버구축을 연습했고 개발을 위해 local 서버도 구축 했으니 이제 진짜 배포용 서버를 구축할 차례다. AWS를 이용해 서버 구축을 해보자.
Ubuntu 20.04.2 LTS
Nginx
MySQL 8.0.26
PHP 7.4.3
AWS 서버 구축 (Ubuntu + Nginx + PHP + MySQL)
AWS는 아마존의 클라우드 컴퓨팅 서비스다. 회원가입 후 인스턴스를 생성해 가상머신에서 했던것과 마찬가지로 서버를 구축해보자.
이번에는 Apache대신 Nginx를 설치할 계획이다. Apache에서는 요청이 일정량을 넘어가면 프로세스와 스레드를 생성하지만 Nginx는 Master process가 worker process를 비동기 event-driven방식으로 관리하기 때문에 process의 생성, 삭제가 일어나지 않는다. 따라서 Nginx가 더 효율적으로 자원을 쓴다.
1. AWS 인스턴스 생성
회원가입 후 EC2를 클릭하여 절차대로 생성하면 큰 어려움이 없다.
탄력적 ip를 할당받아 인스턴스를 중지후 재실행 시켰을때 ip가 바뀌지 않도록 해준다.
AWS Console -> 네트워크 및 보안 -> 탄력적 ip -> 탄력적 ip 주소 할당
생성된 탄력적 ip 이름 -> 탄력적 ip 주소 연결 -> 리소스 유형(인스턴스) 선택
2. Key 파일을 이용한 인스턴스 접속
인스턴스 생성 시 다운받은 key파일을 이용해 터미널로 인스턴스에 접속한다.
cd {key파일 위치}
chmod 400 {key파일 이름.cer}
ssh -i "{key파일 이름.cer}" ubuntu@ec2-15-165-131-40.ap-northeast-2.compute.amazonaws.com
터미널에서 key파일이 있는 디렉토리로 이동 후 AWS 페이지의 인스턴스-연결-SSH 클라이언트에서 복사한 명령어를 실행한다. 페이지에는 key파일의 확장자가 .pem라고 나와있지만 내게 다운받아진 파일 확장자는 .cer이었다. 따라서 커맨드들의 .pem을 .cer로 바꿔 입력해줬다.
3. Nginx, MySQL, PHP설치
sudo apt update
sudo apt install nginx
sudo apt install mysql-server
sudo apt install php-fpm php-mysql
Nginx는 Apache와 달리 자체적인 php 모듈이 없다. 따라서 CGI를 이용해 외부 프로그램과 연결되어 동적 페이지를 제공한다. 이를 위해 Apache를 사용할때와는 달리 php-fpm을 설치해줘야 한다.
MySQL과 PHP 설치를 확인해 보고 Nginx는 AWS페이지에서 http 인바운드 규칙을 추가해 외부에서 접속해 확인해본다.
4.PHP-Nginx연동
PHP와 Nginx를 연동하고 연동을 확인한다.
cd /var/www/html
sudo vim index.php
sudo /etc/nginx/sites-available
sudo vim default
sudo service nginx restart
Nginx의 document root인 /var/www/html로 이동해 index.php파일을 작성한다.
/etc/nginx/sites-available/default 파일을 수정해 php-fpm과 연결해준다.
주석으로 되어있는 php location 블럭에 php-fpm주석을 해제해주면된다.
외부ip로 접속해 연동이 잘 됐는지 index.php파일을 확인한다.
5. datagrip을 이용한 MySQL 외부 접속
5.1. MySQL에 새로운 계정과 DB를 생성하고 권한을 부여한다.
sudo mysql -u root -p
mysql> create user 'cloer'@'%' identified by 'password';
mysql> create database ss_db;
mysql> grant all privileges on ss_db.* to 'cloer'@'%'; //권한 부여
mysql> flush privileges;
mysql> show grants for 'cloer'@'%'; //유저 권한 확인
mysql> show databases;
mysql> use mysql;
mysql> select user, host from user;
@'%': 외부접근 가능
@'localhost': 내부접근만 가능
@'xxx.xxx.xxx.xxx': 지정 ip주소로만 접근가능
5.2. MySQL의 외부접속을 허가해준다.
cd /etc/mysql/mysql.conf.d
sudo vim mysqld.cnf
sudo service mysql restart
bind-address 를 0.0.0.0으로 설정해 외부접속을 허가해 준다.
5.3. AWS 인바운드 규칙 추가
인바운드 규칙에 MYSQL/Aurora - 3306 - 0.0.0.0/0, ::/0 을 추가해준다.
5.4. DataGrip으로 외부에서 MySQL접속
DataGrip다운로드 후 생성한 DB를 연결해준다.
6. phpMyAdmin 설치
sudo apt update
sudo apt upgrade
sudo apt install phpmyadmin
sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin //심볼릭링크 생성
sudo vim /etc/nginx/sites-avilable/default //파일 수정
sudo service nginx restart
- Web server를 선택하는 창에서는 Nginx를 다운했기에 아무것도 체크하지 않고 OK
- Configure database를 묻는 질문에서 mysql을 이미 다운했기에 No
다운로드된 phpmyadmin을 Nginx의 document root에 "ln -s" 커맨드로 이용하여 심볼릭링크(바로가기) 생성한다.
/etc/nginx/sites-available/default 파일에 index.php파일을 추가해준다.
AWS ip/myadmin으로 확인한다. (앞서 만들었던 ss_db를 삭제했어서 위 phpmyadmin 페이지에 표시되지 않습니다.)
7. Domain 적용
가비아를 이용해 도메인을 구매했다. 도메인 구매 후 레코드를 추가해 second-level 도메인을 설정해준다.
8. https 적용
무료로 인증서를 발급 받을 수 있는 Let's Encrypt를 사용했다.
8.1. certbot 설치, Nginx에 도메인 설정변경
sudo apt update
sudo apt upgrade
sudo add-apt-repository ppa:certbot/certbot
sudo apt install python3-certbot-nginx
먼저 certbot을 업데이트하고 certbot저장소를 추가한다. certbot의 nginx패키지를 설치한다.
sudo vim /etc/nginx/sites-available/default
Nginx의 default파일의 server_name뒤에 원하는 도메인을 적는다.
sudo nginx -t
sudo systemctl reload nginx
nginx를 테스트 해보고 리로드해준다.
8.2. certbot으로 인증서 받기
sudo certbot --nginx -d cloer.shop -d www.cloer.shop
sudo service nginx restart
DNS 레코드를 추가한 cloer.shop과 www.cloer.shop에 대한 인증서를 받는다. 중간에 이메일 입력, 동의 A, 이메일 알림 No, http를 https로 redirect 2번 등 설정이 있으니 잘 읽어보고 해야한다.
인증 완료후 You should test your configure at: 의 주소에서 확인 할 수 있다.
페이지 주소창옆에 자물쇠 아이콘이 뜨는것을 확인 할 수 있다.
9. sub domain 적용
도메인에 대해서는 알아볼게 많고 처음 접하면 살짝 어지러워 지기에 다른 글에서 정리하고 이 글에서는 설치 흐름만 살펴보려한다.
9.1. DNS 레코드에 원하는 서브 도메인 추가
my.cloer.shop과 your.cloer.shop을 만들었다.
9.2. Nginx 설정 파일 수정
cd /var/www/html
sudo mkdir my
sudo mkdir your
sudo vim my/my.html
sudo vim your/your.html
Nginx의 기본 html 폴더에 각 서브도메인에 연결할 디렉토리와 접속할 때 보여줄 html파일을 만든다.
9.3. Nginx 기본 설정 파일 수정
sudo vim /etc/nginx/sites-avilable/default
managed by Certot 부분은 이 글 후반부에 서브 도메인에 https인증을 받을때 자동으로 생긴 것이므로 무시하고 server{ root 부터 location} 까지만 my와 your에대해 두개 작성해준다.
sudo service nginx restart
주소창의 주의 요함이 보기 싫으니 서브도메인도 https를 적용시켜 주자.
9.3. 서브도메인 https 적용
sudo certbot certonly --manual -d *.cloer.shop -d cloer.shop --preferred-challenges dns
.cloer.shop 하위에 있는 모든 호스트를 가르키는 *.cloer.shop과 cloer.shop에 대해 인증서를 수동으로 발급받는다. 수동으로 하는 이유는 이 글에 잘 정리 되어있다. 저 글의 3.DNS 방식이 DNS에 직접 TXT레코드를 추가해 인증하는 방법으로, 수동설치(manual)를 뜻하는것 같다. 설치 방법은 Certbot 공식 홈페이지를 참조했다. 지금 생각해보니 그냥 처음부터 "sudo certbot --nginx -d *.cloer.shop -d cloer.shop"커맨드로 인증서를 받았으면 됐지 않았을까 싶다...
수동설치를 하면 이런식으로 텍스트를 주는데 저 텍스트를 도메인의 레코드에 추가해 도메인에서 한 요청임을 인증해야한다. 저 화면이 뜨면 바로 엔터를 치지 말고 해탕 텍스트를 레코드에 추가하고 업데이트를 기다렸다가 엔터를 치자.
인증서를 받긴 했는데 적용이 안돼서 아까 생각했던 certbot --nginx -d 와일드카드 로 해봤다.
이제 주의를 요하지 않아도 된다. 하지만 http로 접근하면 https로 redirect가 되지 않는다.
10. redirection
ip주소, cloer.shop, www.cloer.shop, *.cloer.shop(서브도메인)을 http로 요청할경우 https로 redirction해보자.
내가 하고자 하는것은 ip주소를 입력했을때 cloer.shop으로, www.cloer.shop을 입력했을때 www를 빼고 cloer.shop으로, http를 https로 redirect하는 것이다.
먼저 main server의 server_name에서 www.cloer.shop을 뺐다. main server는 listen 443으로 https만 받는다.
서브 도메인을 만들어주고 certbot에서 만들어준 listen 80을 뺐다. 서브도메인도 https만 받는다. main server와 서브 도메인 server의 http는 아래에서 따로 설정해준다.
ip주소, www.cloer.shop으로 접근했을때 https로 redirection해주고 서브도메인에서도 80번 포트로 접근하면 https로 돌려줬다. certbot에서 작성해준 스크립트는 같은 내용인거같아서 주석처리 했다.
글을 쓰다보니 https://{ip주소}로 접근할때를 설정 안해줘서 확인 해봤는데 역시 오류가 났다.
검색을 해보니 나같은 사람이 있었다. 생각해보면 https://{ip주소} 는 될리가 없다. 일단 ip주소에대한 인증서를 발급받은적이 없고 Lets Encrypt에서는 발급해주지 않는다고 한다. 다른 인증기관에서 ip주소에 대한 인증서를 발급받았다고 해도 https://{ip주소}로 접근할 일이 없다.
www없애기, http -> https, 서브 도메인 모두 redirect 설정을 끝냈다.
+ 추가 server_name을 wildcard로 했을때 return을 어떻게 해야할지 몰라 서브 도메인마다 server 블럭을 만들었는데 $host로 하면 된다. www도 wildcard에 넣어서 서브도메인과 www를 한번에 처리했다. 위에 서브도메인 경로를 설정해준 server block도 *.cloer.shop 과 $host를 이용해 합쳐서 작성 할 수 있을것 같지만 존재하지 않는 서브 도메인으로 접근할 경우 예외 처리도 해야할 것같아서 그냥 두고 redirection부분만 수정했다.
관련 포스트
DNS ...작성중....
참조
Apache vs Nginx: https://niklasjang.tistory.com/56
SSL인증 (Nginx): https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04
서브도메인 SSL인증: https://happist.com/573990/%EC%B5%9C%EC%8B%A0-lets-encrypt-ssl-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EB%B0%9C%EA%B8%89-%EB%B0%A9%EB%B2%95-3%EA%B0%80%EC%A7%80-%EC%A0%95%EB%A6%AC (블로그는 글만 참조하고 커맨드는 본문처럼 certbot --nginx로)
Nginx document: http://nginx.org/en/docs/http/server_names.html#wildcard_names
같이 보면 좋은 글
.pem vs .cer: https://www.sslcert.co.kr/guides/kb/54
'Server' 카테고리의 다른 글
[Server] Local 서버 구축 (0) | 2021.09.24 |
---|---|
[Server] 서버 개념, lamp 설치 (1) | 2021.09.07 |