2025年7月15日 星期二

Mapleboard MP510-50 測試 (二十九) : 禁止使用 IP 訪問網站

上週在我追蹤的臉書專頁 "黑暗執行緒" 看到關於 Nginx 網站封鎖 IP 存取的文章 : 


作者的完整內容如下 : 


作者主要是著墨在想隱藏域名不想公開, 但我的域名 tony1966.cc 是公開的, 並沒有要隱藏. 事實上想要完全隱藏域名是不可能的, 網路上有公開的資料庫可以查詢域名, 只要知道域名就能用網路指令 (例如 dig) 反查主機的 IP. 我在意的是作者提到 Nginx 預設站台 default 預設是允許使用 IP 直接訪問網站的, 這管道潛藏著資安隱憂必須封鎖. 

我詢問 AI 允許使用主機 IP 直接訪問網站會有甚麼風險呢? 摘要說明如下 : 
  • 會暴露不必要的服務或資訊 :
    若 Nginx 網站設定檔中有 default_server 或 server_name _ 的 server 區塊, 訪問 IP 地址可能會回應某個網站的內容 (例如 Nginx 的預設頁面), 這通常不是應該給瀏覽者看到的. 
  • 會繞過域名相關的安全策略 : 
    允許用 IP 存取會繞過 SSL/TLS 憑證檢查 (因為憑證綁定域名而非 IP), 導致客戶端顯示 "不安全網站" 的警告, 影響用戶信任感, 
  • 增加駭客攻擊面 :
    攻擊者可能通過 IP 網址掃描伺服器來偵測未正確配置的站台或未預期的服務 (例如開發中的 Flask 應用程式) 來探查安全漏洞. 
  • 增加伺服器負載 :
    Nginx 的 default_server 可能回應所有未匹配的請求導致伺服器承受不必要的負載. 
我使用 IP 直接訪問網站確實會顯示網頁, 訪問根目錄顯示 Nginx 伺服器預設網頁 : 




訪問前兩篇的獨立站台 hello 與 hello2 也可顯示網頁 :




因此若駭客掃描到開發中的 Flask app 站台也會顯示開發中的結果, 這應該加以禁止, 本篇旨在紀錄如何封鎖這種直接用 IP 訪問網站的管道. 

本系列全部的測試紀錄參考 :


我在前兩篇測試中使用獨立站台 hello 來執行 Flasp app 時就已經為了避免域名衝突而刪除 /etc/nginx/sites-enabled/ 下的預設站台 defaut 符號鏈結 (分身/捷徑), 只剩下 /etc/nginx/sites-enabled/ 下的 default 本尊, 所以預設站台 default 其實未啟用 :

tony1966@LX2438:~$ ls -ls /etc/nginx/sites-available/   
總用量 16
8 -rw-r--r-- 1 root root 4492 Jul  5 13:11 default
4 -rw-r--r-- 1 root root 1201 Jul 15 14:24 flask.tony1966.cc
4 -rw-r--r-- 1 root root 1311 Jul 14 16:35 hello
tony1966@LX2438:~$ ls -ls /etc/nginx/sites-enabled/   
總用量 0
0 lrwxrwxrwx 1 root root 44 Jul 15 14:09 flask.tony1966.cc -> /etc/nginx/sites-available/flask.tony1966.cc
0 lrwxrwxrwx 1 root root 32 Jul  7 15:23 hello -> /etc/nginx/sites-available/hello

可見真正有啟用的站台只有 hello 與 flask.tony1966.cc 而已.  

但為了保險起見, 還是用下列指令過濾一下 :  

grep -r "default_server" /etc/nginx/sites-available/
grep -r "server_name _" /etc/nginx/sites-available/

tony1966@LX2438:~$ grep -r "default_server" /etc/nginx/sites-available/   
/etc/nginx/sites-available/default: listen 80 default_server;
/etc/nginx/sites-available/default: listen [::]:80 default_server;
/etc/nginx/sites-available/default: # listen 443 ssl default_server;
/etc/nginx/sites-available/default: # listen [::]:443 ssl default_server;
/etc/nginx/sites-available/default: # listen 443 ssl default_server;
/etc/nginx/sites-available/default: # listen [::]:443 ssl default_server;
tony1966@LX2438:~$ grep -r "server_name _" /etc/nginx/sites-available/   
/etc/nginx/sites-available/default: server_name _;

可見只存在於未啟用的 default 站台而已. 

那要如何封鎖以 IP 訪問網站伺服器呢? 勪決辦法就是建立一個拒絕 IP 存取的 default server 站台, 用 nano 在 /etc/nginx/sites-available/ 下建立一個 reject_ip 站台設定檔 : 

tony1966@LX2438:~$ sudo nano /etc/nginx/sites-available/reject_ip    
[sudo] tony1966 的密碼:

輸入如下內容 : 

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    return 444;  # Nginx 特殊狀態碼,立即斷線
}

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    server_name _;

    ssl_certificate /etc/letsencrypt/live/tony1966.cc/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tony1966.cc/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    return 444;
}

此處 server_name _ 是 Nginx 用來匹配所有未被明確指定的 Host (例如 IP 位址) 的寫法; return 444 表示 Nginx 不回應內容, 也不發出封包, 而是直接斷開連線. 

按 Ctrl+O 存檔後按 Ctrl+X 跳出 nano, 然後建立符號鏈結以啟用此 reject_ip 站台 :

tony1966@LX2438:~$ sudo ln -s /etc/nginx/sites-available/reject_ip /etc/nginx/sites-enabled/   

檢視已啟用站台 : 

tony1966@LX2438:~$ ls -ls /etc/nginx/sites-enabled/   
總用量 0
0 lrwxrwxrwx 1 root root 44 Jul 15 14:09 flask.tony1966.cc -> /etc/nginx/sites-available/flask.tony1966.cc
0 lrwxrwxrwx 1 root root 32 Jul  7 15:23 hello -> /etc/nginx/sites-available/hello
0 lrwxrwxrwx 1 root root 36 Jul 15 23:23 reject_ip -> /etc/nginx/sites-available/reject_ip

檢查站台設定檔是否正確 : 

tony1966@LX2438:~$ sudo nginx -t   
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

全部正確無誤就重新載入 Nginx 伺服器 :

tony1966@LX2438:~$ sudo systemctl reload nginx   

這時用 IP 訪問網站就無法顯示網頁了 : 






因為 return 444 就是不回應, 所以網頁顯示 "未傳送資料". 

使用域名訪問網站則可正常存取 :


沒有留言 :