Last Updated on 2024-08-04 by Clay
htpasswd 是一個用於 Apache 和 Nginx 等網頁伺服器的工具,可以用來生成、管理使用者名稱與密碼的文件,以實現在 Nginx 做反向代理服務時進行基本的身份驗證。
不過需要強調的是,htpasswd 與 Nginx 的驗證機制雖然實作簡單,但卻是適合僅需要基本保護的應用場景,如內部工具或不涉及敏感數據的小型應用。根據其落地應用的領域與其需求的隱私管理,實際上可能需要更複雜的驗證系統來提高安全性。
以下是一個詳細的教學,說明如何在 Nginx 中使用 htpasswd 進行基本身份驗證。關於 Nginx 的架設方式,可以參考我之前的文章:[Linux] 使用 Nginx 在單一端口上做反向代理、轉發不同端口的服務請求
架設簡單的 Python API 服務
Python API 服務
為了能夠測試 htpasswd 驗證機制,我們快速使用 Python 的 fastapi 和 uvicorn 套件起兩個簡單的小服務。
pip install fastapi uvicorn
接著
from fastapi import FastAPI
import uvicorn
import argparse
def create_app(api_name: str, port: str) -> FastAPI:
app = FastAPI()
@app.get(f"/api/{api_name}")
async def read_root():
return {"message": f"Hi, I am the endpoint /api/{api_name} on port {port}"}
return app
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="FastAPI server")
parser.add_argument("--port", type=int, default=8000, help="Port to run the server on")
parser.add_argument("--api-name", type=str, required=True, help="API name to be used in the endpoint")
args = parser.parse_args()
app = create_app(
api_name=args.api_name,
port=args.port,
)
uvicorn.run(app, host="0.0.0.0", port=args.port)
接著我們起兩個不同端口跟 API 名稱的服務:
python3 fastapi_service.py --api-name service1 --port 8001
python3 fastapi_service.py --api-name service2 --port 8002
架設帶有 htpasswd 驗證機制的 Nginx 反向代理服務
Step 1. Nginx 安裝
首先,我們安裝 Nginx:
sudo apt update
sudo apt install nginx
Step 2. htpasswd 安裝
sudo apt update
sudo apt install apache2-utils
對於 CentOS 或 RHEL 系統,可以使用以下命令:
sudo yum install httpd-tools
Step 3. 生成 htpasswd 設定檔
接下來我們就可以使用 htpasswd
指令來建立一個全新的 .htpasswd 密碼文件並新增使用者。
sudo htpasswd -c /etc/nginx/.htpasswd <USER_NAME>
執行後,系統會提示輸入、並二次確認新增使用者的密碼。
如果需要添加更多用戶,可以使用以下命令:
sudo htpasswd /etc/nginx/.htpasswd <USER_NAME>
需要注意的是之後若要新增使用者指令不要帶上 -c
參數,否則會覆蓋掉之前創建的 .htpasswd
文件。
Step 4. 配置 Nginx 的 .conf 設定,並重新啟動 Nginx
首先編輯 Nginx 的設定檔 /etc/nginx/conf.d/default.conf
:
sudo vim /etc/nginx/conf.d/default.conf
配置轉發的 location 邏輯、.htpasswd 檔案位置以及需要驗證的服務:
upstream service1 {
server 192.168.212.152:8001;
}
upstream service2 {
server 192.168.212.152:8002;
}
server {
listen 443;
location /api/service1 {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://service1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/service2 {
proxy_pass http://service2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
在這裡,我只有配置端口 8001 的 /api/service1 的服務需要驗證,另一個則不需要。
接著我們驗證 Nginx 服務的配置沒有問題後,就重新啟動 Nginx 服務好讓設定生效。
sudo nginx -t
sudo systemctl restart nginx
最終結果,會看到在 /api/service2
的服務不需要驗證:
但是 /api/service1
的服務是需要輸入帳號和密碼的:
以上,就是一個簡易的使用 htpasswd 搭配 Nginx 建立一個簡單的驗證機制筆記。
References
- Apache HTTP Server - htpasswd - Manage user files for basic authentication
- Restricting Access with HTTP Basic Authentication - Nginx