certbot 을 주기적으로 renew 한 후 , 인증서가 갱신되면 post_hook 으로
새로운 SSL 인증서 .pem 을 Spring Project 의 .pfx 로 변환하고, 스프링 프로젝트를 재실행 해주는 코드가 필요하다.

지난글의 https://blog.1day1.org/712 에서 언급한 pem => pfx 변환 코드를 좀더 개선했다.

 

스프링 프로젝트에 letsencrypt 인증서를 사용해보자 ( feat. pfx / PCKS12)

지난글에 이어 https://blog.1day1.org/711 스프링 프로젝트에 .pem 인증서를 사용해보자. letsencrypt 를 좀더 활용해보자. (feat. post_hook)letsencrypt 를 잘 사용하고 있는데, 주로 개발용으로 사용했다.간단한

blog.1day1.org

개선한 코드는 letsencrypt의 pem 인증서의 날짜와 변환한 pfx 날짜를 비교해서 변환할지 체크하는 코드를 추가했다.

# cat lets-pem2pfx.sh 
#!/bin/bash

if [ "$2" == "" ]; then
	echo "Usage) $0 {domain} {out-dir/out-file.pfx} {convert-now}";
	exit;
fi

out_dir=$PWD
domain=$1
out_file=$2
convert=$3

password=124345

######
lets_dir=/etc/letsencrypt/live

if [ "$convert" == "convert-now" ]; then
	echo 
else
	certbot certificates --cert-name $domain
fi
ls -al $lets_dir

cd $lets_dir/$domain

# file mtime check.
echo 
echo -n "Origin: "
echo `date +%s%N --reference cert.pem`
echo " "`date  --reference cert.pem`
echo 
echo -n "Target: "
echo `date +%s%N --reference $out_dir/$out_file`
echo " "`date  --reference $out_dir/$out_file`
echo 
if [ "cert.pem" -nt "$out_dir/$out_file" ]; then
	printf '%s\n' "cert.pem is newer than $out_dir/$out_file : need to update new"
else
	printf '%s\n' "cert.pem is older than $out_dir/$out_file"
	echo "No action";
	echo
	exit 122 # fail code ( 0~256 )
fi


if [ "$convert" == "convert-now" ]; then
	openssl pkcs12 -export \
	 -out $out_dir/$out_file \
	 -inkey privkey.pem -in cert.pem -certfile chain.pem \
	 -passin pass:$password -passout pass:$password
	echo "Convert Done";
	ls -al $out_dir/$out_file;
fi

exit 200;
# end file

위 코드를 기반으로 renew 시에 post_hook 에서 처리할 스크립트는 다음과 같다.

# cat renewal-ssl-restart.sh 
#!/bin/bash

readlink=$(readlink -f $0)
dirpath=$(dirname $readlink)


echo 
echo `date`
echo $dirpath;
cd $dirpath;

# convert pem 2 pfx - renewal pem
bash lets-pem2pfx.sh your-domain.com ssl/your-domain.com.pfx convert-now
retCode=$?

if [ "$retCode" == "200" ]; then
	echo "convert-done - do action"

	# restart - tomcat
	echo "Shutdown..."
	shutdown.sh
	sleep 5

	echo "Start up..."
	startup.sh
fi

letsencrypt 의 인증서가 갱신이 되면 post_hook 으로 해당 코드를 실행하여,
pem => pfx 변환 / 스프링프로젝트 재실행 해준다. 위 프로젝트 재실행 코드는 본인에 맞게 수정하여 쓴다.

해당 코드를 콘솔에서 실행까지 테스트 한 후에 /etc/letsencrypt/renewal/yourdomain.conf 의 post_hook 에 넣어준다.

# Options used in the renewal process
[renewalparams]
authenticator = nginx
installer = nginx
account = af93d65834vadv37436bddsfh092ad2a
manual_public_ip_logging_ok = None
#pre_hook = systemctl stop nginx
post_hook = systemctl restart nginx ; bash /root/bin/renewal-ssl-restart.sh >> /var/log/nginx/renewal_ssl_restart-$(date +\%Y-\%m-\%d).log
server = https://acme-v02.api.letsencrypt.org/directory

다음 명령으로 테스트 해본다.

certbot renew --cert-name your-domain.com --dry-run

테스트 명령 후에 혹시 이런 에러가 보일 수 있다.

renewal-ssl-restart.sh >> /var/log/nginx/renewal_ssl_restart-$(date +\%Y-\%m-\%d).log
Error output from post-hook command systemctl:
Another instance of Certbot is already running.

해당 bash 코드에 certbot 확인하는 코드가 있었는데, 해당 코드를 post_hook 에서 실행되지 않게 고쳐줬다.(아래 부분이 고친 코드)

if [ "$convert" == "convert-now" ]; then
	echo 
else
	certbot certificates --cert-name $domain
fi

위 코드는 인증서 확인용 코드인데, 없어도 무방하니 해당 부분 지워도 된다.

테스트 까지 완료했다면, 이제 기다리면 된다.

 

내가 쓰고 있는 인증서는 30일정도 후에 업데이트 될 듯 하다(잘 되길...)

 

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,

letsencrypt 를 잘 사용하고 있는데, 주로 개발용으로 사용했다.

간단한 사용법은 https://blog.1day1.org/657 에서 확인.

 

letsencrypt 초간단 설치 in ubuntu , nginx (feat. certbot)

https 를 사용하는 것은 옵션이 아니라 이젠 필수요소인듯 하다. 명령은 2줄이면 될려나? apt install certbot python3-certbot-nginx certbot --nginx -d {도메인} -d {여러개일때 도메인 추가} 나중에 도메인을 추가

blog.1day1.org

좀더 프로덕션에 사용해 볼까 하는 생각에 좀더 자동화를 해보려고 알아보고 있다.

# cat /etc/letsencrypt/renewal/yoursite.com.conf 
# renew_before_expiry = 30 days
version = 1.11.0
archive_dir = /etc/letsencrypt/archive/yoursite.com
cert = /etc/letsencrypt/live/yoursite.com/cert.pem
privkey = /etc/letsencrypt/live/yoursite.com/privkey.pem
chain = /etc/letsencrypt/live/yoursite.com/chain.pem
fullchain = /etc/letsencrypt/live/yoursite.com/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = nginx
installer = nginx
account = ef9ksjdkfjskd3sdf5sdf3s23gf12g452t4g232ad2a
manual_public_ip_logging_ok = None
pre_hook = systemctl stop nginx
post_hook = systemctl start nginx
server = https://acme-v02.api.letsencrypt.org/directory

3개월(90일) 후에 재인증(?)을 해줘야 한다.
위 설정에서 pre_hook / post_hook 부분에서
systemctl start nginx 로 하면 nginx 가 정상으로 실행되지 않는 현상이 있다.

실행 체크는 certbot renew --dry-run 으로 해보면 된다.(아래와 비슷한 에러)

2024/08/04 01:40:02 [emerg] 22375#22375: bind() to 0.0.0.0:80 failed (98: Address already in use)
2024/08/04 01:40:02 [emerg] 22375#22375: bind() to 0.0.0.0:443 failed (98: Address already in use)
2024/08/04 01:40:02 [notice] 22375#22375: try again to bind() after 500ms
2024/08/04 01:40:02 [emerg] 22375#22375: bind() to 0.0.0.0:80 failed (98: Address already in use)
2024/08/04 01:40:02 [emerg] 22375#22375: bind() to 0.0.0.0:443 failed (98: Address already in use)
2024/08/04 01:40:02 [notice] 22375#22375: try again to bind() after 500ms
2024/08/04 01:40:02 [emerg] 22375#22375: bind() to 0.0.0.0:80 failed (98: Address already in use)
2024/08/04 01:40:02 [emerg] 22375#22375: bind() to 0.0.0.0:443 failed (98: Address already in use)

보통 저런 에러는 nginx 가 실행중이라 start 를 해서 이미 80/443 포트를 사용중이라는 에러
(원인의 예상은 renew 체크시 web 접속이 필요해서 nginx 가 실행중이어야 하는 듯 싶다.)
letsencrypt 인증서버에서 .well-known 서버접속해서 확인하는 듯 하다.

13.214.188.135 - - [04/Aug/2024:01:44:32 +0900] "GET /.well-known/acme-challenge/G_jAk7TzDtYa5B9RRH2-tBY5jvvOkxqsz8ZLEgnV5_8 HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
18.226.4.132 - - [04/Aug/2024:01:44:32 +0900] "GET /.well-known/acme-challenge/G_jAk7TzDtYa5B9RRH2-tBY5jvvOkxqsz8ZLEgnV5_8 HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
16.16.94.36 - - [04/Aug/2024:01:44:33 +0900] "GET /.well-known/acme-challenge/G_jAk7TzDtYa5B9RRH2-tBY5jvvOkxqsz8ZLEgnV5_8 HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
16.16.94.36 - - [04/Aug/2024:01:44:33 +0900] "GET /.well-known/acme-challenge/II0XkQ6LIjFkl_jGey5q98RyZd231HG5Xs6amebSOjM HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
18.226.4.132 - - [04/Aug/2024:01:44:42 +0900] "GET /.well-known/acme-challenge/II0XkQ6LIjFkl_jGey5q98RyZd231HG5Xs6amebSOjM HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
54.191.171.212 - - [04/Aug/2024:01:44:42 +0900] "GET /.well-known/acme-challenge/II0XkQ6LIjFkl_jGey5q98RyZd231HG5Xs6amebSOjM HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"

에러가 발생해서 다음처럼 수정하였다. (nginx 중지 안해도 되니 pre_hook 은 주석처리 )

#pre_hook = systemctl stop nginx
post_hook = systemctl restart nginx

일단 dry-run 으로 해보니 정상적이었다.(실제 90일 후에 어떨지 살펴봐야겠지)

 

다음 활용은 letsencrypt 인증서 (.pem) 를 spring boot  의 ( .pfx ) 파일로 변환해서 사용해봐야겠다.

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,

https 를 사용하는 것은 옵션이 아니라 이젠 필수요소인듯 하다.

명령은 2줄이면 될려나?  

apt install certbot python3-certbot-nginx
certbot --nginx -d {도메인} -d {여러개일때 도메인 추가}

나중에 도메인을 추가하려면 2번째 명령을 -d 옵션 추가해서 다시 해주면 된다.

명령 후 다음과 같은 메시지가 나오면.

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

2번 즉, http 로 접속하면 https 로 리다이렉트 해준다. (본인의 사례에 따라 1번이 필요하면 1번)

자동으로 cron.d 에도 넣어주어 주기적으로 갱신한다.(즉, 신경쓸 것이 없다)

예전에는 좀 귀찮았던것 같은데, 요즘은 그냥 한줄이면 끝나네.

끝.

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,