一、基于不同ip搭建web服务器
(一)实验目标
在 red hat 10 系统上安装 nginx,并配置两个基于不同 ip 地址的虚拟主机(virtual host),实现通过不同 ip 访问不同的网页内容。
(二)详细操作步骤
第一步:安装 nginx
使用 dnf 包管理器安装 nginx。
dnf install nginx -y
注意:截图显示安装过程中提示“无法读取客户身份”及“未在权利服务器中注册”,这属于订阅管理提示,不影响 nginx 软件包的正常安装。
启动并设置 nginx 开机自启。
systemctl restart nginx systemctl enable nginx
验证:使用 systemctl status nginx 查看服务状态,确保显示 active (running)。
第二步:创建网页目录结构
为了区分不同的虚拟主机,我们需要创建独立的目录和测试页面。
1、创建主目录
在 /www 下创建 test 和 exam 目录。
mkdir -p /www/{test,exam}
2、设置 selinux 上下文(关键步骤)
由于 rhel 默认开启 selinux,直接在根目录 / 下创建的目录可能无法被 nginx 读取。需要修改安全上下文
semanage fcontext -a -t httpd_sys_content_t "/www(/.*)?" restorecon -r /www
解释:将 /www 及其子目录的类型标记为httpd_sys_content_t,允许 web 服务访问。
3、创建测试页面
echo "hello,130" > /www/test/index.html echo "hello,131" > /www/exam/index.html

第三步:配置网络 ip 地址
本实验采用“基于 ip 的虚拟主机”,因此需要为网卡配置多个 ip 地址(ip 别名)。
1、查看当前 ip
使用 ip a 查看网卡名称(截图中为 ens160)
2、临时添加 ip 地址
nmcli connection modify ens160 +ipv4.addresses 172.25.2.130/24 nmcli connection modify ens160 +ipv4.addresses 172.25.2.131/24 nmcli connection up ens160
效果:此时 ens160 网卡将同时拥有 130 和 131 两个 ip。
第四步:配置防火墙
firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload
第五步:配置 nginx 虚拟主机
将配置文件存放在 /etc/nginx/conf.d/ 目录下。
1、编辑配置文件
vim /etc/nginx/conf.d/ip.conf
2、配置代码
将以下代码复制到 ip.conf 文件中:
server {
listen 172.25.2.130:80;
server_name _;
location / {
root /www/test;
index index.html;
}
}
server {
listen 172.25.2.131:80;
server_name _;
location / {
root /www/exam;
index index.html;
}
}参数解释:
listen:指定该虚拟主机监听的 ip 和端口。root:指定该 ip 对应的网站根目录。server_name _;:表示匹配任意主机名。
3、重启 nginx 使配置生效
systemctl restart nginx
(三)验证测试
配置完成后,通过 curl 命令或浏览器进行访问测试。
访问 ip 130:
- 命令:
curl http://172.25.2.130 - 输出:
hello,130
访问 ip 131:
- 命令:
curl http://172.25.2.131 - 输出:
hello,131
(四)故障排查提示
如果访问失败,请检查以下几点:
- selinux 权限:确保
/www目录的 selinux 上下文正确(使用ls -zd /www查看)。 - 防火墙:确保防火墙已放行 80 端口。
- 配置语法:运行
nginx -t检查配置文件是否有语法错误。 - 服务状态:确保
systemctl status nginx显示为 running。
二、基于不同端口的web服务器搭建
(一)实验目标及意义
目标:在 red hat 10 系统上,利用已安装的 nginx 服务,配置两个基于不同端口的虚拟主机。实现通过访问 ip:9091 和 ip:9092 访问不同的网页内容。
意义:在生产环境中,有时无法为服务器分配多个 ip 地址,或者希望在同一 ip 上托管多个独立的 web 服务。此时,基于端口的虚拟主机(port-based virtual host)是最佳解决方案。
(二)详细操作步骤
第一步
参照 一、 中 (二)详细操作步骤 的前两步操作(一模一样)
第二步:配置防火墙(开放指定端口)
nginx 默认只开放 80 端口,我们需要手动放行 9091 和 9092 端口。
firewall-cmd --permanent --add-port=9091/tcp firewall-cmd --permanent --add-port=9092/tcp
重载防火墙
firewall-cmd --reload
验证:确保命令返回 success。
第三步:nginx虚拟主机
创建一个新的配置文件,或者修改原有的配置文件(建议新建以避免冲突)。
1、编辑配置文件
vim /etc/nginx/conf.d/port.conf
2、写入配置代码
将以下代码复制到文件port.conf中。注意 listen 指令后的端口号变化,以及 root 路径的对应关系。
server {
listen 9091; # 监听本机所有 ip 的 9091 端口
server_name _; # 匹配任意域名
location / {
root /www/test; # 对应 test 目录
index index.html;
}
}
server {
listen 9092; # 监听本机所有 ip 的 9092 端口
server_name _; # 匹配任意域名
location / {
root /www/exam; # 对应 exam 目录
index index.html;
}
}💡 参数解析:
listen 9091:不再指定具体 ip,意味着服务器的所有 ip 地址(如 172.25.2.130)都可以通过:9091访问此服务。root:复用了上一实验的目录结构,确保数据一致性。
3、重启 nginx 服务
systemctl restart nginx
(三)验证测试
配置完成后,使用 curl 命令进行本地或远程测试。
访问端口 9091:
- 命令:
curl http://127.0.0.1:9091 - 预期输出:
hello,130
访问端口 9092:
- 命令:
curl http://127.0.0.1:9092 - 预期输出:
hello,131
(四)可能有困惑之处-详解
1、配置server_name _;的原因
在基于端口的配置中,nginx 依靠 listen 指令后的端口号(如 9091)来区分不同的网站。server_name _; 是一个通配符,表示“匹配任意域名”。如果写死域名或 ip,当客户端通过 ip:端口 访问时,http 请求头中的 host 字段(如 127.0.0.1:9091)可能无法匹配,导致 nginx 返回默认页面或 404。使用 _ 确保了只要端口对,就能命中配置。
2、防火墙配置的必要性
linux 的 firewalld 默认只放行常用端口(如 80、443)。自定义端口(9091/9092)必须手动添加规则,否则外部网络包无法进入服务器。
(五)所遇故障及排查思路
1、遇到的报错

日志中出现了关键错误信息:
nginx: [emerg] bind() to 0.0.0.0:9091 failed (13: permission denied)
解读:nginx 进程没有权限绑定到 9091 和 9092 端口。这通常不是文件权限问题,而是 selinux(security-enhanced linux) 在作祟。selinux 有一套预定义的端口策略,nginx 默认只被允许监听 80、443 等标准端口,非标准端口会被拦截。
2、解决步骤
①查看防火墙配置(放行的端口是否正确)
[root@localhost conf.d]# firewall-cmd --list-ports
若出现9091/tcp 9092/tcp,则证明无误;
若没出现,就重新配置,如下命令。
防火墙放行端口(这一步是必要的,但不是导致 permission denied 的原因)
firewall-cmd --permanent --add-port=9091/tcp firewall-cmd --permanent --add-port=9092/tcp firewall-cmd --reload
重启服务(依然失败,大概率推断是 selinux 问题)
systemctl restart nginx

上述确认无误但还是不能启动,进一步如下操作:
②检查端口是否被其他进程占用
netstat -tuln | grep 9091 netstat -tuln | grep 9092
![]()
假设被占用了,你看到类似这样的输出: tcp 0 0 0.0.0.0:9091 0.0.0.0:* listen 0 12345 1234/java
最后一列 1234/java 表示:pid 为 1234 的 java 程序正在占用 9091 端口。
杀掉进程(以 pid 1234 为例)
kill -9 1234
重新检查端口,确认已释放
netstat -tuln | grep 9091
(此时应该没有输出,表示端口空闲)
没被占用,且还不能正常启动nginx,继续下一步操作:
③ selinux 排错
解决方案:临时禁用 selinux 进行验证
临时将 selinux 设置为宽容模式(permissive)
setenforce 0
再次检查配置语法
nginx -t
输出:syntax is ok (此时语法检查通过,且不再报 permission denied)
systemctl restart nginx
再次重新启动nginx
![]()
最终建议: 为了系统安全,建议在实验结束后,重新开启 selinux 并通过策略模块放行端口,而不是保持 setenforce 0 的状态。
3、最终解决故障,成功排错并解决!
三、基于不同主机名的web服务器搭建
(一)实验目标
配置两个基于域名的虚拟主机 (www.test.com 和 www.exam.com),并实现正常访问。
(二)详细操作步骤
第一步:准备网站根目录与测试页面
1、创建网站根目录
mkdir -p /www/test /www/exam
2、编写测试页面文件
/www/test/index.html 内容为 hello,130
/www/exam/index.html 内容为 hello,131
这里我直接用的上述实验的目录文件了,就没有重复操作,这里就不放实验图片啦 > . <
3、本地解析
修改 /etc/hosts 文件,添加域名映射(指向本机或指定 ip),以便在没有 dns 服务器的情况下进行测试。
vim /etc/hosts
第二步:编写 nginx 虚拟主机配置
1、进入配置目录
cd /etc/nginx/conf.d/
2、创建配置文件
[root@localhost conf.d]# vim hostname.conf
[root@localhost conf.d]# cat hostname.conf
server {
listen 9091;
server_name www.test.com;
location / {
root /www/test;
index index.html;
}
}
server {
listen 9092;
server_name www.exam.com;
location / {
root /www/exam;
index index.html;
}
}第三步:重启nginx服务
# 放行 selinux 策略(解决 9091/9092 权限问题) [root@localhost conf.d]# semanage port -a -t http_port_t -p tcp 9091 [root@localhost conf.d]# semanage port -a -t http_port_t -p tcp 9092 [root@localhost conf.d]# systemctl restart nginx.service
(三)验证测试
[root@localhost conf.d]# curl http://www.test.com hello,130 [root@localhost conf.d]# curl http://www.exam.com hello,131
(四)所遇故障及排查思路
1、遇到的故障
2、解决方法1(使用9091、9092端口)

nginx: [emerg] bind() to 0.0.0.0:9091 failed (13: permission denied)
解读:nginx 想要绑定(监听)9091 端口,但是系统拒绝了。
原因:这是 selinux 在搞鬼,9091 端口被 selinux 拦截(centos/rhel 的安全机制,默认不允许 nginx 用 80 以外的端口)。
解决:
①将配置文件的80端口改为9091和9092
②通过命令放行selinux策略
# 安装 semanage 工具(如果没安装) yum install policycoreutils-python-utils -y # 告诉 selinux 允许 9091和9092 semanage port -a -t http_port_t -p tcp 9091 semanage port -a -t http_port_t -p tcp 9092
提示:如果还是不行也检查一下9091和9092是否被其他进程监听占用,如下图。
正是因为我发现9091和9092比80(如解决方法2中图)被进程监听占用得少(就可以少备份一份文件),所以上述正常详细操作步骤中我选择的是用9091和9092端口,而不是80端口。
3、解决方法2(仍使用80端口)
①首先排查80端口是否被其他进程监听占用
grep -r "listen.*80" /etc/nginx/

输出分析
ip.conf: listen 172.25.2.130:80;(它已经在用 80 了)ip.conf: listen 172.25.2.131:80;(它还在用 80)hostname.conf: listen 80;(你又申请用一次 0.0.0.0:80)
结论:出现了nginx配置冲突,80端口ip.conf在使用了,hostname也想使用,导致冲突。这就像是两个人都想坐同一把椅子(80号椅子),肯定会打架。
②备份干扰文件并移除(ip.conf)
mv /etc/nginx/conf.d/ip.conf /etc/nginx/conf.d/ip.conf.bak
4、成功解决
无论上述哪一种方法都能有效解决这个报错问题,最后重启nginx服务就没问题了!
(五) 实验总结与关键知识点
1、nginx 启动失败排查三部曲
systemctl status nginx(看状态)journalctl -xeu nginx.service(看具体报错原因,如 permission denied)grep "listen" /etc/nginx/*(看哪里占用了端口)
2、selinux 的重要性
- 当你确信端口未被占用(
netstat检查后),但 nginx 依然报permission denied时,90% 的情况是 selinux 在起作用。 - 解决方案:使用
semanage port -l \| grep http查看允许端口,使用semanage port -a添加新端口,而不是直接关闭 selinux (setenforce 0)。
3、虚拟主机配置原则
基于主机名的虚拟主机,要求所有
server块的listen指令必须相同(相同的 ip:端口),nginx 才能通过server_name来区分不同的网站。如果端口不同,它们在逻辑上就是两个独立的服务,而非“基于主机名”的虚拟主机实验。注:本实验因环境限制改用了不同端口,但在纯净环境下,应统一使用 80 端口并解决冲突
(六)扩展知识:linux 中常见的三种“permission denied”🧐
1、文件/目录权限拒绝 (标准 linux 权限)
- 场景:你试图删除一个属于其他用户的文件,或者执行一个没有执行权限的脚本。
- 原因:
rwx(读、写、执行)权限设置不对。 - 解决:使用
chmod修改权限,或使用chown修改所有者。
2、端口绑定权限拒绝 (特权端口限制)
- 场景:一个普通用户试图启动服务监听 80 端口。
- 原因:linux 规定 0-1023 的端口是“特权端口”,只有 root 用户才能使用。
- 解决:使用
sudo提权,或者改用 1024 以上的大端口(如 8080, 9091)。
3、安全策略权限拒绝 (selinux/apparmor) ——正是上述所遇的故障
场景:即使是 root 用户,即使端口没被占用,即使文件权限正确,系统依然拒绝操作。
原因:系统的安全策略(selinux)认为该操作不安全。
特征:通常伴随着端口绑定失败(如你的情况)或文件访问失败(如 nginx 无法读取网页文件)。
解决:
- 正确做法:调整 selinux 策略(如使用
semanage port -a ...放行端口)。 - 粗暴做法:临时关闭 selinux (
setenforce 0)。
四、基于https加密的web服务器配置
(一)实验目标
配置基于https加密的web站点
(二)实验步骤
1、生成ssl证书
# 创建证书目录 sudo mkdir -p /etc/ssl/private # 生成自签名证书,建议直接复制粘贴下述代码 openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/nginx-selfsigned.key \ -out /etc/ssl/certs/nginx-selfsigned.crt
openssl req: 调用 openssl 的证书签名请求(csr)生成工具。-x509: 指定输出一个自签名证书,而不是生成证书请求文件(csr)。在测试环境中直接生成证书用此参数。-nodes: no des (no des encryption)。表示私钥文件不加密。nginx 服务启动时通常需要读取私钥,如果私钥设置了密码,每次重启 nginx 都需要手动输入密码,这在生产服务器上是不可接受的,因此必须使用-nodes。-days 365: 指定证书有效期为 365 天。-newkey rsa:2048: 生成一个新的密钥对(公钥和私钥)。rsa:2048指定使用 rsa 算法,密钥长度为 2048 位(目前的安全标准)。-keyout ...: 指定生成的私钥文件保存路径。-out ...: 指定生成的证书文件(公钥部分)保存路径。

证书信息填写:
country name (2 letter code) [xx]: cn state or province name (full name) []: beijing locality name (eg, city) [default city]: beijing organization name (eg, company) [default company ltd]: my organizational unit name (eg, section) []: it common name (eg, your name or your server's hostname) []: www.https.com email address []: admin@example.com
2、配置selinux上下文
# 配置证书文件selinux上下文 [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t "/etc/ssl/certs/nginx-selfsigned.crt" [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t "/etc/ssl/private/nginx-selfsigned.key" [root@localhost ~]# restorecon -v /etc/ssl/certs/nginx-selfsigned.crt [root@localhost ~]# restorecon -v /etc/ssl/private/nginx-selfsigned.key
semanage fcontext: selinux 管理文件上下文的命令。
-a: 添加(add)一条规则。-t httpd_sys_content_t: 指定目标类型。httpd_sys_content_t是 apache/nginx 进程允许读取的文件类型。"/path/...": 对应的文件路径。
restorecon -v: 重新加载(restore)文件的安全上下文。-v 参数表示显示详细过程。这一步是将 semanage 定义的规则应用到实际文件上,让 nginx 进程能够读取证书文件,否则会报 403 forbidden 或权限拒绝错误。
3、创建配置文件
创建 /etc/nginx/conf.d/https.conf:
server {
listen 443 ssl;
server_name www.https.com;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
location / {
root /www/https;
index index.html;
}
}4、配置本地解析
编辑 /etc/hosts 文件:
sudo vim /etc/hosts
添加以下内容:127.0.0.1 www.https.com
5、编写测试页面文件
[root@localhost ~]# cd /www/ [root@localhost www]# ll 总计 0 drwxr-xr-x. 2 root root 24 3月30日 18:35 exam drwxr-xr-x. 2 root root 6 3月30日 14:49 https drwxr-xr-x. 2 root root 24 3月30日 18:35 test [root@localhost www]# cd https/ [root@localhost https]# echo hello,https!!! > index.html echo hello,httpsll! > index.html [root@localhost https]# cat index.html hello,httpsll!
6、测试配置
# 检查配置语法(可选) nginx -t # 重启nginx systemctl restart nginx # 测试访问(忽略证书验证) curl -k https://www.https.com
(三)常见问题与解决方案
问题1:证书文件无法加载
现象: cannot load certificate ... no such file or directory
解决方案
# 确保证书目录存在 sudo mkdir -p /etc/ssl/private # 重新生成证书 sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/nginx-selfsigned.key \ -out /etc/ssl/certs/nginx-selfsigned.crt
问题2:https访问被重定向
现象: 访问时被重定向到广告页面
解决方案
# 确保本地解析配置正确 echo "127.0.0.1 www.https.com" | sudo tee -a /etc/hosts # 删除默认配置文件 sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
问题3:selinux权限拒绝
现象: nginx无法访问文件或端口
解决方案
# 修复目录上下文 sudo restorecon -r /www # 允许自定义端口 sudo semanage port -a -t http_port_t -p tcp 9090
五、 实验总结与配置思路
(一)四个实验的整体配置思路
这四个实验层层递进,展示了 nginx 如何利用 listen 和 server_name 指令实现“一台服务器,多个站点”。
1、基于 ip 的虚拟主机 (ip-based)
- 核心逻辑:不同的 ip 地址 对应不同的网站。
- 配置关键:
listen指令后跟具体的 ip:port(如172.25.2.130:80)。服务器通过判断请求发往哪个 ip 来决定展示哪个页面。 - 前提:服务器必须配置了多个 ip 地址(ip 别名)。
2、基于端口的虚拟主机 (port-based)
- 核心逻辑:同一个 ip,不同的 端口号 对应不同的网站。
- 配置关键:
listen指令后跟不同的端口(如9091或9092)。 - 应用场景:ip 资源有限,但需要通过不同入口访问内部服务。
3、基于主机名的虚拟主机 (name-based)
- 核心逻辑:同一个 ip 和端口,根据 http 请求头中的 域名 (host) 不同来区分网站。
- 配置关键:所有
server块监听相同的listen(如80),通过不同的server_name(如www.test.com)来匹配。 - 本质:这是目前互联网上最常用的“虚拟主机”技术,即大量网站共用一个 ip。
4、基于 https 的加密站点
核心逻辑:在 http 的基础上增加 ssl/tls 加密层。
配置关键
listen 443 ssl;:声明这是一个 ssl 监听端口。ssl_certificate和ssl_certificate_key:指定证书和私钥的路径。
安全增强:结合了前三种虚拟主机的逻辑,但增加了数据传输的加密和身份验证(虽然是自签名)。
(二)关键排错经验总结
通过这四个实验,可以总结出 linux 下 web 服务排错的“黄金法则”:
第一步(服务层)
systemctl status nginx -> 看服务是否启动。
第二步(日志层)
journalctl -xeu nginx.service -> 看具体报错代码(如 permission denied)。
第三步(配置层)
nginx -t-> 检查语法;grep listen /etc/nginx/*` -> 检查端口冲突。
第四步(安全层)
当端口未被占用但无法绑定时,检查 selinux (semanage port -l | grep http);当文件存在但无法读取时,检查 selinux 上下文 (ls -z)。
到此这篇关于基于红帽redhat环境下配置nginx web服务器的文章就介绍到这了,更多相关红帽redhat配置nginx服务器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论