Ubuntu 22.04配置Nginx反向代理完整教程
引言
反向代理是将应用服务器暴露到互联网的推荐方法。无论是在生产环境中运行Node.js应用程序还是使用Flask内置的最小Web服务器,这些应用服务器通常会绑定在本地主机的TCP端口上。这意味着默认情况下,您的应用程序只能在所在机器上本地访问。尽管您可以指定一个不同的绑定点来强制通过互联网访问,但这些应用服务器被设计为在生产环境中从反向代理中提供服务。这在隔离应用服务器与直接互联网访问、集中防火墙保护以及减少常见威胁(如拒绝服务攻击)的攻击面方面提供了安全性的好处。
从客户的角度来看,与反向代理的互动并无太大差异,与直接与应用服务器进行互动相同。在功能上完全一致,客户无法察觉到任何区别。客户请求资源,然后接收到资源,无需对客户端进行任何额外的配置。
这篇教程将展示如何使用流行的Web服务器和反向代理解决方案Nginx来设置反向代理。您将安装Nginx,并使用proxy_pass指令配置为反向代理,同时转发客户端请求中的适当头信息。如果您手头上没有应用服务器用于测试,您还可以选择使用WSGI服务器Gunicorn来设置一个测试应用程序。
先决条件
完成这个教程,你需要:
- 一台Ubuntu 22.04服务器,根据我们的Ubuntu 22.04初始服务器设置指南进行设置,
- 您想要代理的应用服务器地址,在本教程中将被称为app_server_address。这可以是一个带TCP端口的IP地址(如Gunicorn默认的http://127.0.0.1:8000),或者一个Unix域套接字(如pgAdmin的http://unix:/tmp/pgadmin4.sock)。如果您没有设置用于测试的应用服务器,本教程将指导您设置一个绑定到http://127.0.0.1:8000的Gunicorn应用程序。
- 一个指向您服务器公网IP的域名。这将配置Nginx来代理您的应用服务器。
步骤一 – 安装Nginx
通过默认源可以使用apt来安装Nginx。更新你的仓库索引,然后安装Nginx:
- sudo apt update
- sudo apt install nginx
按Y键确认安装。如果需要重启服务,请按ENTER键接受默认选项。
在防火墙中允许通过Nginx访问。按照初始服务器先决条件设置好服务器后,使用ufw添加以下规则:
- sudo ufw allow ‘Nginx HTTP’
现在你可以验证 Nginx 是否正在运行。
- systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-08-29 06:52:46 UTC; 39min ago
Docs: man:nginx(8)
Main PID: 9919 (nginx)
Tasks: 2 (limit: 2327)
Memory: 2.9M
CPU: 50ms
CGroup: /system.slice/nginx.service
├─9919 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
└─9920 "nginx: worker process"
接下来,您将添加一个自定义的服务器块,其中包含您的域名和应用服务器代理。
第二步 – 配置您的服务器块
建议的做法是为新的服务器块创建一个自定义配置文件,而不是直接编辑默认配置。使用nano或您喜欢的文本编辑器创建并打开一个新的Nginx配置文件。
- sudo nano /etc/nginx/sites-available/your_domain
将以下内容插入到您的新文件中,确保将”your_domain”和”app_server_address”替换为正确的值。如果您没有应用服务器进行测试,请在第3步的可选Gunicorn服务器设置中使用http://127.0.0.1:8000作为默认值。
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location / {
proxy_pass app_server_address;
include proxy_params;
}
}
保存并退出,使用nano可以通过按下CTRL+O然后CTRL+X来完成。
此配置文件以标准的Nginx设置开始,其中Nginx将监听端口80,并响应对your_domain和www.your_domain的请求。通过Nginx的proxy_pass指令启用反向代理功能。通过这个配置,通过本地Web浏览器导航到your_domain将与在远程机器上打开app_server_address相同。虽然本教程只会代理一个应用服务器,但Nginx能够同时为多个服务器充当代理。通过根据需要添加更多的location块,一个单一的服务器名称可以通过代理将多个应用服务器组合成一个统一的Web应用。
所有的HTTP请求都带有头部,其中包含有关发送请求的客户端的信息。这些信息包括IP地址、缓存偏好、Cookie跟踪、授权状态等等。Nginx提供了一些推荐的头部转发设置,你可以将其包含在代理参数(proxy_params)中,并可以在/etc/nginx/proxy_params中找到具体的细节。
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
通过反向代理,您的目标是传递有关客户端的相关信息,有时还包括有关反向代理服务器自身的信息。在某些情况下,代理服务器可能希望了解哪个反向代理服务器处理了该请求,但通常重要信息来自原始客户端的请求。为了传递这些标头并使信息可在预期位置使用,Nginx使用了proxy_set_header
指令。
默认情况下,当Nginx充当反向代理时,它会修改两个头部,删除所有空的头部,然后传递请求。修改的两个头部是Host
和Connection
头部。有许多可用的HTTP头部,您可以查阅此详细的HTTP头部列表以了解每个头部的用途,尽管后面我们会介绍与反向代理相关的头部。
这里是由proxy_params转发的标题以及它所存储数据的变量:
- Host:此头部包含客户端请求的原始主机,即网站域名和端口。Nginx将其保存在
$http_host
变量中。 - X-Forwarded-For:此头部包含发送原始请求的客户端的IP地址。它还可以包含一个IP地址列表,其中首先是原始客户端IP,然后是传递请求的所有反向代理服务器的IP地址。Nginx将其保存在
$proxy_add_x_forwarded_for
变量中。 - X-Real-IP:此头部始终包含属于远程客户端的单个IP地址。这与可以包含地址列表的类似头部X-Forwarded-For不同。如果X-Forwarded-For不存在,它将与X-Real-IP相同。
- X-Forwarded-Proto:此头部包含原始客户端用于连接的协议,无论是HTTP还是HTTPS。Nginx将其保存在
$scheme
变量中。
接下来,通过创建一个链接将此配置文件启用,连接到Nginx在启动时读取的sites-enabled目录。
- sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
你现在可以测试你的配置文件是否有语法错误了。
- sudo nginx -t
没有报告任何问题,请重新启动Nginx以应用您的更改。
- sudo systemctl restart nginx
如果您的应用程序服务器正在运行,那么现在已将Nginx配置为您的反向代理,您可以通过本地浏览器访问它。如果您计划使用的应用程序服务器尚未运行,您可以继续启动您计划使用的应用程序服务器。您可以忽略本教程的其余部分。
否则,继续进行下一步操作,使用Gunicorn建立一个测试应用程序和服务器。
第三步 – 使用Gunicorn进行反向代理测试(可选)
如果您在开始本教程之前已经准备好并运行使用的应用服务器,现在可以在您的浏览器中访问它了。
your_domain
然而,如果您手头没有应用服务器来测试您的反向代理,您可以按照以下步骤安装Gunicorn以及一个测试应用程序。Gunicorn是一个常与Nginx反向代理配对使用的Python WSGI服务器。
更新您的apt存储库索引并安装gunicorn。
- sudo apt update
- sudo apt install gunicorn
接下来,你将编写一个Python函数,以HTTP响应的形式返回”Hello World!”,并在Web浏览器中显示。可以使用nano或你喜欢的文本编辑器来创建test.py。
- nano test.py
将以下Python代码插入到文件中:
def app(environ, start_response):
start_response("200 OK", [])
return iter([b"Hello, World!"])
以下是Gunicorn所需的最低限度代码,用于启动一个HTTP响应,将一串文本呈现在您的网络浏览器中。在审查完代码后,保存并关闭文件。
现在开始启动你的Gunicorn服务器,指定测试Python模块和其中的app函数。启动服务器将接管你的终端。
- gunicorn –workers=2 test:app
[2022-08-29 07:09:29 +0000] [10568] [INFO] Starting gunicorn 20.1.0 [2022-08-29 07:09:29 +0000] [10568] [INFO] Listening at: http://127.0.0.1:8000 (10568) [2022-08-29 07:09:29 +0000] [10568] [INFO] Using worker: sync [2022-08-29 07:09:29 +0000] [10569] [INFO] Booting worker with pid: 10569 [2022-08-29 07:09:29 +0000] [10570] [INFO] Booting worker with pid: 10570
输出确认Gunicorn正在监听默认地址http://127.0.0.1:8000。这是您之前在Nginx配置中设置的代理地址。如果没有,请返回到/etc/nginx/sites-available/your_domain文件并编辑与proxy_pass指令相关联的app_server_address。
打开你的网络浏览器并导航到你使用Nginx设置的域名。
your_domain
你的 Nginx 反向代理现在正在服务于你的 Gunicorn 网络应用服务器,并显示”你好,世界!”。
结论
通过本教程,您已将Nginx配置为反向代理,以便访问您的应用服务器,否则这些服务器只能在本地访问。此外,您还配置了请求头转发,将客户端的头部信息传递给应用服务器。
要查看使用Nginx作为反向代理的完整解决方案示例,请看一下在Ubuntu 22.04上如何使用Gunicorn和Nginx来提供Flask应用程序,或者如何在Ubuntu 22.04上使用InstantSearch运行Meilisearch前端。