【BUG记录】Nginx 出现 403:forbiden
我这里只记录一下我的情况。可能和大家的问题原因不对应。
BUG背景
我采用docker 部署Nginx,当我将html文件夹挂载到宿主机之后,访问nginx的默认页面的时候,出现了403:forbiden的情况。
查看日志文件
一般nginx的日志文件在/var/log/nginx文件夹下面,我这里docker部署nginx的时候挂载出来了,挂载到了宿主机的如下图示文件夹。
查看日志文件error.log文件,看到如下错误
2022/01/18 04:05:17 [error] 24#24: *1 directory index of “/usr/share/nginx/html/” is forbidden, client: x.x.x.x(我自己电脑的公网IP地址), server: localhost, request: “GET / HTTP/1.1”, host: “x.x.x.x:8080(这里是我容器宿主机的IP和端口号,8080是映射到nginx容器80的端口号)”
403 forbidden是什么意思?
403 Forbidden是HTTP协议中的一个状态码(Status Code)。可以简单的理解为没有权限访问此站。该状态表示服务器理解了本次请求但是拒绝执行该任务。(根据我的情况,我的是因为指定文件夹下面缺少html文件,但是这应该是404的范畴啊,这里我们暂时不管这个,可能是配置文件的原因)
default.conf(Nginx的server配置文件)
监听80端口,客户端访问容器的80端口,就可以访问到index.html文件
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
BUG探究
使用如下命令创建运行容器nginx
docker run -itd \
--name nginx \
-p 442:443\
-p 8080:80 \
-v /usr/local/nginx/html:/usr/share/nginx/html \
-v /usr/local/nginx/config/nginx.conf:/etc/nginx/nginx.conf \
-v /usr/local/nginx/config/conf.d/default.conf:/etc/nginx/conf.d/default.conf \
-v /usr/local/nginx/logs:/var/log/nginx \
-v /usr/local/nginx/ssl:/ssl \
nginx
html文件夹
容器里面的/usr/share/nginx/html文件夹我挂载到了宿主机的/usr/local/nginx/html
-v /usr/local/nginx/html:/usr/share/nginx/html
我在使用docker 将容器内部的/usr/share/nginx/html的文件夹挂载出去的时候,宿主机(也就是我服务器)的/usr/local/nginx/html对应文件夹是没有任何文件的。
所以说docker 挂载文件夹的时候,并不会把容器文件夹下的东西拷贝到我的宿主机对应的文件夹里面。
并且进入容器内部的时候,在这个/usr/share/nginx/html文件夹下面也找不到index.html文件,大概是因为这个时候这个文件夹已经挂载到了宿主机的/usr/local/nginx/html上面,访问这个文件夹就等于访问宿主机的/usr/local/nginx/html,所以缺少index.html文件,就是default.conf配置文件中index index.html index.htm这行指定的文件,访问的时候,找不到文件,就发生了403
日志文件
日志文件夹我也挂载了出去
-v /usr/local/nginx/logs:/var/log/nginx \
但是容器启动后,宿主机下面却多了两个日志文件。我想应该是docker调用nginx的脚本文件启动nginx服务的时候写入的。(所以容器启动时和启动后生成的文件是没有问题的,都是能够正常使用的)。
docker是怎么运行容器服务的
ssl文件夹
我挂载了一个ssl文件夹,但是这个文件夹在nginx镜像里面是肯定没有的
所以docker会帮我们去创建容器内部的/ssl文件夹
-v /usr/local/nginx/ssl:/ssl \
总结:
使用docker -v 挂载文件的时候,最好是把容器里面的文件都放到宿主机上面。容器服务启动的时候所生成的文件可以不用管他,他会自动生成到宿主机上面。
使用docker搭建服务,目前我想到的最好方法就是先生成一个比较简单的容器服务运行,然后将配置文件等拷贝到服务器准备做挂载的文件夹下面
比如像下面这样,先run一个简单的容器
docker run -itd --name nginx nginx
使用docker exec命令进入容器内部,查看里面有啥文件是需要挂载出来的
一般就是日志文件,配置文件这些挂载出来比较好
docker exec -it 容器名/容器ID /bin/bash
进入到容器里面以后,和平常的linux文件系统一样,你可以到处看看,或者查看官网和其他博客看他的文件结构是怎样的,日志文件夹和配置文件放在哪里
可以使用find命令查找文件的路径,像下面这样
# 查找nginx配置文件nginx.conf
# 这个在/etc/nginx/nginx.conf
find / -name "nginx.conf"
docker cp 指令可以将容器里面的文件拷贝到宿主机的指定文件夹
docker cp nginx(容器名):/etc/nginx/conf.d/default.conf /usr/local/nginx/config/conf.d/default.conf
弄好了之后退出容器
exit
Nginx 403:forbiden的其他可能原因
文件夹权限问题
如果nginx没有web目录的操作权限,也会出现403错误
解决办法:修改web目录的读写权限,或者是把nginx的启动用户改成目录的所属用户,重启Nginx即可解决
如下方式是比较暴力的,文件所有者(Owner)、用户组(Group)、其它用户(Other Users)都赋予了最高权限:可读可写可执行
chmod -R 777 文件夹
由于启动用户和nginx工作用户不一致所致
查看启动用户是谁
ps aux | grep "nginx: worker process" | awk'{print $1}'
Linux ps 命令
Linux grep 命令
Linux awk 命令
shell “|” ,代表有管道。"|" 左右被理解为简单命令,即前一个(左边)简单命令的标准输出指向后一个(右边)标准命令的标准输入
awk会根据分隔符将输入分成若干个字段,$0为整行,$1为第一个字段,$2 为第2个地段,依此类推…
为打印一个字段或所有字段,使用print命令。这是一个awk动作
nginx.conf 配置文件定义了user, 这里默认的user 是 nginx
将user替换为查询到的启动用户
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
selinux
SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。NSA是在Linux社区的帮助下开发了一种访问控制体系,在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。SELinux 默认安装在 Fedora 和 Red Hat Enterprise Linux 上,也可以作为其他发行版上容易安装的包得到。
seLinux设置为开启状态(enabled),也可能导致403
查看当前selinux的状态
/usr/sbin/sestatus
你可以修改他的配置文件
vi /etc/selinux/config
设置为关闭,一般默认状态是关闭的
SELINUX=disabled
使得source命令修改立即生效或者reboot服务器。
source命令也称为“点命令”,也就是一个点符号(.)。source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
source /etc/selinux/config
. /etc/selinux/config
References:
- https://blog.csdn.net/qq_35843543/article/details/81561240
- https://baike.baidu.com/item/SELinux/8865268?fr=aladdin
- https://www.linuxprobe.com/linux-awk-clever.html
(写博客主要是对自己学习的归纳整理,资料大部分来源于书籍、网络资料和自己的实践,整理不易,但是难免有不足之处,如有错误,请大家评论区批评指正。同时感谢广大博主和广大作者辛苦整理出来的资源和分享的知识。)
更多推荐
所有评论(0)