Skip to content

[Linux] 使用 htpasswd 設定 Nginx 驗證機制

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


Read More

Tags:

Leave a Reply