作为Apache前面的反向代理的NGINX在SSL打开时不起作用

我已经阅读了每一篇文章,教程和论坛的评论,对于我来说,一旦SSL使用Nginx服务器模块,我仍然无法让Nginx代理正常工作。

对于常规和ssl访问,Apache完全使用虚拟主机进行设置。 Apache正在使用ports.conf监听端口8081,如下所示:

NameVirtualHost *:8081 Listen 8081 <IfModule ssl_module> Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule> 

我的SSL apache虚拟主机如下所示:

打开nginx并将ssl设置注释掉(见下面的configuration),一切正常,因为我能够正确访问SSL和非SSL版本的站点。

  server { listen 80; # listen 443 ssl; server_name foobar.net; # ssl on; # ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem; location / { proxy_pass http://104.236.224.53:8081; 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_set_header X-Forwarded-Proto $scheme; } } 

当我修改上面的文件并通过在服务器块中取消注释选项打开SSL时,Nginx和Apache之间在端口443上似乎有冲突?

更新和未评论的服务器块如下所示:

  server { listen 80; listen 443 ssl; server_name foobar.net; ssl on; ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem; location / { proxy_pass http://104.236.224.53:8081; 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_set_header X-Forwarded-Proto $scheme; } } 

试图启动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: failed (Result: exit-code) since Mon 2017-02-20 18:35:20 EST; 16s ago Process: 14505 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS Process: 14475 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS) Process: 14671 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE) Process: 14652 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 14328 (code=exited, status=0/SUCCESS) Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] still could not bind() Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Control process exited, code=exited status=1 Feb 20 18:35:20 foo.foobar.net systemd[1]: Failed to start A high performance web server and a reverse proxy server. Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Unit entered failed state. Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Failed with result 'exit-code'. 

我在这里丢失了什么,我的实现让SSL从Nginx正确传递给Apache?


编辑1:为了解决Tim的好处,我将编辑我的主要意图,让Nginx处理所有的请求。

  • 我的初衷是在Apache已经被用作我的主服务器的同一台机器上安装Discourse,它本身在一个Docker容器中。
  • 由于Discourse需要访问端口80才能正常运行,因此build议将nginx设置为反向代理,以处理所有传入的请求,以便相应地传递它们。
  • 我想在后面使用apache来处理所有dynamic内容,并让nginx处理静态位。 所以我的理解是,为了做到这一点,需要在每个实例的apache上build立虚拟主机:http和https请求。 也许我在这里错了吗?

我遵循DigitalOceanbuild议的configuration:快进到可选步骤9。

从逻辑上看,正如我在Apache HTTP监听端口8081上的HTTP主机上传输来自nginx的请求一样,我认为我可以做同样的事情,并且Apache上的HTTPS主机监听端口8081,并且正常地将标头传递给Apache处理其余的事情。 这个实现不能完全工作,因为我被400: the plain http request was sent to https port错误困扰400: the plain http request was sent to https port

我更进了一步,假设可能是因为Apache HTTP和HTTPS都在监听端口8081,如果我将分配的apache HTTP分配给端口8081,HTTPS分配给端口1443,那么所有东西都可以无缝地工作。 当我尝试通过HTTPS访问我的worpress博客,并且这个实现出现错误时,它又不能正常工作

 Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please. 

在这一点上,即使看起来很多人已经得到数字海洋build议的实施正常工作,我实际上是新鲜的想法。 : – /

你已经告诉Apache和Nginx在端口443上侦听,我假设在同一台机器上。 只有一个应用程序可以在端口上侦听。

也许你可以编辑你的问题来告诉我们为什么你要使用Nginx和Apache–你可以用它们中的任何一个来做大部分事情。 你可能会得到更有用的build议。

看起来我终于得到了实施,这要感谢我收到的所有反馈。 Thanx @AlexeyTen和@Tim

  • 首先,我禁用了域名foobar.net的sudo a2dissite foobar.net.cong apache上的https vhost

  • 我编辑了apache ports.conf文件只听端口8081和删除侦听端口443:

 NameVirtualHost *:8081 Listen 8081 
  • 最后,我编辑nginx服务器块来听取端口443,并确保注释掉ssl on 。 不这样做没有工作。
 > server { > listen 80; > listen 443 ssl; > server_name foobar.net; > > # ssl on; > ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem; > ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem; > > location / { > proxy_pass http://104.236.224.53:8081; > 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_set_header X-Forwarded-Proto $scheme; > } } 

这个实现似乎工作正常,无缝地将php处理切换到Apache。

@罗伯特,你的解决scheme工作,但没有在浏览器中加载SSL证书。

我的解决scheme如下:

将Apache的默认端口从80更改为8080

将Apache的默认SSL端口从443更改为444

以下是我的ngnixconfiguration:

服务器{

听80;

 server_name servername.com; 

位置 / {

  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_set_header X-Forwarded-Proto $scheme; expires off; } 

}

服务器{

 listen 443 ssl http2; server_name servername.com; ssl on; ssl_certificate /etc/nginx/ssl/keyname.crt; ssl_certificate_key /etc/nginx/ssl/private/keyname.key; 

位置 / {

  proxy_pass https://127.0.0.1:444; 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_set_header X-Forwarded-Proto $scheme; expires off; } 

}

注意:

  1. 在SSL的情况下,需要将proxy_pass更改为https。
  2. 当nginx作为apache的反向代理服务器时,这工作正常。
  3. 需要修改Apache vhost以包含444而不是443的SSLconfiguration。
  4. configurationApache的ports.conf为444