INTRO
ubuntu 22.04 + nginx 서버에 certbot을 이용하여
let's encrypt기관의 무료 인증서를 발급받아
웹 사이트에 https 보안을 사용해 볼 것이다.
1. UFW 를 사용한 방화벽 열기
- UFW(Uncomplicated Firewall)는 리눅스 데비안 계열에서 사용하는 방화벽 관리 프로그램이다.
- apt-get install 로 쉽게 설치가 가능하다.
- 직접적으로 iptables에 규칙을 추가해도 되지만, 해당 프로그램을 사용하는것이 명령에 사용에 있어 더 편리하다.
- 필자의 현재 구조는 아래와 같다.
- https 포트인 443과, http 포트인 80 포트를 모두 열어줘야하는데
- 현재 도커 컨테이너에 아파치 서버를 올린 형상이므로,
- 외부 방화벽과 컨테이너의 방화벽 모두 ufw를 이용하여 열어주었다.
$ sudo apt-get install ufw
$ sudo ufw allow 443/tcp
$ sudo ufw allow 80/tcp
// 혹시 모르니 22번 포트도 열어두자. 안그러면 enable이후 ssh 접속이 불가해질 수도..
$ sudo ufw allow 22/tcp
$ sudo ufw enable
$ sudo ufw status
// 이렇게 해도 된다.
$ sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
$ sudo iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
2. certbot 설치
- 하기 명령어를 이용하여 certbot을 설치하고,
- certbot을 이용하여 발급받은 인증서를 본인의 서버 환경에 적용해주는 패키지도 함께 설치한다.
$ sudo apt install certbot python3-certbot-nginx
3. nginx 설정
- 현재 기준(2022년 11월) 최신 버전의 nginx 를 설치하게되면, nginx 가 기본적으로 참조하는 config파일이
/etc/nginx/sites-enabled 아래 확장자 없이 default라는 파일로 생성되어있다.
- 해당 파일을 제거해주자.
- 이 다음 스텝에서는 certbot이 nginx경로를 자동 인식하여 config파일들을 변경해주는 과정이 있는데,
- /etc/nginx/sites-enabled 에 있는 default라는 파일은 참조하지 못하는 것으로 보임
- 따라서 /etc/nginx/conf.d 경로에 .conf 확장자를 가진 파일을 만들어줘야한다. (default.conf로 만들자)
- 만들고 난 뒤 certbot이 인식할 수 있게 아래와 같은 내용으로 채워준다.(발급받을 도메인 주소를 적어주자)
- certbot에서 해당 파일을 수정할 예정이다.
server {
listen 80;
listen [::]:80;
server_name "발급받을 도메인 주소(aaaa.com)";
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
- 하기 명령어를 통해 인증서를 발급받는다.
- 인증서를 생성하게 되면, /etc/nginx/conf.d 경로에 있는default.conf파일이 수정된다
$ sudo certbot --nginx
- 이후 별다른 설정 없이 본인의 도메인에 접속해보면 https보안이 적용되어 있는 것을 확인할 수 있다.
- 발급받은 인증서는 90일의 유효기간이 있고,
- 이를 갱신하는 명령어는 아래와 같다.
$ sudo certbot renew --dry-run
- 필자의 환경대로 설치했다면, /etc/cron.d 폴더 내
- crontab으로 하루 2회씩 수행되는 스크립트가 설치되어있을것이다.
- 이는 만료일이 30일 이하로 남은 인증서들을 체크하여 갱신해준다.
/etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc. Renewal will only occur if expiration
# is within 30 days.
#
# Important Note! This cronjob will NOT be executed if you are
# running systemd as your init system. If you are running systemd,
# the cronjob.timer function takes precedence over this cronjob. For
# more details, see the systemd.timer manpage, or use systemctl show
# certbot.timer.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
4. certonly 옵션을 통한 수동 적용(2023.02.09)
- 하기 명령어를 통해 인증서를 발급받게되면, nginx config파일을 certbot이 건드리지 않게 된다.
- 따라서 수동으로 config 파일에 인증서를 적용시켜줘야한다.
sudo certbot certonly -d "domain.com"
- 아래 과정을 거치면 /etc/letsencrypt/live/domain.com 경로에 4가지 인증서가 생성된다.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Nginx Web Server plugin (nginx)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 1
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): [이메일 입력]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Account registered.
Requesting a certificate for domain.com
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/domain.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/domain.com/privkey.pem
This certificate expires on 2023-05-10.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 이 중 사용해야 할 인증서는 fullchain.pem, privkey.pem이다.
- 각 인증서가 뭔지 간략하게 짚고넘어가보면..
- cert.pem : let's encrypt에서 서명한 인증서
- chain.pem : Let's Encrypt의 중간 인증서(intermediate certificate)
- fullchain.pem : cert.pem + chain.pem
- privkey.pem : 인증서의 개인키
- privkey.pem을 바로 사용해도 되지만, .key로 변환해서 사용하는 경우를 봐서 아래에 방법을 정리
sudo openssl rsa -in privkey.pem -text > cert.key
- 이제 nginx config파일에 인증서의 경로를 입력해주면 된다.
- ssl_ciphers는 TLS 인증에서 사용할 알고리즘을 정의하는것.
- 입력하지 않아도 default로 적용되나, 높은 수준의 보안을 요구하는 곳에서는 필수로 사용함
server {
server_name domain.com;
listen 443 ssl;
ssl_protocols TLSv1.3; #TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate [fullchain.pem 인증서의 경로];
ssl_certificate_key [privkey.pem 인증서의 경로];
ssl_ciphers 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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
client_max_body_size 15M;
location / {
root /data/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
마무리
Ubuntu + nginx 기반의 서버에서 https보안을 위한 SSL/TLS 인증서를 발급받아 적용시키는 방법에 대해 포스팅했다.
개인적인 프로젝트를 진행할 때에는 매우 유용하게 쓰이니 알아두면 좋을 것 같다.
-퍼가실 때는 출처를 꼭 같이 적어서 올려주세요!
'DevOps > [Linux]' 카테고리의 다른 글
[Nginx+보안] Nginx 서버가 Nginx인지 모르게 만들기 (0) | 2023.03.04 |
---|---|
[Log 관리] Logrotate 를 활용한 로그파일 관리(feat. Nginx) (0) | 2023.02.28 |
[Linux] Swap memory 설정하기 (0) | 2022.11.23 |
[Linux Ubuntu] sudo: command not found 해결하기 (0) | 2022.11.10 |
[ubuntu + apache2 + certbot] certbot을 이용한 https 보안 사용하기 with docker (0) | 2022.11.09 |