web服务

Administrator 0

Linux Web 服务器


目录

  1. 软件包安装
  2. 认识 Web 服务器:它到底在做什么
  3. 三大主流 Web 服务器总览
  4. Nginx 架构:为什么它快
  5. Nginx 基本配置:server / location / 静态站点
  6. Nginx 托管动态应用
  7. Nginx 反向代理与负载均衡
  8. HTTPS:让网站更安全
  9. 性能优化与缓存
  10. 安全加固要点
  11. Apache httpd:经典之选(对比补充)
  12. Caddy:自动 HTTPS 的现代之选(对比补充)
  13. 从零在 Rocky 部署一个完整网站(整合篇)
  14. 常见问题排查清单
  15. 总结与选型对比
  16. 参考资料

软件包安装

本节安装后面会用到的软件。以 Nginx 为主,Apache 与 Caddy 按需安装。

安装 Nginx(Rocky / RHEL / CentOS)

Rocky 的 AppStream 自带 nginx,直接安装:

sudo dnf install -y nginx
sudo systemctl enable --now nginx
sudo systemctl status nginx

安装 Apache httpd(可选,用于对比)

sudo dnf install -y httpd
sudo systemctl enable --now httpd

提示:Nginx 与 Apache 都监听 80/443 端口,不要在同一台机器上同时启用,以免端口冲突。建议在虚拟机里分别实验,或临时停掉另一个服务。

安装 Caddy(可选,用于对比)

sudo dnf install -y caddy
sudo systemctl enable --now caddy

Ubuntu / Debian 差异

# Nginx / Apache / Caddy 在 Ubuntu 上
sudo apt install -y nginx apache2 caddy

# 服务名:nginx / apache2 / caddy
sudo systemctl enable --now nginx apache2

放行 HTTP/HTTPS 端口(防火墙)

sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload

# 确认
firewall-cmd --query-service=http
firewall-cmd --query-service=https

若在云上,还要在安全组放行 80/443 端口。


一、认识 Web 服务器:它到底在做什么

1.1 一句话定义

Web 服务器是一台(或一组)运行在网络上的程序:它监听 HTTP 请求,返回响应。浏览器输入网址发出请求,Web 服务器把网页(HTML、图片、脚本等)发回给浏览器。

1.2 一次完整的访问流程

浏览器 --HTTP请求-->  Web 服务器(Nginx/Apache/Caddy) --读取--> 网站文件/程序
浏览器 <--HTTP响应--  Web 服务器                  <--返回-->  内容
  • 你访问 http://example.com,浏览器向服务器 80 端口 发一个 HTTP 请求(如 GET /index.html)。
  • Web 服务器找到对应的文件(或调用程序生成内容),组装成 HTTP 响应(含状态码、响应头、正文)返回。
  • 状态码常见:200 OK(成功)、301/302(重定向)、404(找不到)、403(禁止)、500(服务器内部错误)。

1.3 静态与动态

  • 静态内容:文件本来就在磁盘上(HTML、CSS、JS、图片),Web 服务器直接读文件返回,
  • 动态内容:内容由程序实时生成(PHP、Python、Java、Node 等),Web 服务器要把请求转发给后端程序,再把结果返回。

静态内容 Web 服务器自己就能搞定;动态内容需要 Web 服务器 + 后端解释器/应用配合(见第五章)。

1.4 为什么有 80 和 443 两个端口

  • 80:HTTP(明文)。
  • 443:HTTPS(加密,TLS)。
  • 现在主流网站都走 HTTPS(443),80 通常用来跳转到 443。

参考:phoenixNAP - What Is a Web Server?


二、三大主流 Web 服务器总览

Linux 上最常用的三类 Web 服务器:NginxApache httpdCaddy。它们各有侧重:

对比项 Nginx Apache httpd Caddy
出身 高性能、高并发 老牌、功能全面 现代、开箱即用
处理模型 事件驱动、异步 每请求一线程/进程 事件驱动(Go)
静态文件 很快
动态支持 配合 PHP-FPM/FastCGI 内置 mod_php 等模块 配合 FastCGI/代理
配置 清晰、较简洁 灵活但常较冗长 极简(Caddyfile)
自动 HTTPS 需手动或 certbot 需手动或 certbot 内置自动 HTTPS
生态 现代网站主流 传统托管广泛 个人/快速部署
适合 高并发、反向代理 传统应用、.htaccess 个人站点、快速上手

Nginx 目前是互联网上占有率最高的 Web 服务器之一,也是本文主线。Apache 经典稳定,Caddy 以自动 HTTPS 闻名。


三、Nginx 架构:为什么它快

要"讲透"Nginx,先理解它的架构——这是它与 Apache 最本质的区别。

3.1 事件驱动、异步、非阻塞

  • Nginx 采用 事件驱动(event-driven)+ 异步非阻塞 模型:一个 worker 进程可以同时处理成千上万个连接,而不是"一个请求占一个进程"。
  • 这让 Nginx 能用很少的内存支撑很高的并发,尤其擅长静态文件和反向代理。

3.2 master / worker 进程模型

Nginx 运行时有 master 进程 和多个 worker 进程

master 进程(root)  -> 负责管理、读配置、绑定特权端口
worker 进程(nginx 用户)-> 真正处理请求,可配置多个
  • master 以 root 运行:为了能绑定特权端口 80/443(<1024),也为了读配置、管理 worker。
  • worker 以普通用户(nginx)运行:负责处理请求,降权以增强安全,即使被攻破也拿不到 root。
  • worker 数量通常设为 CPU 核心数(worker_processes auto;)。

3.3 这也解释了端口 80 权限坑

  • Linux 中 0–1023 是特权端口,只有 root(或具备 CAP_NET_BIND_SERVICE 能力的进程)能监听。
  • 普通用户直接监听 80 会报:bind() to 0.0.0.0:80 failed (13: Permission denied)
  • Nginx 靠 master 进程的 root 权限绑定 80/443,再由 worker 降权干活——这就是它"能监听 80 又相对安全"的原因。

参考:nginx.org - Beginner's Guide


四、Nginx 基本配置:server / location / 静态站点

4.1 配置文件的组织

/etc/nginx/nginx.conf               # 主配置
/etc/nginx/conf.d/*.conf            # 站点/server 配置(推荐放这里)
/etc/nginx/default.d/               # 默认站点的补充
  • 通常做法:在 conf.d/ 下新建 mysite.conf 写自己的站点。
  • 改完先 nginx -t 测试语法,再 systemctl reload nginx 热加载。

4.2 server 块:定义一个站点

server {
    listen 80;
    server_name mysite.example.com;
    root /var/www/mysite;
    index index.html;
}
  • listen 80;:监听端口。
  • server_name:匹配哪个域名(多个用空格隔开)。
  • root:站点文件根目录。
  • index:访问目录时默认加载的文件。

4.3 location 块:按路径匹配

server {
    listen 80;
    server_name mysite.example.com;
    root /var/www/mysite;

    location /images/ {
        # 前缀匹配:/images/ 开头的请求
    }

    location = /favicon.ico {
        log_not_found off;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}
  • location /:默认处理所有未命中的路径。
  • try_files $uri $uri/ =404:先找文件、再找目录,都没有返回 404。
  • location 匹配优先级:精确(=)> 前缀(^)> 正则()> 普通前缀

4.4 静态站点验证

sudo mkdir -p /var/www/mysite
sudo tee /var/www/mysite/index.html >/dev/null <<'EOF'
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>我的站点</title></head>
<body><h1>Hello Linux Web Server</h1></body></html>
EOF

# 配置权限(worker 以 nginx 用户运行,需能读这些文件)
sudo chown -R nginx:nginx /var/www/mysite
sudo chmod 755 /var/www/mysite && sudo chmod 644 /var/www/mysite/index.html

# 测试并加载配置
sudo nginx -t
sudo systemctl reload nginx

# 验证
curl -I http://127.0.0.1/

参考:docs.nginx.com - Serving Static Content


五、Nginx 托管动态应用

静态内容 Nginx 直接返回;动态内容(如 PHP、Python、Node)需要把请求交给后端程序处理。

5.1 动态内容的常见做法

  • PHP:Nginx 本身不解析 PHP,需要配合 PHP-FPM(FastCGI 进程管理器),用 fastcgi_pass 转发。
  • Python/Node/Java 等:应用自己监听一个高位端口(如 8080),Nginx 用 proxy_pass 反向代理(见第六章)。

5.2 Nginx + PHP-FPM 示例

server {
    listen 80;
    server_name mysite.example.com;
    root /var/www/mysite;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    # 把 .php 请求交给 PHP-FPM 处理
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}
# 安装 PHP-FPM(Rocky)
sudo dnf install -y php-fpm
sudo systemctl enable --now php-fpm

对比:Apache 通常用 mod_php(直接嵌入 PHP)或 PHP-FPM,配置上 Nginx 走 fastcgi_pass,Apache 走 ProxyPass 或 mod_php——这是两者托管动态应用的主要差异。


六、Nginx 反向代理与负载均衡

反向代理(reverse proxy) 是 Nginx 最常用的场景之一:浏览器访问 Nginx(80/443),Nginx 把请求转发给后端应用(跑在高位端口的内网服务),再把响应返回。

6.1 一个最简单的反向代理

假设后端应用监听 127.0.0.1:8080

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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_pass:把请求转发给后端。
  • proxy_set_header Host $host;:把原始 Host 传给后端(后端才知道访问的是哪个域名)。
  • X-Real-IP / X-Forwarded-For:把客户端真实 IP 传给后端(否则后端只看到 127.0.0.1)。

6.2 负载均衡(upstream)

后端有多个实例时,用 upstream 定义一组服务器,Nginx 自动分配请求:

upstream backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
    }
}
  • 默认轮询(round-robin) 分配;也可配 weightleast_conn 等策略。
  • 一台后端挂掉,Nginx 会自动把请求分给其他正常实例。

6.3 SELinux:反向代理要额外放行(Rocky 特有)

# Rocky 上 Nginx 默认被 SELinux 限制,转发到后端需要开启:
sudo setsebool -P httpd_can_network_connect 1

不加这步,反向代理会报 (13: Permission denied) while connecting to upstream

参考:docs.nginx.com - NGINX Reverse Proxy


七、HTTPS:让网站更安全

HTTPS 就是在 HTTP 外面加一层 TLS 加密,运行在 443 端口。要让网站走 HTTPS,需要一张 SSL/TLS 证书

7.1 证书从哪来

  • Let's Encrypt:免费、自动化的证书颁发机构,配合 certbot 工具自动申请和续期,最常用。
  • 云厂商/商业 CA:付费证书,用于企业场景。

7.2 Nginx 配置 HTTPS

手动配置(假设已有证书 example.com.crt 和私钥 example.com.key):

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/ssl/example.com.crt;
    ssl_certificate_key /etc/ssl/example.com.key;

    root /var/www/mysite;
    index index.html;
}

# 把 80 端口的 HTTP 请求跳转到 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

7.3 用 certbot 自动申请证书

# 安装 certbot(Rocky)
sudo dnf install -y certbot python3-certbot-nginx

# 自动申请并配置 Nginx(需域名已解析到本机,且 80 端口可达)
sudo certbot --nginx -d example.com -d www.example.com

# 自动续期(certbot 会装 timer)
sudo certbot renew --dry-run
  • certbot 会自动改写 Nginx 配置加上证书,并设置续期。
  • Let's Encrypt 证书有效期 90 天,certbot 的 timer 会自动续期。

7.4 Apache 与 Caddy 的 HTTPS 对比

Web 服务器 配置 HTTPS 方式
Nginx 手写 ssl_certificate,或用 certbot --nginx
Apache 手写 SSLCertificateFile,或用 certbot --apache
Caddy 无需配置,有域名就自动申请并启用 HTTPS
# Apache 的 HTTPS 配置示例
<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /etc/ssl/example.com.crt
    SSLCertificateKeyFile /etc/ssl/example.com.key
</VirtualHost>

参考:nginx.org - Configuring HTTPS servers、Caddy - Automatic HTTPS


八、性能优化与缓存

Nginx 的常见性能优化点:

8.1 worker 进程数

# 通常设为 CPU 核心数;auto 表示自动检测
worker_processes auto;
events {
    worker_connections 1024;   # 每个 worker 的最大连接数
}

8.2 gzip 压缩

对文本类内容(HTML/CSS/JS/JSON)启用 gzip,能显著减小传输体积:

http {
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml;
}

8.3 静态资源缓存(expires)

对图片、CSS、JS 等静态资源设置缓存头,减少重复请求:

location ~* \.(css|js|png|jpg|jpeg|gif|ico)$ {
    expires 7d;
    add_header Cache-Control "public";
}

8.4 静态文件开启 sendfile

sendfile on;        # 用内核 sendfile 高效发送文件
tcp_nopush on;

参考:docs.nginx.com - Compression and Decompression、nginx.org - ngx_http_gzip_module


九、安全加固要点

9.1 隐藏服务器版本

server_tokens off;   # 隐藏响应头里的 Nginx 版本号

9.2 限制请求体大小

client_max_body_size 10m;   # 限制上传体积,防止超大请求

9.3 关闭目录列表

Nginx 默认不列目录;若开启了 autoindex on 记得关掉或仅用于内网:

autoindex off;

9.4 系统层安全(配合前面学的)

  • 防火墙只放行必要的端口(80/443/22)。
  • 文件权限:网站文件只给 nginx 用户读权限,不给写权限(除非确实需要)。
  • SELinux(Rocky):保持 Enforcing,用 restorecon / setsebool 正确处理上下文和网络布尔值。

安全是系统工程:Web 服务器配置 + 系统防火墙 + 文件权限 + SELinux 缺一不可,正好呼应本系列前面讲过的防火墙与权限模块。


十、Apache httpd:经典之选(对比补充)

Apache httpd 是历史最悠久的 Web 服务器之一,功能全面、稳定,传统虚拟主机托管大量使用。

10.1 与 Nginx 的核心差异

  • 处理模型:Apache 传统上是每请求一线程/进程(MPM 模型),并发高时内存开销比 Nginx 大。
  • 模块化:Apache 功能靠模块(如 mod_phpmod_rewritemod_ssl),灵活但配置较分散。
  • .htaccess:Apache 支持在每个目录放 .htaccess目录级配置(需开启 AllowOverride),Nginx 没有对应机制。

10.2 配置文件位置

# Rocky/RHEL:  /etc/httpd/conf/httpd.conf  主配置
#              /etc/httpd/conf.d/*.conf    站点配置
# Ubuntu:      /etc/apache2/apache2.conf   主配置
#              /etc/apache2/sites-available/  站点(用 a2ensite 启用)

10.3 一个 Apache 静态站点

<VirtualHost *:80>
    ServerName mysite.example.com
    DocumentRoot /var/www/mysite
    <Directory /var/www/mysite>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
  • DocumentRoot 类似 Nginx 的 root
  • Require all granted 放行访问(Apache 2.4 语法)。
  • AllowOverride All 允许 .htaccess 生效。

10.4 何时选 Apache

  • 需要 .htaccess 做灵活的目录级配置(很多传统 CMS/虚拟主机依赖)。
  • 依赖 Apache 丰富的模块(如 mod_phpmod_rewrite)。
  • 老项目、托管环境兼容性要求高。

参考:Apache - httpd 官方文档


十一、Caddy:自动 HTTPS 的现代之选(对比补充)

Caddy 是一个用 Go 写的现代化 Web 服务器,最大亮点是开箱即用的自动 HTTPS极简的 Caddyfile

11.1 Caddyfile:静态站点

mysite.example.com {
    root * /var/www/mysite
    file_server
}

11.2 Caddyfile:反向代理

app.example.com {
    reverse_proxy localhost:8080
}

11.3 自动 HTTPS

  • 只要配了真实域名且解析指向本机,Caddy 会自动向 Let's Encrypt 申请证书并配置 HTTPS,无需手动配证书、无需续期。
  • 用纯 IP 或本机测试时,Caddy 走 HTTP 或内部自签证书。
sudo systemctl restart caddy
sudo journalctl -u caddy -n 50    # 看日志

11.4 何时选 Caddy

  • 几行配置就上线一个带 HTTPS 的站点。
  • 个人博客、内网工具、快速原型。
  • 不想折腾证书申请与续期。

参考:Caddy - Caddyfile Concepts、Rocky Linux - Caddy Web Server


十二、从零在 Rocky 部署一个完整网站(整合篇)

把本系列学到的文件、权限、网络、服务、安全全部串起来,用 Nginx 部署一个带静态站点 + 反向代理的完整网站。

12.1 准备文件与权限

sudo mkdir -p /var/www/mysite
sudo tee /var/www/mysite/index.html >/dev/null <<'EOF'
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>部署测试</title></head>
<body><h1>部署成功!</h1></body></html>
EOF

# worker 以 nginx 用户运行,需能读这些文件
sudo chown -R nginx:nginx /var/www/mysite
sudo chmod 755 /var/www/mysite && sudo chmod 644 /var/www/mysite/index.html

12.2 配置站点

server {
    listen 80;
    server_name _;
    root /var/www/mysite;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

保存到 /etc/nginx/conf.d/mysite.conf

sudo nginx -t
sudo systemctl reload nginx

12.3 放行网络

sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload

12.4 SELinux 检查

sudo restorecon -Rv /var/www/mysite    # 恢复默认上下文
getenforce                             # 确认 Enforcing

12.5 验证

curl -I http://127.0.0.1/       # 应返回 200
curl http://127.0.0.1/          # 应看到"部署成功!"
tail -f /var/log/nginx/access.log   # 看访问日志
  • 浏览器访问服务器 IP 即可看到网站。
  • 若想上 HTTPS,装 certbot 申请证书(见 7.3)。

到这里,文件(/var/www/mysite)、权限(nginx 用户可读)、网络(防火墙放行)、服务(nginx 加载配置)、安全(SELinux/权限) 五个环节全部打通,一个网站就完整上线了。


十三、常见问题排查清单

  1. 浏览器打不开 → 本机 curl -I http://localhost;本机通外部不通,查防火墙和云安全组 80/443。
  2. bind() ... Permission denied 绑定 80 → 非 root 不能监听 <1024 端口;用系统服务让 root 启动。
  3. 13: Permission denied 读文件 → worker 是 nginx 用户,检查文件权限(chown nginx:nginx)。
  4. SELinux 拦截静态文件restorecon -Rv /var/www/...
  5. 反向代理 Permission denied while connecting to upstreamsetsebool -P httpd_can_network_connect 1
  6. 改配置不生效nginx -tsystemctl reload nginx
  7. Nginx 与 Apache 端口冲突 → 两者都监听 80,只能启用其一。
  8. HTTPS 打不开 → 确认 443 端口放行、证书路径正确、域名已解析。

十四、总结与选型对比

14.1 核心速查

需求 Nginx 命令
安装 sudo dnf install -y nginx
启动/自启 sudo systemctl enable --now nginx
测试配置 sudo nginx -t
热加载 sudo systemctl reload nginx
放行端口 sudo firewall-cmd --permanent --add-service=http --add-service=https; sudo firewall-cmd --reload
看日志 tail -f /var/log/nginx/access.log
自动证书 sudo certbot --nginx -d example.com

14.2 三大 Web 服务器选型

场景 选择
高并发、反向代理、现代网站 Nginx
传统托管、需要 .htaccess、模块丰富 Apache httpd
快速上线、自动 HTTPS、个人站点 Caddy

14.3 动手练习建议

# 1. 装 Nginx 并跑起来
sudo dnf install -y nginx && sudo systemctl enable --now nginx
curl -I http://localhost

# 2. 部署一个静态站点(见第四章/十二章)

# 3. 起一个 8080 的服务,配一个反向代理(见第六章)

# 4. 配 HTTPS(见第七章,需域名)

# 5. 对比:在另一台虚拟机装 Apache / Caddy,体验配置差异

提示:练习在虚拟机进行。改配置前先 nginx -t 验证;Nginx 与 Apache/Caddy 不要同时占用 80 端口。


参考资料