本文章为原创非复制行为
前言
nginx可以开启目录浏览做文件服务器,但有时不想让所有人都能访问占用服务器资源,或者对某个子目录做一个私人的文件分享,可以加上一个简单的认证basic auth,使用简单适合安全性要求不高的地方。这种认证在旧路由器固件上能经常见到,因为在局域网传输数据无伤大雅,但在公网非常不安全,basic auth会以明文的方式传输账号和密码,长久以来多次暴露密码添加认证也就无意义了,所以必须要为文件服务器配置ssl,配置ssl还可以避免传输的文件或浏览的内容被攻击者知晓。
先说一说basic auth一些比较明显的缺点
- 虽然账号和密码经过base64转换,实际上还是明文传输
- 本身不能防止暴力破解,需要配合fail2ban等工具
- 不能控制用户注销
配置完成用浏览器访问就会弹出这样的认证窗口
- chrome浏览器不会显示"Server require user and password"的内容
配置
本文章的目录结构
配置账户密码,生成密码文件
获取htpasswd工具,centos安装httpd-tools,debain系安装apache2-utils
[root@ykxz ~]# yum install -y httpd-tools
[root@ykxz ~]# apt-get install -y apache2-utils
官方给出的用法参考:
htpasswd [-cimBdpsDv] [-C cost] passwordfile username
htpasswd -b[cmBdpsDv] [-C cost] passwordfile username passwordhtpasswd -n[imBdps] [-C cost] username
htpasswd -nb[mBdps] [-C cost] username password
这里将basic auth认证文件放在nginx.conf同级目录cert下,密码使用bcrypt加密(-B参数),将账号和密码保存到yourhtpasswd文件。不建议账号设置为Admin,网络攻击常以Admin账号试图登入
- 新建用户ykxz
[root@ykxz ~]# htpasswd -Bbc /etc/nginx/cert/yourhtpasswd ykxz 123456
- 添加用户ykxz2
[root@ykxz ~]# htpasswd -Bb /etc/nginx/cert/yourhtpasswd ykxz2 123456
- 删除用户ykxz2
[root@ykxz ~]# htpasswd -D /etc/nginx/cert/yourhtpasswd ykxz2
给需要的目录添加basic auth认证,在配置文件的location中添加
auth_basic "Server require user and password";
auth_basic_user_file cert/yourhtpasswd;
配置ssl
这里使用了已经购买的域名证书,也可以在Let's Encrypt申请免费的ssl证书(需要三个月更新一次证书),没有购买域名自签ipssl证书也是可以的。
这里将ssl证书文件.pem、.key放在了nginx.conf同级目录cert下,在listen一行将“ssl”添加在端口7000后启用ssl,此时的设置不允许http访问
listen 7000 ssl;
如果使用http访问则返回400错误
并进行一些ssl设置
ssl_certificate cert/123456_your.domain.com.pem;
ssl_certificate_key cert/123456_your.domain.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
这是我的配置文件参考,为顶层目录添加了认证,可直接复制,必须修改的地方为
listen 7000 ssl; nginx监听的端口
server_name your.domain.com; 修改为你的域名
alias file_server/; 文件服务器顶层目录,/不可以删除
# vim: ft=conf
server {
listen 7000 ssl;
server_name your.domain.com;
ssl_certificate cert/123456_your.domain.com.pem;
ssl_certificate_key cert/123456_your.domain.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
charset utf-8;
location / {
auth_basic "Server require user and password";
auth_basic_user_file auth/testpasswd;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
alias fileServer/;
}
error_log logs/error_your.domain.com:7000.log error;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
为多个目录添加认证
如果不仅认证顶层目录还要认证子目录,并采用不同的账户密码,可以采用以下配置
location ^~ /subdirectory/ {
auth_basic "Subdirectory require user and password";
auth_basic_user_file cert/yourhtpasswd2;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
alias file_server/subdirectory/;
}
因为auth_basic不能写在if里面通过判断请求路径添加认证,所以要在server里面添加一个location,当请求的uri匹配到这个location则认证及开启目录浏览