Chuyển noip qua dùng cloudflare truy cập về máy ở nhà

Mạng ở nhà đa số sử dụng IP động, do đó tên miền cần phải được tự động cập nhật mỗi khi Public IP thay đổi để tránh kết nối bị lỗi. Chỉ cần dùng 1 bash script chạy trên linux để tự động cập nhật IP động cho tên miền qua dịch vụ CloudFlare. Nhờ vậy tên miền luôn được trỏ đến IP mới nhất được cấp cho modem mạng ở nhà. Như thế chỉ cần mua tên miền, tài khoản cloudflare miển phí không cần phải gia hạn hằng tháng noip (không thì tốn 24$).

Trước khi tạo script cần phải có 1 số thông tin

  • auth_token: Cloudflare API Token
  • zone_identifier: Zone ID
  • record_name: Tên miền

Tạo Cloudflare API Token

Truy cập vào trang Cloudflare API Token để tạo Token mới

Bấm vào Create Token
Chọn Use Template ở mục Edit Zone DNS
Kéo xuống mục Zone Resources, chọn tên miền bạn muốn sử dụng để cập nhật IP sau đó bấm Continue to Summary
Bấm Create Token
Token đã tạo xong

Bạn cần lưu lại Token vừa mới tạo để lưu vào script đã tạo. Token này sẽ không hiện ra lại trên Cloudflare vì lý do bảo mật. Nếu bạn quên lưu, cần phải xoá Token và tạo lại cái mới.

Tìm thông tin Zone ID

Từ trang chủ Cloudflare, bạn bấm vào tên miền muốn sử dụng để cập nhật IP. Sau đó kéo xuống dưới sẽ thấy mục Zone ID. Lưu lại thông số này để điền vào script

Lưu lại thông tin Zone ID

Tạo A Record cho tên miền

Ví dụ mình muốn sử dụng tên miền alibaba.thuanbui.me để truy cập đến homelab ở nhà. Bấm vào Add record và tạo một A record mới.

  • Name: điền vào alibaba
  • IPv4: điền tạm 1.1.1.1, thông số này sẽ được tự động cập nhật về IP của modem sau khi chạy script.
Tạo A Record cho subdomain alibaba.thuanbui.me

Tạo script

cd ~

mkdir cloudflare

cd cloudflare

nano cloudflare.sh

Nội dung https://thuanbui.me/cap-nhat-ip-dong-cho-ten-mien-qua-cloudflare-de-truy-cap-homelab-tai-nha/:

#!/bin/bash

# Forked from benkulbertis/cloudflare-update-record.sh

# CHANGE THESE

# API Token (Recommended) #####

auth_token=“LrAB–xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”

# Domain and DNS record for synchronization zone_identifier=“48bxxxxxxxxxxxxxxxxxxxx60”

# Can be found in the “Overview” tab of your domain record_name=“alibaba.thuanbui.me” # Which record you want to be synced

# DO NOT CHANGE LINES BELOW # SCRIPT START

echo -e “Check Initiated”

# Check for current external network IP

ip=$(curl -s4 https://icanhazip.com/)

if [[ ! -z ${ip} ]]; then echo -e ” > Fetched current external network IP: ${ip}

else >&2 echo -e “Network error, cannot fetch external network IP.”

fi

# The execution of update

if [[ ! -z ${auth_token} ]]; then header_auth_paramheader=( -H ‘”Authorization: Bearer ‘${auth_token}‘”‘ ) else header_auth_paramheader=( -H ‘”X-Auth-Email: ‘${auth_email}‘”‘ -H ‘”X-Auth-Key: ‘${auth_key}‘”‘ ) fi

# Seek for the record

seek_current_dns_value_cmd=( curl -s -X GET ‘”https://api.cloudflare.com/client/v4/zones/’${zone_identifier}‘/dns_records?name=’${record_name}‘&type=A”‘ ${header_auth_paramheader[@]} -H ‘”Content-Type: application/json”‘ ) record=`eval ${seek_current_dns_value_cmd[@]}`

# Can’t do anything without the record

if [[ -z ${record} ]]; then >&2 echo -e “Network error, cannot fetch DNS record.” exit 1 elif [[ ${record} == *‘”count”:0’* ]]; then >&2 echo -e “Record does not exist, perhaps create one first?” exit 1 fi # Set the record identifier from result record_identifier=`echo “${record}” | sed ‘s/.*”id”:”//;s/”.*//’`

# Set existing IP address from the fetched record

old_ip=`echo “${record}” | sed ‘s/.*”content”:”//;s/”.*//’` echo -e ” > Fetched current DNS record value : ${old_ip}

# Compare if they’re the same

if [ ${ip} == ${old_ip} ]; then echo -e “Update for A record ‘${record_name} (${record_identifier})’ cancelled.\n Reason: IP has not changed.” exit 0 else echo -e ” > Different IP addresses detected, synchronizing…” fi # The secret sause for executing the update json_data_v4=“‘”{“id”:“‘${zone_identifier}‘”,“type”:“A”,“proxied”:true,“name”:“‘${record_name}‘”,“content”:“‘${ip}‘”,“ttl”:120}‘”‘update_cmd=( curl -s -X PUT ‘”https://api.cloudflare.com/client/v4/zones/’${zone_identifier}‘/dns_records/’${record_identifier}‘”‘ ${header_auth_paramheader[@]} -H ‘”Content-Type: application/json”‘ )

# Execution result

update=`eval ${update_cmd[@]} –data $json_data_v4`

# The moment of truth

case $update in *‘”success”:true’*) echo -e “Update for A record ‘${record_name} (${record_identifier})’ succeeded.\n – Old value: ${old_ip}\n + New value: ${ip};; *) >&2 echo -e “Update for A record ‘${record_name} (${record_identifier})’ failed.\nDUMPING RESULTS:\n${update} exit 1;;

esac

Mặc định, script này sẽ kích hoạt chế độ proxy trên Cloudflare nhằm mục đích ẩn IP của modem, giảm nguy cơ bị tấn công vào mạng nhà. Nếu vì lý do nào đó không muốn ẩn IP của mình thì có thể thay đổi thông số "proxied":true thành "proxied":false

Thiết lập quyền thực thi cho file cloudflare.sh

chmod +X cloudflare.sh
Chạy thử xem nào: ./cloudflare.sh

Quay lại Cloudflare, tên miền alibaba.thuanbui.me, mình thấy đã được tự động cập nhật với IP mới. Ngon lành!

Thiết lập chạy tự động

Việc thiết lập cron để script tự động hay rc.local có vẽ không được khi máy chưa có vô mạng, nên một dịch vụ  riêng để chạy với systemd. Với một dịch vụ systemd làm cho service hợp lệ và hoạt động sau khi có mạng.
Bây giờ bạn đã tạo file service: sudo nano /etc/systemd/system/cloudflare.service

[Unit]
Description=Update ip to dns cloudflare service.
After=network.target

[Service]
Type=oneshot
User=root
ExecStart= /bin/bash /home/user/cloudflare/cloudflare.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

Kích hoạt cho dịch vụ khởi động cùng hệ thống:

sudo systemctl enable cloudflare.service
sudo systemctl start cloudflare.service
sudo systemctl stop cloudflare.service

Lưu ý: After=network.target không chạy được do máy khởi động lên là systemd đã chạy nên gây ra lỗi phần này, nên thay bằng:

[Unit]
Wants=network.target network-online.target
After=network.target network-online.target

Mục tiêu network-online là nó không tồn tại trừ khi bạn đang sử dụng một phương pháp “modern” để nâng cấp mạng của mình, như NetworkManager hoặc systemd-networkd .

Nếu bạn không làm điều đó thì systemd sẽ tính ra rằng network-onlinekhông bao giờ có thể đạt được mục tiêu và bỏ qua nó dưới dạng tệp Want.

Tôi đang sử dụng ifupdown trên máy chủ vì nó vẫn thực hiện mọi thứ tôi cần. Để ifupdown hỗ trợ network-onlinemục tiêu trên Debian, bạn nên kích hoạt dịch vụ ifupdown-wait-online:
sudo systemctl kích hoạt ifupdown-wait-online.service
Điều này sẽ đưa vào network-onlinetrạng thái “đạt được mục tiêu” khi mọi giao diện được đánh dấu là “tự động” trong /etc/network/interfaces đều hoạt động.
Vi du nhu:

[Unit]
Description=ChatGPT assistant
Wants=network-online.target
After=network-online.target
After=multi-user.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStartPre=/bin/sh -c 'until ping -c1 google.com; do sleep 1; done;'
ExecStart=/usr/bin/python3 /home/pi/chat.py

[Install]
WantedBy=multi-user.target

Sau do cho systemd biet service moi:
sudo systemctl daemon-reload
Kiem tra xem chay : systemctl start chat.service

Thiết lập SSL miễn phí.

Đầu tiên bạn cần đảm bảo rằng website đã thêm vào CloudFlare và bật Proxy (đám mây màu vàng) thành công.

Tiếp đó, bạn truy cập vào SSL/TLS => Overview => chọn Flexible là hoàn tất và bạn không cần làm gì thêm.

chứng chỉ do chính CloudFlare cung cấp.

Bước 1: Chọn kiểu SSL

Bạn truy cập vào SSL/TLS => Overview => chọn Full hoặc Full (strict) .

Full SSL

Bước 2: Tạo chứng chỉ SSL

Bạn truy cập vào SSL/TLS => Origin Server => Create Certificate

Create Certificate

Chọn Generate private key and CSR with Cloudflare , rồi nhấn Create.

Create Certificate
Create Certificate

Lúc này CloudFlare sẽ cung cấp cho bạn 2 nội dung Origin Certificate và Private Key. Bạn tiến hành copy và lưu lại nội dung 2 File này (quan trọng), sau khi đã lưu xong bạn chọn OK.

Origin Certificate và Private Key

Copy nội dung vào 2 file cert.pem và privatekey.key

  1. sudo nano /home/user/ssl/cert.pem
  2. sudo nano /home/user/ssl/privatekey.key
  3. sudo chmod -R 755 /home/user/ssl

Tiếp đó bạn cần chờ vài phút để CloudFlare duyệt chứng chỉ. Nếu hiển thị như hình bên dưới là chứng chỉ đã được cấp phát và có thể sử dụng.

Certificate

 

Bước 3: Cài đặt chứng chỉ lên máy chủ.

Thiết lập nội dung vô tên miền
sudo nano /etc/nginx/sites-available/your_domain

Nội dung https://www.digitalocean.com/community/tutorials/how-to-host-a-website-using-cloudflare-and-nginx-on-ubuntu-22-04:

server {
listen 80;
listen [::]:80;
server_name your_domain;
return 302 https://$server_name$request_uri;
}

server {

# SSL configuration

listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /home/user/ssl/cert.pem;
ssl_certificate_key /home/user/ssl/privatekey.key;

server_name your_domain;

root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;

location / {
try_files $uri $uri/ =404;
}
}

sudo nginx -t

Không có báo lỗi thì bắt đầu cho chạy:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
sudo systemctl restart nginx

Lưu ý proxied":true bật Proxy (đám mây màu vàng)

SSL cho noip hơi tốn tiền

RapidSSL Basic DV tốn $20, không thì mua No-IP Vital Encrypt DV giảm còn $8.

Tạo CSR thông tin tên miền.

Sử dụng  Trình hướng dẫn DigiCert OpenSSL CSR  để tạo lệnh OpenSSL nhằm tạo Nginx CSR của bạn. Chỉ cần điền vào biểu mẫu, nhấp vào Tạo rồi dán lệnh OpenSSL tùy chỉnh vào thiết bị đầu cuối của bạn.

Hoặc dùng công cụ Csrgenerator.Com để bắt đầu tạo.

chrome IAZIA4IdIl

LƯU Ý: Sau khi tạo CSR sẽ có PRIVATE KEY đây là khóa đi kèm nên bạn phải lưu giữ không được làm mất. Vì khi mất KEY bạn sẽ không import được chứng chỉ CRT (Certificate) vào server/hosting được mà phải làm lại từ đầu. Sau khi có thông tin CSR, bạn có thể bắt đầu các thao tác chứng thực chứng chỉ SSL. File này có thể dùng cho lần tạo chứng thực sau này hết hạn.

Cách 2 dùng câu lệnh openssl req –new –newkey rsa:2048 –nodes –keyout domain.key –out domain.csr

  1. Tiến trình bắt đầu quá trình tạo hai tệp sau:
    • Tệp khóa riêng : Được sử dụng để tạo CSR trở lên để bảo mật và xác minh các kết nối bằng chứng chỉ.
    • Tệp Yêu cầu ký chứng chỉ (CSR) : Được sử dụng để đặt hàng chứng chỉ SSL của bạn và sau đó để mã hóa các tin nhắn mà chỉ khóa riêng tương ứng của nó mới có thể giải mã.
  2. Khi được nhắc về  Common Name  (tên miền), hãy nhập tên miền đủ điều kiện (FQDN) cho trang web mà bạn sắp bảo mật.

    Lưu ý: Nếu bạn đang tạo Nginx CSR cho chứng chỉ Wildcard , hãy đảm bảo tên chung của bạn bắt đầu bằng dấu hoa thị (ví dụ: *.example.com ).

  3. Khi được nhắc, hãy nhập thông tin tổ chức của bạn, bắt đầu bằng thông tin địa lý của bạn.

    Lưu ý: Có thể bạn đã thiết lập thông tin mặc định.

  4. Bây giờ, tệp .csr của bạn sẽ được tạo.

Nạp CSR vào download CRT.

  1. Bạn cần ghép tệp chứng chỉ chính (your_domain_name.crt) và tệp chứng chỉ trung gian (DigiCertCA.crt) thành một tệp .pem.
  2. Để nối các tập tin, hãy chạy lệnh sau:
    cat your_domain_name.crt DigiCertCA.crt >> bundle.crt
  3. add the lines in bold below:

server {

listen   443;

ssl    on;
ssl_certificate    /etc/ssl/bundle.crt
ssl_certificate_key    /etc/ssl/your_domain_name.key;

server_name your.domain.com;
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
location / {
root   /home/www/public_html/your.domain.com/public/;
index  index.html;
}
}

Chạy lệnh sau để khởi động lại Nginx: sudo /etc/init.d/nginx restart

Mở trình duyệt web và truy cập trang web của bạn bằng https. Trình duyệt sẽ đưa ra cảnh báo nếu chứng chỉ trung gian của bạn chưa được cài đặt. Bạn sẽ không nhận được bất kỳ cảnh báo hoặc lỗi nào của trình duyệt.

    1. Nếu bạn ngay lập tức nhận được thông báo trình duyệt về việc trang web không khả dụng thì Nginx có thể chưa được nghe trên cổng 443.
    2. Nếu yêu cầu web của bạn mất nhiều thời gian và hết thời gian, tường lửa có thể đang chặn lưu lượng truy cập trên cổng TCP 443 tới máy chủ web.
    3. Nếu bạn nhận được cảnh báo “không đáng tin cậy”, hãy xem chứng chỉ để xem đó có phải là chứng chỉ bạn mong đợi hay không.
      • Khi bạn xem chứng chỉ, hãy kiểm tra các trường Chủ đề , Nhà phát hành và Hợp lệ cho
      • Nếu bạn phải nối các tệp chứng chỉ thì chứng chỉ chính của bạn (ví dụ: your_domain_name.crt ) có thể không được kết hợp chính xác với chứng chỉ trung gian.

Để biết thêm thông tin, hãy xem tài liệu Nginx SSL .

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *