Views: 8
Installation of Let’s Encrypt Certification On Ubuntu(OCI)
이번 글에서는 무료 SSL인 Let’s Encrypt 를 이용하여 Oracle Cloud Infrastructure(OCI)에 와일드카드(*) 인증서를 받는 법을 기록한다.
In this article, I will record how to obtain a wildcard(*) certificate using Let’s Encrypt, a free SSL, on Oricle Cloud Infrastructure(OCI).
환경
- 오라클 클라우드 환경(Oracle Cloud Infrastructure; OCI)
- Ubuntu 20.04, Nginx
- 개인 도메인(illuwa.net)을 구글 도메인(Domains.google.com)에서 운영
패키지 설치
SSL 인증서는 원래 돈을 주고 구매를 해야 하나, Let’s Encrypt를 이용하면 무료로 사용할 수 있다. 3개월 마다 갱신 해야 한다는 제약 사항이 있으나, 이 또한 자동 갱신이 가능하므로 사용이 편리하다.
Normally, SSL certificates have to be purchased with money, but they can be used for free if Let’s Encrypt is used. There is a constraint that it must be renewed every 3 months, but this can also be done automatically, making it convenient to use.
다른 환경의 OS를 사용하고 있는 경우 명령어가 다를 수 있으므로 아래 사이트에서 명령어를 확인한다. 기본적으로 명령어 일부만 다를 뿐 전체적인 흐름은 같다.
If you are using a different OS environment, the commands may be different, so check the commands on the following website. Basically, only part of the command may be different, but the overall flow is the same.
일부 라이브러리 등은 이미 설치 되어 있을 수 있으나, 설치된 경우 bypass되므로 아래 명령어는 모두 실행한다.
Some libraries may already be installed, but they are bypassed if they are installed, so all of the below commands are executed.
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다... 완료
상태 정보를 읽는 중입니다... 완료
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
libfuse2
Use 'sudo apt autoremove' to remove it.
The following additional packages will be installed:
python3-acme python3-certbot python3-configargparse python3-configobj
python3-icu python3-josepy python3-parsedatetime python3-rfc3339 python3-tz
python3-zope.component python3-zope.event python3-zope.hookable
python3-zope.interface
제안하는 패키지:
python3-certbot-apache python3-certbot-nginx python-certbot-doc
python-acme-doc python-configobj-doc
다음 새 패키지를 설치할 것입니다:
certbot python3-acme python3-certbot python3-configargparse
python3-configobj python3-icu python3-josepy python3-parsedatetime
python3-rfc3339 python3-tz python3-zope.component python3-zope.event
python3-zope.hookable python3-zope.interface
0개 업그레이드, 14개 새로 설치, 0개 제거 및 6개 업그레이드 안 함.
890 k바이트 아카이브를 받아야 합니다.
이 작업 후 4,415 k바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n] y
받기:1 http://deb.debian.org/debian bullseye/main arm64 python3-josepy all 1.2.0 -2 [28.4 kB]
받기:2 http://deb.debian.org/debian bullseye/main arm64 python3-tz all 2021.1-1 [34.8 kB]
받기:3 http://deb.debian.org/debian bullseye/main arm64 python3-rfc3339 all 1.1- 2 [6,768 B]
받기:4 http://deb.debian.org/debian bullseye/main arm64 python3-acme all 1.12.0- 2 [34.6 kB]
받기:5 http://deb.debian.org/debian bullseye/main arm64 python3-configargparse a ll 1.2.3-1 [25.2 kB]
받기:6 http://deb.debian.org/debian bullseye/main arm64 python3-configobj all 5. 0.6-4 [35.8 kB]
받기:7 http://deb.debian.org/debian bullseye/main arm64 python3-parsedatetime al l 2.6-1 [41.3 kB]
받기:8 http://deb.debian.org/debian bullseye/main arm64 python3-zope.hookable ar m64 5.0.1-1+b2 [12.7 kB]
받기:9 http://deb.debian.org/debian bullseye/main arm64 python3-zope.interface a rm64 5.2.0-1 [141 kB]
받기:10 http://deb.debian.org/debian bullseye/main arm64 python3-zope.event all 4.4-3 [9,420 B]
받기:11 http://deb.debian.org/debian bullseye/main arm64 python3-zope.component all 4.3.0-3 [43.1 kB]
받기:12 http://deb.debian.org/debian bullseye/main arm64 python3-certbot all 1.1 2.0-2 [194 kB]
받기:13 http://deb.debian.org/debian bullseye/main arm64 certbot all 1.12.0-2 [4 9.7 kB]
받기:14 http://deb.debian.org/debian bullseye/main arm64 python3-icu arm64 2.5-1 +b2 [233 kB]
내려받기 890 k바이트, 소요시간 0초 (1,948 k바이트/초)
패키지를 미리 설정하는 중입니다...
Selecting previously unselected package python3-josepy.
(데이터베이스 읽는중 ...현재 95086개의 파일과 디렉터리가 설치되어 있습니다.)
Preparing to unpack .../00-python3-josepy_1.2.0-2_all.deb ...
Unpacking python3-josepy (1.2.0-2) ...
Selecting previously unselected package python3-tz.
Preparing to unpack .../01-python3-tz_2021.1-1_all.deb ...
Unpacking python3-tz (2021.1-1) ...
Selecting previously unselected package python3-rfc3339.
Preparing to unpack .../02-python3-rfc3339_1.1-2_all.deb ...
Unpacking python3-rfc3339 (1.1-2) ...
Selecting previously unselected package python3-acme.
Preparing to unpack .../03-python3-acme_1.12.0-2_all.deb ...
Unpacking python3-acme (1.12.0-2) ...
Selecting previously unselected package python3-configargparse.
Preparing to unpack .../04-python3-configargparse_1.2.3-1_all.deb ...
Unpacking python3-configargparse (1.2.3-1) ...
Selecting previously unselected package python3-configobj.
Preparing to unpack .../05-python3-configobj_5.0.6-4_all.deb ...
Unpacking python3-configobj (5.0.6-4) ...
Selecting previously unselected package python3-parsedatetime.
Preparing to unpack .../06-python3-parsedatetime_2.6-1_all.deb ...
Unpacking python3-parsedatetime (2.6-1) ...
Selecting previously unselected package python3-zope.hookable.
Preparing to unpack .../07-python3-zope.hookable_5.0.1-1+b2_arm64.deb ...
Unpacking python3-zope.hookable (5.0.1-1+b2) ...
Selecting previously unselected package python3-zope.interface.
Preparing to unpack .../08-python3-zope.interface_5.2.0-1_arm64.deb ...
Unpacking python3-zope.interface (5.2.0-1) ...
Selecting previously unselected package python3-zope.event.
Preparing to unpack .../09-python3-zope.event_4.4-3_all.deb ...
Unpacking python3-zope.event (4.4-3) ...
Selecting previously unselected package python3-zope.component.
Preparing to unpack .../10-python3-zope.component_4.3.0-3_all.deb ...
Unpacking python3-zope.component (4.3.0-3) ...
Selecting previously unselected package python3-certbot.
Preparing to unpack .../11-python3-certbot_1.12.0-2_all.deb ...
Unpacking python3-certbot (1.12.0-2) ...
Selecting previously unselected package certbot.
Preparing to unpack .../12-certbot_1.12.0-2_all.deb ...
Unpacking certbot (1.12.0-2) ...
Selecting previously unselected package python3-icu.
Preparing to unpack .../13-python3-icu_2.5-1+b2_arm64.deb ...
Unpacking python3-icu (2.5-1+b2) ...
python3-configargparse (1.2.3-1) 설정하는 중입니다 ...
python3-parsedatetime (2.6-1) 설정하는 중입니다 ...
python3-icu (2.5-1+b2) 설정하는 중입니다 ...
python3-zope.event (4.4-3) 설정하는 중입니다 ...
python3-zope.interface (5.2.0-1) 설정하는 중입니다 ...
python3-tz (2021.1-1) 설정하는 중입니다 ...
python3-zope.hookable (5.0.1-1+b2) 설정하는 중입니다 ...
python3-configobj (5.0.6-4) 설정하는 중입니다 ...
python3-josepy (1.2.0-2) 설정하는 중입니다 ...
python3-rfc3339 (1.1-2) 설정하는 중입니다 ...
python3-zope.component (4.3.0-3) 설정하는 중입니다 ...
python3-acme (1.12.0-2) 설정하는 중입니다 ...
python3-certbot (1.12.0-2) 설정하는 중입니다 ...
certbot (1.12.0-2) 설정하는 중입니다 ...
Created symlink /etc/systemd/system/timers.target.wants/certbot.timer → /lib/sys temd/system/certbot.timer.
Processing triggers for man-db (2.9.4-2) ...
디렉토리 및 파일 사전 준비
나중에 설정 등을 깔끔하고 알기 쉽게 하기 위해 인증서 발급에 사용될 디렉토리를 미리 세팅한다.
To make the configuration clean and easy to understand later, the directory used for certificate issuance is set up in advance.
sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenges
sudo touch /etc/nginx/snippets/letsencrypt.conf
sudo chown root:ubuntu /etc/nginx/snippets/letsencrypt.conf
sudo chmod 775 /etc/nginx/snippets/letsencrypt.conf
이후, /etc/nginx/snippets/letsencrypt.conf 를 편집하여 아래 내용을 붙여 넣는다.
Next, edit the /etc/nginx/snippets/letsencrypt.conf and paste the following contents.
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}
SSL 인증서 발급
모든 도메인에 대한 인증서 발급은 3가지 방식(Standalone, Webroot, DNS) 중 DNS 방식으로 발급을 받는다. DNS 방식은 1. 콘솔 명령어 실행 > 2. DNS에 이름 및 값 추가 > 3. 콘솔 엔터 순으로 연결된다.
The issuance of a certificate for all domains will be obtained using the DNS method among the three methods (Standalone, Webroot, DNS). The DNS method is connected in the order of 1. executing console command > 2. adding name and value to DNS > 3. entering the console.
Let’s Encrypt에서 특정 문구를 DNS 에 추가하라고 요청이 오면 그 문구를 copy해서 DNS 관리자(본인의 경우 Google Domains)에서 도메인 이름, 값, 형식(TXT)을 추가해주고 난 뒤 잠시 기다렸다가 콘솔의 명령어를 진행하는 순서이다.
When a request comes from Let’s Encrypt to add a specific phrase to DNS, copy that phrase and add the domain name, value, and type (TXT) to the DNS administrator (in the case of Google Domains). After waiting for a while, the order of executing the console command will be proceeded.
sudo certbot certonly --manual --preferred-challenges dns -d "*.illuwa.net"
이메일을 입력하라고 물어오면, 본인이 사용하는 메일을 기재한다.
When asked to enter email, enter the email that you are using.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): illuwa@gmail.com
Let’s Encrypt 이용 약관의 동의 여부를 물어온다. 당연히 동의해야 서비스 이용이 가능하므로 Y를 눌러준다.
If asked for agreement to the terms of service for Let’s Encrypt, click “Y” to agree, as it is necessary to use the service.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017-w-v1.3-notice.pdf.
You must agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
인증서 발행이 되고 나면 뉴스레터를 수신할 것인지를 물어온다. (이건 취향에 따라 선택하기로 한다.)
Whether to receive the newsletter after the certificate is issued is asked. (This is according to personal preference.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 *.illuwa.net
여기가 가장 중요하다. 아래 그림에서 6번째 줄 및 8번째 줄에 있는 내용으로 DNS 관리 페이지로 가서 도메인을 생성해 준 후 대기시간(대충 5분 내외) 한다. DNS에 잘 반영이 되었는지를 확인하려면 아래 사이트에서 주소를 쳐서 제일 오른쪽의 TXT 부분에 내용이 정상적으로 뜨는지 확인해본다.
To make sure that the domain has been properly reflected in the DNS, you can check it by entering the address in the website below and verifying that the content appears correctly in the TXT section on the right.
https://toolbox.googleapps.com/apps/dig/
TXT 부분에서 입력한 내용이 확인된다면 엔터를 처 Let’s Encrypt가 DNS에 확인할 수 있도록 한다.
If the content entered in the TXT section is confirmed, press Enter to allow Let’s Encrypt to verify in the DNS.
Performing the following challenges:
dns-01 challenge for *.illuwa.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.illuwa.net with the following value:
-NjMwobWuM--ZLA5JnrjMrrwDRi_cHp5atBJ9gL-RI0
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
이후 기다리면 아래와 같이 인증서가 성공적으로 발행되었음을 확인할 수 있다.
Then, after waiting, you can confirm that the certificate has been successfully issued as follows.
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: illuwa@gmail.com).
We were unable to subscribe you the EFF mailing list because your e-mail address appears to be invalid. You can try again later by visiting https://act.eff.org.
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/*.illuwa.net/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/*.illuwa.net/privkey.pem
Your certificate will expire on 2022-11-30. To obtain a new or
tweaked version of this certificate in the future, simply run
certbot again. To non-interactively renew *all* of your
certificates, run "certbot renew"
- 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
인증서 자동 갱신(Automatic renewal of certificate)
앞서 진행한 인증서 발행 마지막 화면을 보면 인증서 갱신을 하고 싶을 경우 certbot renew 를 하면된다고 기재되어 있다.(상단 실행결과 14번째 줄). 만료 전 저 명령어를 실행하면 되므로, 스케쥴러에 등록해서 자동으로 명령을 내리도록 한다.
If you look at the last screen of the certificate issuance that you previously carried out, it is noted that if you want to update the certificate, you can just do “certbot renew” (line 14 of the top execution results). So, you should schedule it to automatically give the command before it expires.
일단 인증서 만료일을 확인해보자. 인증서 유효기간이 3개월이므로 11번째 라인에 89일 남았음을 알 수 있다.
Let’s check the expiration date of the certificate first. You can see that the certificate validity period is 3 months and 89 days are left on line 11.
sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: *.illuwa.net
Serial Number: -------------------------------------(가림처리)
Key Type: RSA
Domains: *.illuwa.net
Expiry Date: 2022-11-30 03:24:16+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/*.illuwa.net/fullchain.pem
Private Key Path: /etc/letsencrypt/live/*.illuwa.net/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
저 날짜가 도래하기 전 자동 갱신을 위해 아래와 같이 설정한다.
To automatically renew the certificate before that date, set it up as follows.
sudo su
crontab -e
초기 설정 서버라면 crontab 을 만들면서 에디터를 고르라고 뜨는데 본인이 편한 에디터로 선택한다.
If it is a newly set up server, you will be asked to create a crontab and choose an editor, so choose the editor that you are comfortable with.
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.tiny
3. /bin/ed
Choose 1-3 [1]: 1
~3 중 1개
이후, 아래와 같이 내용을 붙여넣기 해준다. 이미 내용이 있다면 제일 마지막 2줄을 입력해 준다.
Then, paste the following content. If there is already content, add the last two lines.
Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
0 3 * * * /home/ubuntu/certbot-auto renew --renew-hook "sudo service nginx restart"
0 4 * * 1 root shutdown now -r
SSL 인증서를 웹서버에 적용(Apply SSL certificate to web server)
이제 거의 끝나간다. 인증서를 발급 받았다면 적용을 위해 dhparam 을 암호화 한다. 시간이 꽤 오래(한 20분?) 걸리므로 잠시 다른 일을 하고 와도 좋다.
Now we are almost done. After getting the certificate, we encrypt dhparam to apply it. It takes quite a while (about 20 minutes?) so it’s okay to come back later and do something else.
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
Generating DH parameters, 4096 bit long safe prime, generator 2
This is going to take a long time
..............................+...................................................
............................+.....................................................
..................................................................................
....+..+............................+.............................................
..................................................................................
........................................................++*++*++*
이후, 초기에 설정했던 파일들을 수정해준다.
Later, modify the files initially set up.
sudo touch /etc/nginx/snippets/ssl.conf
sudo chmod 777 /etc/nginx/snippets/ssl.conf
sudo vi /etc/nginx/snippets/ssl.conf
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
이후, 수정되지 않도록 권한을 변경한다.
Later, change the permissions so that they cannot be modified.
sudo chmod 644 /etc/nginx/snippets/ssl.conf
NGINX에 인증서 반영하기(Implementing a certificate in NGINX.)
sudo vi /etc/nginx/site-available/default
아래 내용 중에 illuwa.net 이라고 된 부분은 본인의 도메인에 맞게 변경한다.
Replace the part with “illuwa.net” with your own domain accordingly in the content below.
# Default HTTPS server configuration
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name illuwa.net;
ssl_certificate /etc/letsencrypt/live/illuwa.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/illuwa.net/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/illuwa.net/fullchain.pem;
include /etc/nginx/snippets/ssl.conf;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
location / {
try_files $uri $uri/ =404;
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
location ~ /\.ht {
deny all;
}
}
# HTTPS www. server configuration
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.illuwa.net;
ssl_certificate /etc/letsencrypt/live/illuwa.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/illuwa.net/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/illuwa.net/fullchain.pem;
include /etc/nginx/snippets/ssl.conf;
location / {
return 301 https://illuwa.myds.me$request_uri;
}
}
# Default server configuration
server {
listen 80;
listen [::]:80 default_server;
server_name illuwa.net;
include /etc/nginx/snippets/letsencrypt.conf;
location / {
return 301 https://illuwa.myds.me$request_uri;
}
}
# HTTP - CNAME Connect www.illuwa.net to illuwa.net
server {
listen 80;
listen [::]:80;
server_name www.illuwa.net;
include /etc/nginx/snippets/letsencrypt.conf;
location / {
return 301 https://illuwa.myds.me$request_uri;
}
}
설정에 문제가 없는지 확인 후 nginx를 재시작한다.
Check if there are no problems with the configuration and then restart NGINX.
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo service nginx restart