ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AWS/Lightsail] AWS에서 웹서비스 만들기 실습 - 4. Certbot 을 통한 인증서 발급 및 https 적용
    서버 관리/AWS & Lightsail 2021. 3. 25. 17:53
    반응형

    웹 서버 구축까지 끝났지만 문제가 있다. 보안성이 없는 HTTP로 통신한다는 점이다. HTTPS를 적용하려면 인증서를 구매해야 하는데 개인프로젝트 개발용도로 쓰기엔 비용이 상당히 부담스럽다.

     

    그래서 Certbot을 이용해 인증서를 구축해볼 계획이다.

    1. Certbot 사이트 접속(https://certbot.eff.org)

    Certbot 사이트 메인으로 들어가면 사용하는 Software와 System을 물어보는 화면이 나타난다. Software는 웹서버를 말하는 것이며, 지난시간에 구축한 웹서버가 Nignx 이므로 Ningx를, System OS는 ubuntu 20.04를 선택한다.

    선택하면 페이지 이동과 함께 설명서가 표시된다.  Default는 단일 도메인을 위한 인증서를 발급받을때 사용하는 방법이며, wildcard는 향후 하위 도메인(예를 들어, mail.nosearchuser.com, auth.nosearchuser.com 등의 도메인)을 통해 여러 서버에서 도메인을 사용할 경우를 위해 사용하는 통합 인증서를 발급받는 방법이다.

     

    단순 웹서비스 구축이긴 하지만, 범용성을 위해 wildcard 방식으로 받아보겠다.

    사이트 첫 단계는 현재 사용중인 DNS 제공자(제공업체)의 지원여부를 확인하는 단계이다. 링크에 접속하면 DNS Plugins 문서가 열리는데 각 서비스 업체별 플러그인 설치방법이 적힌 Link 리스트가 표시되어 있다. 도메인 제공업체가 Route 53이므로 certbot-dns-route53을 선택한다.

    사이트를 들어가면 관련 문서가 표시되는데 아래와 같은 설명을 볼 수 있다.

    직역하면 "이 플러그인을 사용하려면 다음 권한이있는 계정에 대한 Amazon Web Sevices API 자격 증명이 포함 된 구성 파일이 필요합니다." 라고 되어있는데, AWS에서 관련 자격증명에 대한 구성설정을 진행하지 않았다. 따라서, 관련 구성을 먼저 선행해야 한다.

     

    2. AWS 서비스 사용자 추가

    웹 콘솔 상단 메뉴에서 "내 보안 자격 증명"으로 접속하거나 IAM 서비스를 찾아 접속한다.

    IAM 대시보드 메뉴에서 [사용자]를 선택한 후, [사용자 추가] 버튼을 누른다.

     

    총 다섯 단계의 작업이 필요한데, 상당히 복잡한 부분도 있다.

    1 단계

    사용자 이름은 "Certbot", 액세스 유형은 "프로그래밍 방식 액세스"를 선택한다.

     

     

    2단계

    기존 정책 직접 연결을 선택한 후, [정책 생성] 버튼을 누른다.

    그러면 정책 생성 관련 페이지가 표시된다. 앞서 접속했던 "certbot-dns-route53" 문서의 "Example AWS policy file" 를 참조로 값을 입력할 예정이기 때문에 JSON 편집을 선택한다.

    정책 생성 페이지가 표시됨

    certbot-dns-route53.readthedocs.io/en/stable/#sample-aws-policy-json 에 작성된 json 값을 복사하여 정책에 붙여넣는다. 그 뒤, "hostedzone/YOURHOSTEDZONEID" 부분의 YOURHOSTEDZONEID 값을 보유한 도메인의 호스팅영역 ID를 입력한다.

     

    호스팅영역 ID는 Route 53 콘솔의 [호스팅 영역] 항목에서 확인가능하다.

     

    * 실습 기준인 2021-03-25 기준으로 정책 버전이 "2012-10-17"로 메뉴얼과 동일하기 때문에 복사 붙여넣기로 처리한 것이다. 향후 버전이 달라지거나, 방법이 변경될 경우 제대로 되지 않을 수 있다.

     

    태그 생성은 무시하고, 마지막 단계에서 정책 이름을 입력 한다. 필자는 "certbot-dns-route53-policy"로 작성했다.

    정책이 생성되었다면, 사용자 추가화면으로 돌아와 생성했던 정책을 찾은 뒤 다음을 진행한다. 검색이 안될 경우, Refresh 버튼을 눌러주면 된다.

    3단계

    3단계는 태그 추가 사항이다. 서비스 운영상 당장은 필요없으므로 무시하고 넘어간다.

     

    4단계

    설정한 사용자 및 정책사항을 확인하는 단계이다. [사용자 만들기] 버튼을 눌러 진행을 계속한다.

    5단계

    사용자 추가가 완료되었다. csv 파일을 다운로드 받고 이 단계를 마무리 한다.

     

    3. EC2 인스턴스에 aws-cli 설치

    SSL을 통해 생성한 EC2 인스턴스에 접속한 후, aws-cli 설치한다. 아래 명령어를  순서대로 입력하면 설치된다. 버전 2를 기준으로 한다.

    * 환경에 따라 unzip이 없을 수 있다. 그럴 경우 snap 또는 apt 명령어로 설치하도록 하자.

    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install

    보다 자세한 설치 과정은 docs.aws.amazon.com/ko_kr/cli/latest/userguide/install-cliv2-linux.html에서 확인할 수 있다.

    * 필자가 맨땅에 해딩 방식으로 진행하다보니 불필요할 수도 있다. 참조만 해주기 바란다.

     

    4. 관리자 권한으로 environment 설정

    EC2 인스턴스의 SSL 에서 아래와 같은 명령어를 입력한 뒤, export 명령어로 관련 정보를 추가한다.

    sudo su
    export AWS_ACCESS_KEY_ID=<csv 파일의 AWS_ACCESS_KEY_ID 값>
    export AWS_SECRET_ACCESS_KEY=<csv 파일의 AWS_SECRET_ACCESS_KEY 값>

    * export 값이 보존되지 않으므로, root 세션을 다시 열었을 경우 이 과정이 또 필요할 수 있다.

    이 아래 단계부터는 ROOT 세션으로 작업했다는 가정하에 sudo 명령어를 생략하고 작성합니다.
    만약 SSL 연결을 종료했거나, su 권한을 나왔을 경우에는 sudo 명령어가 필요할 수 있습니다.

    5. Snap 명령어 최신버전 적용

    이제 본격적인 Certbot 설치 과정에 진입할 수 있게 되었다. EC인스턴스에서 아래와 같은 명령어로 snap 명령어를 최신버전으로 적용시킨다.

    snap install core; snap refresh core

     

    실습환경인 인스턴스가 우분투 20.04 버전이므로 기본적으로 snap은 설치되어 있다. 가능성은 낮지만, snap이 설치 안되어있을 수도 있다. 이 경우 snapcraft.io/docs/installing-snapd에서 설치과정을 진행해야 한다.

     

    6. 명령어 사용을 위한 설정

    certbot을 사용하기위해 아래 명령어를 순차적으로 입력한다.

    ln -s /snap/bin/certbot /usr/bin/certbot
    snap set certbot trust-plugin-with-root=ok

     

    7. DNS 플러그인 설치

    사전 설정의 주범(?)이었던 certbot DNS 플러그인을 설치한다. Route53 이 도메인 제공자이므로 아래 명령어로 설치한다.

    snap install certbot-dns-route53

     

    8. certonly 명령어 실행

    인증서 생성을 위해 아래와 같이 명령어를 입력한다.

    certbot certonly --dns-route53 -d <도메인주소> -i nginx

    입력하면 이메일 주소를 입력하는 창이 나타난다.  사용하는 이메일 주소를 입력한 뒤 엔터를 누른다.

    다음 단계로 이용 약관(Term of service) 동의 여부를 묻는다. Y를 입력한 뒤 엔터를 누른다.

    정상적으로 설정되었다면 아래와 같은 메시지가 표시된다.

    한번에 성공이 안될 수도 있다. 이런 메시지가 표시된다면 명령어를 한번 더 실행해보자.

    아래와 같이 Unable to locate credentials. 메시지가 뜬다면 "4. 관리자 권한으로 enviroment 설정"이 제대로 안되었거나, 세션이 끝나서 값이 사라졌을 가능성이 높다.

     

    9. nginx config 파일 수정

    certbot certonly 명령어에 -i nginx 설정이 제대로 안되었는지, 내가 착각을 한건지 https는 여전히 적용되지 않았다. 수동설정을 위해 설정 파일을 수정해야 한다.

     

    vi 명령어로 해당 위치의 파일을 연다.

    vi /etc/nginx/sites-available/default

    아래 내용은 site-available/default 파일의 주석 일부를 제외한 전체 파일 내용이다. 한글로 입력한 주석부분을 중심으로 참조하여 설정한다.

    server 설정을 두 개로 둔 이유는, 한 개의 설정위치에서 return 301 https 리다이렉트를 설정하면, 리다이렉트 횟수가 너무 많다는 오류가 나타나기 때문이다.

    # Default server configuration
    #
    server {
    	listen 80 default_server;
    	listen [::]:80 default_server;
    	return 301 https://$host$request_uri; # https 를 사용하는 서버로 리다이렉트
    
    	# SSL configuration
    	#
    	#listen 443 ssl default_server;
    	#listen [::]:443 ssl default_server;
    	
    	#ssl_certificate
    	#ssl_certificate_key
    	#
    	# Note: You should disable gzip for SSL traffic.
    	# See: https://bugs.debian.org/773332
    	#
    	# Read up on ssl_ciphers to ensure a secure configuration.
    	# See: https://bugs.debian.org/765782
    	#
    	# Self signed certs generated by the ssl-cert package
    	# Don't use them in a production server!
    	#
    	# include snippets/snakeoil.conf;
    
    	#root /var/www/html;
    
    	# Add index.php to the list if you are using PHP
    	#index index.html index.htm index.nginx-debian.html;
    
    	#server_name _;
    
    	#location / {
    		# First attempt to serve request as file, then
    		# as directory, then fall back to displaying a 404.
    		#try_files $uri $uri/ =404;
    	#}
    
    	# pass PHP scripts to FastCGI server
    	#
    	#location ~ \.php$ {
    	#	include snippets/fastcgi-php.conf;
    	#
    	#	# With php-fpm (or other unix sockets):
    	#	fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    	#	# With php-cgi (or other tcp sockets):
    	#	fastcgi_pass 127.0.0.1:9000;
    	#}
    
    	# deny access to .htaccess files, if Apache's document root
    	# concurs with nginx's one
    	#
    	#location ~ /\.ht {
    	#	deny all;
    	#}
    }
    
    
    # Virtual Host configuration for example.com
    #
    # You can move that to a different file under sites-available/ and symlink that
    # to sites-enabled/ to enable it.
    #
    server {
    	#listen 80 default_server; # 사용안함
    	#listen [::]:80 default_server; # 사용안함
    
    	listen 443 ssl default_server; # https 서비스를 위해 추가
    	listen [::]:443 ssl default_server; # https 서비스를 위해 추가
    
    	ssl_certificate /etc/letsencrypt/live/{도메인명}/fullchain.pem; # certbot으로 만든 인증서 풀체인파일(cert.pem + chain.pem)
    	ssl_certificate_key /etc/letsencrypt/live/{도메인명}/privkey.pem; # certbot으로 만든 인증서 키파일
    
    	server_name nosearchuser.com www.nosearchuser.com;
    
    	root /var/www/html;
    	index index.html index.htm index.nginx-debian.html;
    
    	location / {
    		try_files $uri $uri/ =404;
    	}
    }
    

     

    * nginx 버전마다 설정방법에 차이를 보이는 듯 하다. 다른사이트에선 ssl on;도 입력하도록 안내하지만, 추가한 뒤 재실행했을때 오류를 일으켰다.

     

    10. nginx 재실행 및 접속 확인

    아래 명령어로 nginx 를 재실행한다.

    service nginx restart

    재실행이 완료되었다면 생성한 도메인을 http로 접속시도해 본다. 필자는 http://nosearchuser.com 으로 생성했기 때문에 해당 도메인으로 접속해보았다.

     

    제대로 설정되었음을 증빙해주듯, 유효한 인증서가 적용된 웹 사이트가 표시된다.

    https가 적용된 웹사이트

    인증서는 3개월마다 주기적으로 업데이트 해야 한다고 한다. 업데이트 시점이 오면 별도의 포스트로 정리할 계획이다.

    반응형

    댓글

Designed by Tistory.