MKTalkway
首页
注册

使用Openssl生成Basic Auth密码文件为Nginx添加用户认证

MiKing233
好吃懶做
2021-11-23 13:58:43

Nginx支持Basic Auth身份认证,当启用此功能时,浏览器会弹出窗口要求用户输入用户名和密码,输入正确才允许访问网页。

想要實現這樣的功能首先我們需要新建一個文本文檔,將其命名爲user.txt,輸入以下内容

user1:passwd123:這裏是注釋
user2:passwdabc:也可以像下面不添加注釋
user3:passwd@#$

每行為一條用戶信息,每條用戶信息被分爲三段,用戶名:密碼:注釋,其中注釋可以省略,每段閒以冒號分隔 (不要在用戶名,密碼,注釋中包含冒號)


接下來使用下面的命令將密碼段進行hash運算生成一個名爲passwd.txt的密碼文件

cut -d ":" -f 2 user.txt | openssl passwd -6 -stdin | paste -d ":" user.txt - | tr -d '\r' | awk 'BEGIN{FS=":";OFS=":"}{if (NF==4) print $1,$4,$3; else if (NF==3) print $1,$3}' > passwd.txt

以上命令组合了cutopensslpastetrawk5个命令,作用简单说明如下:

  • cut : 取出user.txt的第二个字段(密码明文),将结果输出到stdout;

  • openssl : 将stdin中输入的数据(3条密码明文)使用SHA512形式进行hash,输出到stdout;

  • paste : 将user.txt中的原始内容与hash过的密码组合起来,输出到stdout;

  • tr : 去除可能出现的 \r 符号;

  • awk : 从stdin中提取出用户名、hash过的密码、注释字段,将结果输出到passwd.txt。

例如要将字符串abc进行hash运算,使用的命令及输出的结果如下:

Command#openssl passwd 123456
>iZi0eRBKGI0VQ

注意由于在hash运算时自动加入了随机的salt,因此相同的字符串每次进行hash时,产生的结果都是不一样的。


執行後生成的passwd.txt内容如下

user1:$6$fckDq6LmxWi.iUs1$G0C8qhjuIV1tYrzEaz0/3uwqIdASjZG5HnXtBk8NuHyZ/FO8oEUr8DWIXiuxD4Ef2/4C9k3G2COdYLqgL5Ap/1:這裏是注釋
user2:$6$1eoBNTVHEksXbRrh$wRbCtmfhAFbkJPKKUK2jKa.5LUPdNPOggXmlewY2OzUx6Do7SSVqnc0xfFTw.ETJNvscPrqat8FkOzMGJILFT0:也可以像下面不添加注釋
user3:$6$IajTZutwmhQ.dR.Z$ZEu4reXCwAr3Rzl3PzQpxdxvcoZpCA5RPOcocx8uRHbPhTmupza27W5OA75KkAnqvVPfQlHDkBBps3ZrKEGPb1

可以看到和user.txt相比,其密碼字段已被hash運算加密,不再以明文保存


接下来编辑Nginx的配置文件,在location部分增加两个命令:

auth_basic "Please login";
auth_basic_user_file /home/etc/passwd.txt;

auth_basic 指令开启Nginx的Basic Auth认证功能,并设置了一个字符串,该字符串可能会显示在浏览器的密码输入提示窗口中(根据浏览器的不同,有些会显示,有些不会显示),你可以在HTTP Response header中的WWW-Authenticate字段看到这个字符串。

auth_basic_user_file 指令设置了密码文件的路径。


下面是兩個完整的例子:

server { #這是一個使用Basic Auth的例子1
    listen 8080;
    server_name  localhost;
    location / {
        proxy_pass http://myserver;
    }

location /login {
    proxy_pass http://myserver;
    auth_basic "Please login";
    auth_basic_user_file /path/to/passwd.txt;
    }
}


server{ #這是一個使用Basic Auth的例子2
  listen 443 ssl;
  server_name test.mknetwork.net;
  ssl_certificate mknetwork.net.Origin.pem;
  ssl_certificate_key mknetwork.net.Origin.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  ssl_prefer_server_ciphers on;
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_redirect off;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    auth_basic "Please login";
    auth_basic_user_file /home/nginx/user.txt;
  }
}


修改完成後保存配置文件並重載配置后,打開對應網頁就可以看到要求輸入用戶名和密碼的提示框了。

虽然以上很大篇幅提到了对密码文件进行hash,但是在Basic Auth认证方式中,客户端(浏览器) 发送到服务器的用户名和密码仍然是明文的,因此在生产环境最好为网站开启SSL/TLS加密。


以上内容參考自:https://mengqi.info/html/2019/201901160829-openssl-passwd.html