如何在一个 Ubuntu 14.04 Droplet 上将 Nginx 配置为 Web 服务器和 Apache 的反向代理

介绍

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提供服务。

前提条件

可选参考

本教程需要对Apache和Nginx中的虚拟主机的基本知识,以及SSL证书的创建和配置。

第1步:安装Apache和PHP5-FPM

除了Apache和PHP-FPM之外,我们还必须安装PHP FastCGI Apache模块,这是libapache2-mod-fastcgi,可在Ubuntu的 multiverse 存储库中使用,首先必须在sources.list文件中启用。

1sudo nano /etc/apt/sources.list

查找下面的行,并通过在开始时删除哈希符号(# )来消除评论。

1# deb http://mirrors.digitalocean.com/ubuntu trusty multiverse
2
3 . . .
4
5# deb http://mirrors.digitalocean.com/ubuntu trusty-updates multiverse

这应该留给你下面所示的东西。

1deb http://mirrors.digitalocean.com/ubuntu trusty multiverse
2
3 . . .
4
5 deb http://mirrors.digitalocean.com/ubuntu trusty-updates multiverse

保存文件并更新 apt 存储库。

1sudo apt-get update

然后安装必要的包。

1sudo apt-get install apache2 libapache2-mod-fastcgi php5-fpm

第2步:配置Apache和PHP5-FPM

在此步骤中,我们将更改Apache的端口号为8080,并使用mod_fastcgi模块将其配置为PHP5-FPM。

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 service apache2 reload

检查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

步骤 3 — 配置 Apache 以使用 mod_fastcgi

Apache 默认情况下使用mod_php,但需要额外的配置才能使用 PHP5-FPM。

注意: 如果您正在尝试使用mod_php在现有LAMP安装上使用此教程,请先禁用它: > ``` > sudo a2dismod php5 > ``

我们将为mod_fastcgi添加一个配置块,这取决于mod_action

1sudo a2enmod actions

找出在您的 Droplet 上安装了哪些版本的 Apache:

1sudo apache2 -v

相应地编辑fastcgi配置文件,这些配置指令将对.php文件的请求传送到PHP5-FPM UNIX插槽。

1sudo nano /etc/apache2/mods-enabled/fastcgi.conf

将下列行添加到IfModule mod_fastcgi.c>... </IfModule>块的底部为Apache 2.4**:

1AddType application/x-httpd-fastphp5 .php
2 Action application/x-httpd-fastphp5 /php5-fcgi
3 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
4 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
5 <Directory /usr/lib/cgi-bin>
6  Require all granted
7 </Directory>

Apache 2.2 不需要<目录>部分,所以添加以下内容:

1AddType application/x-httpd-fastphp5 .php
2 Action application/x-httpd-fastphp5 /php5-fcgi
3 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
4 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

在「fastcgi.conf」中完成后,进行配置测试。

1sudo apachectl -t

如果您看到警告无法使用 127.0.1.1 可靠地确定服务器的完全合格域名,则将ServerName指令设置在全球范围内以抑制此消息,这没问题。

1sudo service apache2 reload

第4步:验证PHP功能

检查PHP是否通过创建一个phpinfo()文件并从您的Web浏览器访问它。

1echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php

要在浏览器中查看该文件,请访问 http://111.111.111.111.111:8080/info.php,但使用您的 Droplet 的 IP 地址。

phpinfo Server API

phpinfo PHP Variables

在页面顶部,检查 Server API 说** FPM/FastCGI** . 页面下方约三分之二的路径,** PHP变量** 部分会告诉你** SERVER_SOFTWARE** 是Ubuntu上的Apache. 这些证实mod_fastcgi是活跃的,而Apache正在使用PHP5-FPM来处理PHP文件。

第5步:为Apache创建虚拟主机

我们将为域名foobar.nettest.io创建两个Apache虚拟主机文件,这开始于为两个网站创建 _document root_目录。

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()文件。

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 *:*>
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>

保存并关闭文件. 然后对 test.io 做同样的事情。

1sudo nano /etc/apache2/sites-available/test.io.conf
1<VirtualHost *:*>
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>

注1: AllowOverride All启用了.htaccess支持。

注2: 这些只是最基本的指南. 有关在 Apache 中设置虚拟主机的完整指南,请参阅 如何在 Ubuntu 14.04 LTS 上设置 Apache 虚拟主机

现在两个Apache虚拟主机已设置,使用a2ensite命令启用网站,从而在sites-enabled目录中创建一个符号链接到虚拟主机文件。

1sudo a2ensite foobar.net
1sudo a2ensite test.io

再次检查 Apache 对配置错误。

1sudo apachectl -t

重新加载,如果显示了 Syntax OK

1sudo service apache2 reload

要确认网站正在工作,请在浏览器中打开http://foobar.net:8080http://test.io:8080并验证它们是否显示其 index.html 文件。

你应该看到:

foobar.net index page

test.io index page

此外,通过访问 info.php 文件来检查 PHP 是否正在工作: http://foobar.net:8080/info.phphttp://test.io:8080/info.php

您应该在每个网站上看到相同的PHP配置规格列表,就像您在步骤1中看到的那样。

第6步:安装和配置 Nginx

在此步骤中,我们将安装 Nginx,并将域名) on Ubuntu 14.04 LTS](https://andsky.com/tech/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts)。

安装 Nginx。

1sudo apt-get install nginx

然后删除默认虚拟主机的 symlink。

1sudo rm /etc/nginx/sites-enabled/default

现在我们将为 Nginx 创建虚拟主机. 首先为两个网站创建 document root 目录:

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    	try_files $uri =404;
14    	fastcgi_pass unix:/var/run/php5-fpm.sock;
15    	fastcgi_index index.php;
16    	include fastcgi_params;
17    }
18}

现在,为 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    	try_files $uri =404;
12    	fastcgi_pass unix:/var/run/php5-fpm.sock;
13    	fastcgi_index index.php;
14    	include fastcgi_params;
15    }
16}

保存和关闭文件. 然后通过创建网站启用目录的象征链接来启用两个网站。

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 service nginx configtest

然后重新加载 Nginx 如果显示了 OK

1sudo service nginx reload

现在,您可以在网页浏览器中访问您的 Nginx 虚拟主机的 phpinfo() 文件,通过 http://example.com/info.phphttp://sample.org/info.php

Nginx PHP Variables

SERVER_SOFTWARE 应该说** nginx** ,表示这些文件是由Nginx直接提供的。** DOCUMENT_ROOT** 应该指向您在此步骤中早些时候为每个Nginx网站创建的目录。

在此时刻,我们已经安装了 Nginx 并创建了两个虚拟主机,接下来我们将设置一个额外的虚拟主机来为在 Apache 上托管的域名提供代理请求。

第7步:为Apache的虚拟主机配置 Nginx

在本节中,我们将创建一个额外的 Nginx 虚拟主机,在server_name指令中使用多个域名。

创建一个新的 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://111.111.111.111: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 service nginx configtest

重新加载 Nginx 如果显示了 OK

1sudo service nginx reload

打开浏览器,在Apache的域名中访问http://foobar.net/info.php

phpinfo of Apache via Nginx

变量 SERVER_SOFTWARE 和** DOCUMENT_ROOT** 应该确认这个请求是由 Apache 处理的. 变量** HTTP_X_REAL_IP** 和** HTTP_X_FORWARDED_FOR** 由 Nginx 添加,应该显示您在浏览器中访问 URL 的计算机的公共 IP 地址。

我们已经成功设置了 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-threaded-dev

从GitHub下载最新稳定版本。

1wget https://github.com/gnif/mod_rpaf/archive/stable.zip

用它提取:

1unzip stable.zip

转到工作目录。

1cd mod_rpaf-stable

然后编译并安装模块。

1sudo make
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 111.111.111.111
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.loadrpaf.conf文件的符号链接。

1sudo apachectl -t

如果返回了 Syntax OK ,请重新加载 Apache。

1sudo service apache2 reload

在您的浏览器上访问 Apache 网站的 phpinfo() 页面,并检查 PHP 变量 部分.** REMOTE_ADDR** 变量现在也将是您本地计算机的公共 IP 地址。

第9步:设置HTTPS网站(可选)

在此步骤中,我们将为在Apache上托管的两个域配置SSL证书。 Nginx支持SSL终止,因此我们可以设置SSL而不修改Apache的配置文件。

创建SSL证书及其私钥的目录。

1sudo mkdir /etc/nginx/ssl

对于本文,我们将使用自签名的SSL证书,有效期为10年,为foobar.nettest.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) []:example.com
7Email Address []:

现在打开apache虚拟主机文件,该文件向 Nginx 向 Apache 传输请求。

1sudo nano /etc/nginx/sites-available/apache

由于我们为每个域都有单独的证书和密钥,我们需要为每个域拥有单独的服务器 {... } 块,您应该删除当前的内容,完成后,您的apachevhost 文件应该看起来像下面。

 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://111.111.111.111: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://111.111.111.111: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}

保存文件并执行配置测试。

1sudo service nginx configtest

如果测试成功,重新加载 Nginx。

1sudo service nginx reload

通过浏览器访问 Apache 的一个域名,使用前缀 https://: https://foobar.net/info.php

phpinfo ssl

请参阅 PHP 变量 部分,变量** SERVER_PORT** 已设置为** 443** 和** HTTPS** 设置为** on** ,就好像 Apache 是通过 HTTPS 直接访问的。

步骤 10 — 阻止直接访问 Apache (可选)

由于Apache在公共IP地址上的端口8080上倾听,所以它可以被所有人访问,可以通过在您的防火墙规则集中使用以下IPtables命令来阻止它。

1sudo iptables -I INPUT -p tcp --dport 8080 ! -s 111.111.111.111 -j REJECT --reject-with tcp-reset

请确保使用您的 Droplet 的 IP 地址,而不是红色示例。一旦您的防火墙封锁了端口 8080,请测试它是否无法访问 Apache. 打开您的 Web 浏览器并尝试在端口 80 上访问 Apache 的一个域名。

浏览器应该显示无法连接网页不可用错误消息. IPtables的tcp-reset选项可用,外部用户不会看到端口8080和没有任何服务的端口之间的差异。

注: IPtables 规则无法默认地重新启动系统,有几种方法可以保存 IPtables 规则,但最简单的方法是在 Ubuntu 的存储库中使用iptables-persistent

步骤 11 — 使用 Nginx 服务静态文件(可选)

当 Nginx 代理人请求 Apache 域时,它会将每个文件请求发送到 Apache. Nginx 比 Apache 更快地服务静态文件,如图像、JavaScript 和风格表。

打开apache虚拟主机文件。

1sudo nano /etc/nginx/sites-available/apache

添加两个额外的 location 块到每个服务器块,如下面的代码块中的红色显示。

 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://111.111.111.111: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://111.111.111.111: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}

「try_files」指令讓 Nginx 在 document root 中尋找檔案,並直接服務它們. 如果檔案有「.php」擴張,則將要求傳送到 Apache. 即使檔案在 document root 中找不到,也將要求傳送到 Apache,以便像 permalinks 這樣的應用程式功能無問題地工作。

备份文件并执行配置测试。

1sudo service nginx configtest

如果测试成功,重新加载 Nginx。

1sudo service nginx reload

要验证这是有效的,你可以检查Apache在/var/log/apache2中的日志文件,并查看index.phpfoobar.netindex.php文件的GET请求。

警告: 包含位置 ~ /\. 指令非常重要,这会阻止 Nginx 打印.htaccess 和.htpasswd 等文件的内容。

结论

完成本教程后,你现在应该有一个 Ubuntu Droplet 与 Nginx 服务的example.comsample.org,以及 Apache 服务的foobar.nettest.io

Published At
Categories with 技术
comments powered by Disqus