介绍
Apache 和 Nginx 是常用 PHP 的两种流行的开源 Web 服务器,在托管具有不同要求的多个网站时,在相同的虚拟机上运行它们可以是有用的。
具有 IPv4 和 IPv6 地址的 dropplets 可以配置为在一个协议上的 Apache 站点和在另一个协议上的 Nginx 站点提供服务,但这目前并不实用,因为 ISP 的 IPv6 采用仍然不普遍。为第二个 Web 服务器提供不同的端口号,如 81 或
8080 是另一个解决方案,但与端口号共享 URL(如 http://example.com:81
)并不总是合理或理想的。
本教程将向您展示如何将 Nginx 配置为 Web 服务器和 Apache 的反向代理服务器 - 所有在一个 Droplet 上。 根据 Web 应用程序,可能需要对代码进行更改,以保持 Apache 反向代理服务器的警惕,特别是当配置 SSL 站点时。
我们将在一个Droplet上托管四个域名,其中两个将由Nginx提供服务:‘example.com’(默认虚拟主机)和‘sample.org’.其余两个,‘foobar.net’和‘test.io’,将由Apache提供服务。
前提条件
- 一个新的Ubuntu 16.04 Droplet。
- 具有`sudo'权限的标准用户账户。 您可以通过遵循 [初始服务器设置与 Ubuntu 16.04] (https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-16-04) 的步骤2和步骤3来建立标准账户.
- 联合国 想要的域名应该指向您Droplet在 DigitalOcean 控制面板上的IP地址. 请参看如何用数字海洋设置主机名的第3步,以说明如何这样做。 如果您将域名 DNS 设置在其它位置, 您应该在那里创建相应的 A 记录 。 .
可选参考
本教程需要对Apache和Nginx中的虚拟主机的基本知识,以及SSL证书的创建和配置。
- 在 Apache 上设置虚拟主机 * 在 Nginx 上设置虚拟主机 * (https://andsky.com/tech/tutorials/how-to-set-up-multiple-ssl-certificates-on-one-ip-with-nginx-on-ubuntu-124)
第1步:安装Apache和PHP-FPM
除了Apache和PHP-FPM之外,我们还必须安装PHP FastCGI Apache模块,该模块被命名为libapache2-mod-fastcgi。
首先,更新 apt 存储库,以确保您有最新的包。
1sudo apt-get update
接下来,安装必要的包:
1sudo apt-get install apache2 libapache2-mod-fastcgi php-fpm
接下来,让我们更改Apache的默认配置。
第2步:配置Apache和PHP-FPM
在此步骤中,我们将更改Apache的端口号为8080并将其配置为使用mod_fastcgi模块与PHP-FPM合作,编辑Apache配置文件并更改Apache的端口号。
1sudo nano /etc/apache2/ports.conf
找下面的线条:
1Listen 80
把它改成:
1Listen 8080
保存并退出ports.conf
。
注意:网页服务器在配置反向代理时通常会听127.0.0.1:8080
,但这样做会将PHP的环境变量 SERVER_ADDR 的值设置为反向IP地址,而不是服务器的公共IP。
接下来,我们将编辑Apache的默认虚拟主机文件. 该文件中的<VirtualHost>
指令设置为仅在端口80
上服务网站,所以我们还必须改变这一点。
1sudo nano /etc/apache2/sites-available/000-default.conf
第一行应该是:
1<VirtualHost *:80>
把它改成:
1<VirtualHost *:8080>
保存文件并重新加载Apache。
1sudo systemctl reload apache2
检查Apache是否正在听8080
。
1sudo netstat -tlpn
输出应该看起来像下面的例子,用 apache2 听到** :::8080** 。
1Active Internet connections (only servers)
2Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
3tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1086/sshd
4tcp6 0 0 :::8080 :::* LISTEN 4678/apache2
5tcp6 0 0 :::22 :::* LISTEN 1086/sshd
一旦您确认Apache在正确的端口上收听,您可以配置对PHP和FastCGI的支持。
步骤 3 — 配置 Apache 以使用 mod_fastcgi
Apache 默认情况下使用mod_php
来服务 PHP 页面,但需要额外的配置来使用 PHP-FPM。
<$>[注] 注 :如果您在使用mod_php的现有LAMP安装上尝试此教程,请先用: <$>
1sudo a2dismod php7.0
我们将为mod_fastcgi
添加一个配置块,这取决于mod_action
。
1sudo a2enmod actions
这些配置指令将对.php 文件的请求传送到 PHP-FPM UNIX 接口。
1sudo nano /etc/apache2/mods-enabled/fastcgi.conf
在该块中的现有项目下面,在<IfModule mod_fastcgi.c>... </IfModule>
块中添加以下行:
1AddType application/x-httpd-fastphp .php
2 Action application/x-httpd-fastphp /php-fcgi
3 Alias /php-fcgi /usr/lib/cgi-bin/php-fcgi
4 FastCgiExternalServer /usr/lib/cgi-bin/php-fcgi -socket /run/php/php7.0-fpm.sock -pass-header Authorization
5 <Directory /usr/lib/cgi-bin>
6 Require all granted
7 </Directory>
将您所做的更改保存到fastcgi.conf
,并进行配置测试。
1sudo apachectl -t
如果您看到警告无法使用 127.0.1.1 可靠地确定服务器的完全合格域名
,则将ServerName
指令设置在全球范围内以抑制此消息,这没问题。
1sudo systemctl reload apache2
现在让我们确保我们可以从Apache服务PHP。
第4步:验证PHP功能
检查PHP是否通过创建一个phpinfo()
文件并从您的Web浏览器访问它。
1echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php
要在浏览器中查看该文件,请访问 http://your_ip_address:8080/info.php。这将为您提供使用的 PHP 配置设置列表。
在页面顶部,检查 Server API 说** FPM/FastCGI** . 页面下方约三分之二的路径,** PHP变量** 部分会告诉你** SERVER_SOFTWARE** 是Ubuntu上的Apache. 这些证实mod_fastcgi
是活跃的,而Apache正在使用PHP-FPM来处理PHP文件。
第5步:为Apache创建虚拟主机
让我们为域名foobar.net
和test.io
创建Apache虚拟主机文件,以便做到这一点,我们首先将为两个网站创建文档根目录,并在这些目录中放置一些默认文件,以便我们可以轻松地测试我们的配置。
首先,创建根目录:
1sudo mkdir -v /var/www/{foobar.net,test.io}
然后为每个网站创建一个索引
文件。
1echo "<h1 style='color: green;'>Foo Bar</h1>" | sudo tee /var/www/foobar.net/index.html
1echo "<h1 style='color: red;'>Test IO</h1>" | sudo tee /var/www/test.io/index.html
然后为每个网站创建一个phpinfo()
文件,以便我们可以测试PHP是否正确配置。
1echo "<?php phpinfo(); ?>" | sudo tee /var/www/foobar.net/info.php
1echo "<?php phpinfo(); ?>" | sudo tee /var/www/test.io/info.php
现在为foobar.net
域创建虚拟主机文件。
1sudo nano /etc/apache2/sites-available/foobar.net.conf
将下列指令放入新文件中:
1<VirtualHost *:8080>
2 ServerName foobar.net
3 ServerAlias www.foobar.net
4 DocumentRoot /var/www/foobar.net
5 <Directory /var/www/foobar.net>
6 AllowOverride All
7 </Directory>
8</VirtualHost>
<$>[注] 注: AllowOverride All
启用了 .htaccess
支持。
对于在 Apache 中设置虚拟主机的完整指南,请参阅 如何在 Ubuntu 16.04 上设置 Apache 虚拟主机。
保存并关闭文件,然后为「test.io」创建类似的配置。
1sudo nano /etc/apache2/sites-available/test.io.conf
1<VirtualHost *:8080>
2 ServerName test.io
3 ServerAlias www.test.io
4 DocumentRoot /var/www/test.io
5 <Directory /var/www/test.io>
6 AllowOverride All
7 </Directory>
8</VirtualHost>
现在两个Apache虚拟主机已设置,使用a2ensite
命令启用网站,从而在sites-enabled
目录中创建一个符号链接到虚拟主机文件。
1sudo a2ensite foobar.net
1sudo a2ensite test.io
再次检查 Apache 对配置错误。
1sudo apachectl -t
如果显示了 Syntax OK ,请重新加载 Apache。
1sudo systemctl reload apache2
要确认网站正在工作,请在浏览器中打开http://foobar.net:8080
和http://test.io:8080
并检查每个网站是否显示其 index.html 文件。
你应该看到以下结果:
此外,请检查 PHP 是否正在运行,访问每个网站的 info.php 文件,请访问浏览器中的 http://foobar.net:8080/info.php
和 http://test.io:8080/info.php
。
您应该在每个网站上看到相同的PHP配置规格列表,就像您在步骤4中看到的那样。
第6步:安装和配置 Nginx
在此步骤中,我们将安装 Nginx,并将域名) on Ubuntu 16.04](https://andsky.com/tech/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04)。
使用包管理器安装 Nginx。
1sudo apt-get install nginx
然后删除默认虚拟主机的simlink,因为我们将不再使用它,我们将稍后创建自己的默认网站(‘example.com’)。
1sudo rm /etc/nginx/sites-enabled/default
现在我们将使用我们在Apache中使用的相同程序为 Nginx创建虚拟主机,首先为两个网站创建文档根目录:
1sudo mkdir -v /usr/share/nginx/{example.com,sample.org}
与Apache的虚拟主机一样,我们将在安装完成后再次创建)`文件进行测试。
1echo "<h1 style='color: green;'>Example.com</h1>" | sudo tee /usr/share/nginx/example.com/index.html
1echo "<h1 style='color: red;'>Sample.org</h1>" | sudo tee /usr/share/nginx/sample.org/index.html
1echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/example.com/info.php
1echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/sample.org/info.php
现在为域名example.com
创建一个虚拟主机文件。
1sudo nano /etc/nginx/sites-available/example.com
Nginx 将配置文件中的服务器 {... }
区域称为服务器块 **. 为主要虚拟主机, example.com 创建服务器块.
默认_服务器` 配置指令使其成为默认的虚拟主机,它处理不匹配任何其他虚拟主机的 HTTP 请求。
将以下内容粘贴到 example.com 文件中:
1server {
2 listen 80 default_server;
3
4 root /usr/share/nginx/example.com;
5 index index.php index.html index.htm;
6
7 server_name example.com www.example.com;
8 location / {
9 try_files $uri $uri/ /index.php;
10 }
11
12 location ~ \.php$ {
13 fastcgi_pass unix:/run/php/php7.0-fpm.sock;
14 include snippets/fastcgi-php.conf;
15 }
16}
现在,为 Nginx 的第二个域名,‘sample.org’创建一个虚拟主机文件。
1sudo nano /etc/nginx/sites-available/sample.org
sample.org 的服务器块应该是这样的:
1server {
2 root /usr/share/nginx/sample.org;
3 index index.php index.html index.htm;
4
5 server_name sample.org www.sample.org;
6 location / {
7 try_files $uri $uri/ /index.php;
8 }
9
10 location ~ \.php$ {
11 fastcgi_pass unix:/run/php/php7.0-fpm.sock;
12 include snippets/fastcgi-php.conf;
13 }
14}
保存和关闭文件. 然后通过创建网站启用
目录的象征链接来启用两个网站。
1sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
1sudo ln -s /etc/nginx/sites-available/sample.org /etc/nginx/sites-enabled/sample.org
使用 Nginx 配置测试:
1sudo nginx -t
然后重新加载 Nginx 如果显示了 OK 。
1sudo systemctl reload nginx
现在,访问您的 Nginx 虚拟主机的 phpinfo()
文件,通过访问 http://example.com/info.php
和 http://sample.org/info.php
。
SERVER_SOFTWARE
应该说nginx
,表示这些文件是由 Nginx 直接提供的。
在此时刻,我们已经安装了 Nginx 并创建了两个虚拟主机,接下来我们将配置 Nginx 来为在 Apache 上托管的域名提供代理请求。
第7步:为Apache的虚拟主机配置 Nginx
让我们在server_name
指令中创建一个额外的 Nginx 虚拟主机,其中包含多个域名。
创建一个新的 Nginx 虚拟主机文件:
1sudo nano /etc/nginx/sites-available/apache
添加下面的代码块. 这将指定两个Apache虚拟主机域的名称,并向Apache代理他们的请求. 请记住在proxy_pass
中使用公共IP地址。
1server {
2 listen 80;
3 server_name foobar.net www.foobar.net test.io www.test.io;
4
5 location / {
6 proxy_pass http://your_server_ip:8080;
7 proxy_set_header Host $host;
8 proxy_set_header X-Real-IP $remote_addr;
9 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
10 proxy_set_header X-Forwarded-Proto $scheme;
11 }
12}
保存文件并通过创建象征链接启用这个新的虚拟主机。
1sudo ln -s /etc/nginx/sites-available/apache /etc/nginx/sites-enabled/apache
进行配置测试:
1sudo nginx -t
重新加载 Nginx 如果显示了 OK 。
1sudo systemctl reload nginx
打开浏览器并访问您的浏览器中的 URL http://foobar.net/info.php
. 向下滚动到 PHP 变量 部分并检查显示的值。
变量 SERVER_SOFTWARE 和** DOCUMENT_ROOT** 证实该请求由 Apache 处理。 变量** HTTP_X_REAL_IP** 和** HTTP_X_FORWARDED_FOR** 由 Nginx 添加,应该显示您正在使用的计算机的公共 IP 地址以访问 URL。
我们已经成功设置了 Nginx 来向 Apache 提供特定域的代理请求,接下来,让我们将 Apache 配置为将REMOTE_ADDR
变量设置为直接处理这些请求。
第8步:安装和配置mod_rpaf
在此步骤中,我们将安装一个名为 mod_rpaf 的Apache模块,该模块会根据反向代理提供的值重新编写** REMOTE_ADDR** 、** HTTPS** 和** HTTP_PORT** 的值。如果没有这个模块,一些PHP应用程序将需要代码更改,以便从代理程序后面无缝工作。
安装构建模块所需的包:
1sudo apt-get install unzip build-essential apache2-dev
从GitHub下载最新稳定版本。
1wget https://github.com/gnif/mod_rpaf/archive/stable.zip
用它提取:
1unzip stable.zip
转到工作目录。
1cd mod_rpaf-stable
然后编译并安装模块。
1make
1sudo make install
在mods-available
目录中创建一个文件,其中加载 rpaf 模块。
1sudo nano /etc/apache2/mods-available/rpaf.load
将以下行添加到文件中:
1LoadModule rpaf_module /usr/lib/apache2/modules/mod_rpaf.so
在此目录中创建另一个文件. 这将包含配置指令。
1sudo nano /etc/apache2/mods-available/rpaf.conf
添加以下代码块,确保添加您的Droplet的IP地址。
1<IfModule mod_rpaf.c>
2 RPAF_Enable On
3 RPAF_Header X-Real-Ip
4 RPAF_ProxyIPs your_server_ip
5 RPAF_SetHostName On
6 RPAF_SetHTTPS On
7 RPAF_SetPort On
8</IfModule>
请参阅)以获得更多信息。
RPAF_Header - 用于客户端真实 IP 地址的标题.* RPAF_ProxyIPs* - 调节 HTTP 请求的代理 IP.** RPAF_SetHostName* - 更新 vhost 名称以便 ServerName 和 ServerAlias 工作.** RPAF_SetHTTPS* - 根据 X-Forwarded-Proto
中包含的值设置 HTTPS
环境变量.** RPAF_SetPort* - 设置 SERVER_PORT
环境变量。
保存rpaf.conf
并启用该模块。
1sudo a2enmod rpaf
这将创建mods-enabled
目录中的rpaf.load
和rpaf.conf
文件的符号链接。
1sudo apachectl -t
如果返回了 Syntax OK ,请重新加载 Apache。
1sudo systemctl reload apache2
在您的浏览器中访问 Apache 网站的 phpinfo()
页面,并检查 PHP 变量 部分。
第9步:设置HTTPS网站(可选)
在此步骤中,我们将为在Apache上托管的两个域配置SSL证书。 Nginx支持SSL终止,因此我们可以设置SSL而不修改Apache的配置文件。
创建SSL证书及其私钥的目录。
1sudo mkdir /etc/nginx/ssl
对于本文,我们将使用自签名的SSL证书,有效期为10年,为foobar.net
和test.io
生成自签证书。
1sudo openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/foobar.net-key.pem -out /etc/nginx/ssl/foobar.net-cert.pem -days 3650 -nodes
1sudo openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/test.io-key.pem -out /etc/nginx/ssl/test.io-cert.pem -days 3650 -nodes
每次,您将被要求提供证书识别详细信息. 每次输入共同名称
的适当域名。
1Country Name (2 letter code) [AU]:US
2State or Province Name (full name) [Some-State]:New York
3Locality Name (eg, city) []:New York City
4Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean Inc
5Organizational Unit Name (eg, section) []:
6Common Name (e.g. server FQDN or YOUR name) []:foobar.net
7Email Address []:
现在打开从 Nginx 到 Apache 的请求代理的 Apache 虚拟主机文件。
1sudo nano /etc/nginx/sites-available/apache
由于我们为每个域都有单独的证书和密钥,所以我们需要为每个域设置单独的服务器 {... }
块。
1server {
2 listen 80;
3 listen 443 ssl;
4 server_name test.io www.test.io;
5
6 ssl on;
7 ssl_certificate /etc/nginx/ssl/test.io-cert.pem;
8 ssl_certificate_key /etc/nginx/ssl/test.io-key.pem;
9
10 location / {
11 proxy_pass http://your_server_ip:8080;
12 proxy_set_header Host $host;
13 proxy_set_header X-Real-IP $remote_addr;
14 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
15 proxy_set_header X-Forwarded-Proto $scheme;
16 }
17}
18
19server {
20 listen 80;
21 listen 443 ssl;
22 server_name foobar.net www.foobar.net;
23
24 ssl on;
25 ssl_certificate /etc/nginx/ssl/foobar.net-cert.pem;
26 ssl_certificate_key /etc/nginx/ssl/foobar.net-key.pem;
27
28 location / {
29 proxy_pass http://your_server_ip:8080;
30 proxy_set_header Host $host;
31 proxy_set_header X-Real-IP $remote_addr;
32 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33 proxy_set_header X-Forwarded-Proto $scheme;
34 }
35}
我们将原始服务器块分成两个单独的块,并告诉 Nginx 倾听 443 端口,这是安全网站的默认端口。
保存文件并执行配置测试。
1sudo nginx -t
如果测试成功,重新加载 Nginx。
1sudo systemctl reload nginx
现在,请在浏览器中使用https://
前缀访问Apache的域名之一。 首先,请访问https://foobar.net/info.php
,您将看到以下内容:
<$>[注意]我们为本教程使用了自签证书,因此浏览器可能会警告我们,连接可能不值得信任。
请参阅 PHP 变量 部分,变量** SERVER_PORT** 已设置为** 443** 和** HTTPS** 设置为** on** ,就好像 Apache 是通过 HTTPS 直接访问的。
步骤 10 — 阻止直接访问 Apache (可选)
由于Apache在公共IP地址上的端口8080
上倾听,所以它可以被所有人访问,可以通过在您的防火墙规则集中使用以下IPtables命令来阻止它。
1sudo iptables -I INPUT -p tcp --dport 8080 ! -s your_server_ip -j REJECT --reject-with tcp-reset
请确保使用您的 Droplet 的 IP 地址,而不是红色示例。一旦您的防火墙封锁了端口 8080,请测试它是否无法访问 Apache. 打开您的 Web 浏览器,并尝试在端口
80 上访问 Apache 的一个域名。
浏览器应该显示无法连接
或网页不可用
错误消息. IPtables的tcp-reset
选项可用,外部用户不会看到端口8080
和没有任何服务的端口之间的差异。
注意: IPtables 规则不会默认的系统重新启动。 保存 IPtables 规则的方法有很多,但最简单的是在 Ubuntu 存储库中使用 iptables-persistent
。 探索 这篇文章 了解如何配置 IPTables 的更多信息。
步骤 11 — 使用 Nginx 服务静态文件(可选)
当 Nginx 代理人请求 Apache 域时,它会将该域的每个文件请求发送给 Apache. Nginx 在服务像图像、JavaScript 和风格表等静态文件方面比 Apache 更快。
首先打开apache
虚拟主机文件。
1sudo nano /etc/nginx/sites-available/apache
您需要为每个服务器块添加两个额外的位置块,并修改现有的位置块(如果您从上一步中只有一个服务器块,您可以完全更换文件的内容,以便它匹配下面的内容)。
1server {
2 listen 80;
3 server_name test.io www.test.io;
4 root /var/www/test.io;
5 index index.php index.htm index.html;
6
7 location / {
8 try_files $uri $uri/ /index.php;
9 }
10
11 location ~ \.php$ {
12 proxy_pass http://your_ip_address:8080;
13 proxy_set_header Host $host;
14 proxy_set_header X-Real-IP $remote_addr;
15 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16 proxy_set_header X-Forwarded-Proto $scheme;
17 }
18
19 location ~ /\. {
20 deny all;
21 }
22}
23
24server {
25 listen 80;
26 server_name foobar.net www.foobar.net;
27 root /var/www/foobar.net;
28 index index.php index.htm index.html;
29
30 location / {
31 try_files $uri $uri/ /index.php;
32 }
33
34 location ~ \.php$ {
35 proxy_pass http://your_ip_address:8080;
36 proxy_set_header Host $host;
37 proxy_set_header X-Real-IP $remote_addr;
38 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
39 proxy_set_header X-Forwarded-Proto $scheme;
40 }
41
42 location ~ /\. {
43 deny all;
44 }
45}
如果您也希望 HTTPS 可用,请从步骤 9 保存听 443 ssl;
行和其他 SSL 设置。
「try_files」指令使 Nginx 在文档根中搜索文件并直接服务它们. 如果文件具有 `.php' 扩展,请求将传递给 Apache. 即使在文档根中没有找到文件,请求也会传递给 Apache,以便应用程序功能如 permalinks 无问题地工作。
警告:位置
指令非常重要,这防止 Nginx 打印包含敏感信息的文件内容,如.htaccess
和.htpasswd
。
保存文件并执行配置测试。
1sudo nginx -t
如果测试成功,重新加载 Nginx。
1sudo service nginx reload
要验证这是有效的,你可以检查Apache在/var/log/apache2
中的日志文件,并查看info.php
和foobar.net
的info.php
文件的GET请求。
1sudo tail -f /var/log/apache2/other_vhosts_access.log
访问您的浏览器中的http://test.io/info.php,然后从日志中查看输出,您会看到Apache确实在响应:
1test.io:80 your_server_ip - - [01/Jul/2016:18:18:34 -0400] "GET /info.php HTTP/1.0" 200 20414 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36"
然后访问每个网站的index.html
页面,你不会看到任何来自Apache的日志条目。
当您完成观察日志文件时,请按CTRL+C
以停止尾声。
此设置的唯一警告是,Apache无法限制对静态文件的访问,静态文件的访问控制需要在Nginx的apache
虚拟主机文件中进行配置。
结论
现在你有一个 Ubuntu Droplet 与 Nginx 服务的example.com
和sample.org
,以及 Apache 服务的foobar.net
和test.io
。虽然 Nginx 是 Apache 的反向代理,但 Nginx 的代理服务是透明的,并且连接到 Apache 域似乎是直接从 Apache 服务的。