post-image

Thiết lập HTTPS với chứng chỉ SSL miễn phí Let’s Encrypt cho Nginx trên CentOS 7

Tổng quan
Mô hình hoạt động khi cài đặt Let's Encrypt trên Nginx, CentOS

Let’s Encrypt CA cung cấp chứng chỉ SSL miễn phí

Let’s Encrypt là một tổ chức cấp chứng chỉ SSL mới cung cấp các chứng chỉ SSL miễn phí, cho phép bạn thiết lập mã hóa HTTPS cho máy chủ web. Hiện nay, các tổ chức cấp chứng chỉ SSL đều thu phí do liên quan đến vấn đề bảo hiểm, trong khi đó Let’s Encrypt hoạt động miễn phí và được tài trợ bởi một số công ty hoạt động trong lĩnh vực công nghệ thông tin như Facebook, Chrome (Google), Firefox, Vultr, Cisco…

Sử dụng Let’s Encrypt khi gặp rủi ro đương nhiên bạn sẽ không được bảo hiểm. Vấn đề này cũng không lớn lắm nếu website của bạn chỉ hoạt động trong các lĩnh vực như cung cấp nội dung, tư vấn, hướng dẫn.

Let’s Encrypt giúp cho website của bạn có thể hoạt động ở giao thức HTTPS, đây cũng là một tiêu chí giúp cài thiện điểm SEO, tăng thứ hạng của bạn trên các hệ thống tìm kiếm. Trong bài viết này, chúng tôi sẽ hướng dẫn bạn thiết lập HTTPS cho website sử dụng chứng chỉ SSL miễn phí từ Let’s Encrypt. Máy chủ web sử dụng là NginX hoạt động trên hệ điều hành CentOS 7 (một hệ điều hành khá phổ biến cho máy chủ web hiện nay, với các hệ điều hành Linux khác cũng tương tự). Với môi trường Windows và webserver Apache chúng tôi sẽ có những bài hướng dẫn riêng.

Các yêu cầu cài đặt Let’s Encrypt

  1. Server đã cài đặt hệ điều hành CentOS 7, nên tạo tài khoản khác tài khoản root và phân quyền chạy sudo để cài đặt.
  2. Server đã cài đặt webserver NginX (Xem Hướng dẫn cài đặt NginX, PHP, MariaDB trên CentOS 7) hoặc xem bước 1.
  3. Tên miền của bạn phải đã được cấu hình bản ghi A để phân giải trên DNS, nếu bạn sử dụng cả www.yourdomain.com thì cũng cần bản ghi A cho tên miền con này. Bạn có thể sử dụng nslookup để kiểm tra xem các phân giải tên miền đã hoạt động chưa.

Ok, nếu bạn đã đáp ứng đầy đủ các yêu cầu trên, chúng ta sẽ bắt đầu cài đặt Let’s Encrypt. ## Bước 1: Cài đặt NginX

Nếu bạn chưa có NginX thực hiện cài đặt

# yum install epel-release # yum install nginx
Code language: PHP (php)

Bước 2: Tải Let’s Encrypt

Cách nhanh nhất cài Let’s Encrypt client là clone gói letsencrypt/letsencrypt từ GitHub, trước đó hãy cài đặt git client.

# yum install git
Code language: PHP (php)

Sau khi git được cài đặt, chuyển đến thư mục /opt và lấy Let’s Encrypt client về máy

# cd /opt # git clone https://github.com/letsencrypt/letsencrypt
Code language: PHP (php)

Bước 3: Tạo chứng chỉ SSL miễn phí từ Let’s Encrypt

Trước khi gửi yêu cầu cấp chứng chỉ SSL, phải dừng webserver Nginx do dịch vụ cấp chứng chỉ Let’s Encrypt hoạt động ở cổng 80. Chú ý: nếu các cổng 80 và 443 chưa được mở trên firewall, thực hiện mở các cổng này:

# firewall-cmd --add-service=http # firewall-cmd --add-service=https # firewall-cmd --runtime-to-permanent
Code language: PHP (php)

Nếu iptables đang hoạt động, cần thêm các truy nhập cho HTTP và HTTPS như sau:

# iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT # iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT
Code language: PHP (php)

Ok, chúng ta tạm dừng webserver Nginx

# systemctl stop nginx
Code language: PHP (php)

Kiểm tra xem còn ứng dụng nào hoạt động trên cổng 80 không cho chắc ăn.

# ss -tln
Code language: PHP (php)

Ok, bước tiếp theo chúng ta yêu cầu chứng chỉ SSL từ Let’s Encrypt (tạo private key giữ trên server và CSR tự động gửi đến Let’s Encrypt). Chuyển đến thư mục cài đặt letsencrypt và chạy lệnh letsencrypt-auto

# cd /opt/letsencrypt # ./letsencrypt-auto certonly --standalone -d yourdomain.com -d www.yourdomain.com
Code language: PHP (php)

Chú ý thay yourdomain.com thành tên miền của bạn. Sau khi các gói được cài đặt Let’s Encrypt client sẽ yêu cầu bạn nhập một số thông tin như tên miền, tên công ty, tài khoản email để yêu cầu cấp lại chứng chỉ… để tạo private key và CSR. CSR sẽ được tự động gửi đến Let’s Encrypt thông qua ứng dụng client này và Let’s Encrypt tạo chứng chỉ SSL cũng tự động gửi về và lưu các file liên quan ở thư mục /etc/letsencrypt/live. Câu lệnh trên hoàn thành với thông báo

IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/allaravel.com/fullchain.pem. Your cert will expire on 2017-12-04. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Code language: PHP (php)

Bước 4: Cài đặt chứng chỉ SSL của Let’s Encrypt cho Nginx

Liệt kê các chứng chỉ được cấp cho tên miền của bạn

# ls -al /etc/letsencrypt/live/ # ls -al /etc/letsencrypt/live/yourdomain.com
Code language: PHP (php)

Cấu hình Nginx server block, thường thì các server chạy cho nhiều domain khác nhau nên mỗi domain sẽ tạo file .conf khác nhau trong trong thư mục /etc/nginx/conf.d. Mở file này và thêm vào

server { listen 443 default_server; # SSL configuration ssl on; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; }
Code language: PHP (php)

Cấu hình redirect các toàn bộ traffict sang https

server { listen 80; server_name yourdomain.com www.yourdomain.com; rewrite ^/(.*) https://yourdomain.com$1 permanent; }
Code language: PHP (php)

Lưu file Ctrl + O và thoát ra Ctrl + X. Kiểm tra xem cú pháp của nginx đã đúng chưa, nếu chuẩn rồi thì start Nginx.

# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # systemctl start nginx
Code language: PHP (php)

Giờ chúng ta mở trình duyệt ra và chạy http://yourdomain.com nó sẽ tự động chuyển về https://yourdomain.com và nội dung trang hoạt động bình thường. Cài đặt chứng chỉ SSL thành công, chúng ta kiểm tra xem điểm cấu hình SSL tại địa chỉ https://www.ssllabs.com/ssltest/analyze.html?d=yourdomain.com, chú ý thay yourdomain.com thành tên miền của bạn. Thông thường nếu không cấu hình thêm, bạn sẽ chỉ được điểm chất lượng B khi đánh giá tại đây.

Điểm chất lượng cấu hình khi chưa fix Key Exchange

Điểm B do các tham số Diffie-Helman key exchange được thiết lập yếu, chúng ta sẽ tạo lại mật mã Diffie-Helman vào thư mục /etc/nginx/ssl/ bằng câu lệnh:

# mkdir /etc/nginx/ssl # cd /etc/nginx/ssl # openssl dhparam -out dhparams.pem 4096 Generating DH parameters, 4096 bit long safe prime, generator 2 This is going to take a long time ......+................................+...+.................................................................................. ... .............................................................++*++*
Code language: PHP (php)

Chú ý: lệnh tạo lại DH sẽ mất khá lâu, trên máy chủ của allaravel.com mất hơn 20 phút, bạn làm tách cafe rồi vào làm tiếp là vừa. Cấu hình lại Nginx server block để nhận mật mã DH mới:

server { listen 443 default_server; # SSL configuration ssl on; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; # Diffie-Helman setup ssl_dhparam /etc/nginx/ssl/dhparams.pem; ssl_session_timeout 30m; ssl_session_cache shared:SSL:10m; ssl_buffer_size 8k; add_header Strict-Transport-Security max-age=31536000; }
Code language: PHP (php)

Lưu file, kiểm tra lại cấu hình nginx và khởi động lại nginx:

# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # systemctl restart nginx
Code language: PHP (php)

Ok, giờ vào lại https://www.ssllabs.com/ssltest/analyze.html?d=yourdomain.com, click vào Clear cache và thực hiện kiểm tra lại điểm SSL.

Điểm chất lượng SSL sau khi tạo lại mã Diffie Hellman key exchange

Bước 5: Cấu hình tự động gia hạn chứng chỉ SSL Let’s Encrypt khi hết hạn

Đến bước 4 coi như chúng ta đã hoàn thành việc cài đặt chứng chỉ SSL miễn phí của Let’s Encrypt cho webserver Nginx, tuy nhiên mỗi chứng chỉ SSL này chỉ có thời hạn trong 90 ngày, hết thời gian đó bạn phải gia hạn lại chứng chỉ. Việc gia hạn có thể làm thủ công bằng câu lệnh trước khi đến thời điểm hết hạn bằng plugin webroot, sau đó thực hiện khởi động lại Nginx:

# ./letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --webroot-path=/usr/share/nginx/html/ -d yourdomain.tld -d www.yourdomain.tld # systemctl restart nginx
Code language: PHP (php)

Chú ý thay webroot-path bằng thư mục gốc của webserver document. Để gia hạn một cách tự động, tạo một file bash tên cert-renew trong thư mục /usr/local/bin với nội dung:

#!/bin/bash webpath='/usr/share/nginx/html/' domain=$1 le_path='/opt/letsencrypt' le_conf='/etc/letsencrypt' exp_limit=30; get_domain_list(){ certdomain=$1 config_file="$le_conf/renewal/$certdomain.conf" if [ ! -f $config_file ] ; then echo "[ERROR] The config file for the certificate $certdomain was not found." exit 1; fi domains=$(grep --only-matching --perl-regex "(?<=domains \= ).*" "${config_file}") last_char=$(echo "${domains}" | awk '{print substr($0,length,1)}') if [ "${last_char}" = "," ]; then domains=$(echo "${domains}" |awk '{print substr($0, 1, length-1)}') fi echo $domains; } if [ -z "$domain" ] ; then echo "[ERROR] you must provide the domain name for the certificate renewal." exit 1; fi cert_file="/etc/letsencrypt/live/$domain/fullchain.pem" if [ ! -f $cert_file ]; then echo "[ERROR] certificate file not found for domain $domain." exit 1; fi exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s) datenow=$(date -d "now" +%s) days_exp=$(echo \( $exp - $datenow \) / 86400 |bc) echo "Checking expiration date for $domain..." if [ "$days_exp" -gt "$exp_limit" ] ; then echo "The certificate is up to date, no need for renewal ($days_exp days left)." exit 0; else echo "The certificate for $domain is about to expire soon. Starting renewal request..." domain_list=$( get_domain_list $domain ) "$le_path"/letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --webroot-path=”$webpath” --domains "${domain_list}" echo "Reloading Nginx..." sudo systemctl reload nginx echo "Renewal process finished for domain $domain" exit 0; fi
Code language: PHP (php)

Chú ý, như ở trên thay biến $webpath ở đầu script thành thư mục gốc Nginx document. Để chắc chắn script có thể chạy được, cài đặt thêm gói bc:

# chmod +x /usr/local/bin/cert-renew # yum install bc
Code language: PHP (php)

Kiểm tra script chạy tốt không bằng lệnh

# /usr/local/bin/cert-renew yourdomain.com
Code language: PHP (php)

Cuối cùng là tạo một lịch chạy tự động script này hàng tuần trong 30 ngày trước khi hết hạn.

# crontab -e
Code language: PHP (php)

và thêm dòng lệnh sau vào dòng cuối cùng:

@weekly /usr/local/bin/cert-renew yourdomain.com >> /var/log/yourdomain.com-renew.log 2>&1
Code language: JavaScript (javascript)

Ok, vậy là đã hoàn tất các bước.

Lời kết

Chứng chỉ SSL miễn phí của Let’s encrypt là giải pháp tuyệt vời với các website hạn chế về nguồn tài chính, tuy nhiều việc phải thực hiện vì chỉ được cấp phép trong 90 ngày mỗi lần nhưng không quá phức tạp. Nếu bạn có tài chính rủng rỉnh hơn, bạn cũng nên tặng thưởng cho Let’s Encrypt một chút, dù chỉ là một tách cafe để động viên tinh thần cho một cộng đồng chia sẻ.

Nếu tài chính rủng rỉnh hơn nhiều, bạn nên tham khảo và mua các chứng chỉ SSL tại các nhà cung cấp tên tuổi bởi mức bảo hiểm rủi ro của các gói này khá lớn và cũng vì thế khách hàng tin tưởng website của bạn hơn.

Các bạn có thể tham khảo các bài viết hay về Laravel tại đây.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

Nguồn tham khảo: allravel

Leave a Reply

Your email address will not be published. Required fields are marked *