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

Nội dung

    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 trangCloudflare 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ềnalibaba.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àoalibaba
    • IPv4: điền tạm1.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":truethà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ềnalibaba.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-online.target
    
    [Service]
    Type=oneshot
    User=root
    ExecStart= /bin/bash /home/user/cloudflare/cloudflare.sh
    RemainAfterExit=yes
    [Install]
    WantedBy=network-online.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êunetwork-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ưNetworkManagerhoặcsystemd-networkd.

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

    Tôi đang sử dụngifupdowntrên máy chủ vì nó vẫn thực hiện mọi thứ tôi cần. Đểifupdownhỗ 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àonetwork-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àoSSL/TLS=>Overview=> chọnFlexiblelà 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àoSSL/TLS=>Overview=> chọnFullhoặcFull(strict).

    Full SSL

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

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

    Create Certificate

    ChọnGenerate private key and CSR with Cloudflare, rồi nhấnCreate.

    Create Certificate
    Create Certificate

    Lúc này CloudFlare sẽ cung cấp cho bạn 2 nội dungOrigin CertificatePrivate 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ọnOK.

    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ụngTrì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àoTạorồ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.

     

    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.

    1 File key chỉ chứa: —–BEGIN PRIVATE KEY—– cho đến —–END PRIVATE KEY—–. Nạp vào ssl_certificate_key.

    Còn 1 file pem lấy từ No-IP Vital Encrypt DV thì Download Certificate chọn Chuỗi PEM (Khuyến nghị) Bao gồm tất cả các chứng chỉ cần thiết trong một tệp. Định dạng này bao gồm các chứng chỉ CA trung gian và được các máy chủ web phổ biến hỗ trợ để tích hợp dễ dàng nhất. Nó chứa toàn bộ 3 —–BEGIN CERTIFICATE—– —–END CERTIFICATE—–. File này nạp vào ssl_certificate

    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 chochứ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áctrường Chủ đề,Nhà phát hànhvà Hợplệ 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 xemtài liệu Nginx SSL.

    Để lại một bình luận

    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 *