带有nodejs的nginx反向代理和基于SSL的apache

时间:2017-06-29 03:13:40

标签: node.js apache ssl nginx proxy

我一直在尝试使用nginx设置反向代理,该代理可以在端口3000上使用ssl上的nodejs,在端口443上使用aps over ssl。我已经尝试了很多东西,我的conf文件可能有吨错误。我最近的尝试是/etc/apache2/sites-enabled/000-default.conf:

<VirtualHost *:443>
        # The ServerName directive sets the request scheme, hostname and port t$
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin admin@test.com
        DocumentRoot /var/www/html/public
        SSLEngine on
        SSLCertificateFile /var/www/certs/test_com.crt
        SSLCertificateKeyFile /var/www/certs/test_com.key

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

我的nginx配置如下所示:

server {
listen 80;

access_log /var/log/nginx/secure.log;
error_log /var/log/nginx/secure.error.log;    


server_name test.com;

ssl on;
ssl_certificate /var/www/certs/test_com.crt;
ssl_certificate_key /var/www/certs/test_com.key;



location / {
    proxy_pass https://127.0.0.1:3000;
}

location /public {
    proxy_pass https://127.0.0.1:443;
    root /var/www/html/public; //this is where I keep all the html files
}
}

当我运行netstat -tulpn时,我得到:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               
tcp6       0      0 :::22                   :::*                    LISTEN      -               
tcp6       0      0 :::3000                 :::*                    LISTEN      -               
udp        0      0 0.0.0.0:68              0.0.0.0:* 

这是我第一次设置这样的服务器所以如果有人可以解释反向代理如何与使用来自apache实例的网页在ssl上使用的nodejs服务器一起工作,我真的很感激。

我不确定这是如何工作的,但如果我不得不在逻辑上猜测,我希望在端口80上侦听nginx实例,将所有http流量重定向到https流量。我希望在端口443上配置apache,这样我就可以浏览到我的css样式表https://test.com/assets/css/stylesheet.css,并能够将其用作节点服务器中的路径。

我在搜索中发现了这一点,但无法正确实现:https://www.digitalocean.com/community/questions/how-to-setup-ssl-for-nginx-and-apache

我知道我不是很好解释,但我希望有人能够理解我的需要并帮助我。谢谢!

1 个答案:

答案 0 :(得分:0)

是的,这听起来令人困惑。从nginx直接提供静态资产是很常见的,然后将所有其他请求反向代理到某些后端(3000上的节点)。 我对Apache的需求感到非常困惑。 如果你真的需要Apache,你可以这样做。

首先,你说你希望nginx在端口80上侦听,只是将所有http流量重定向到https,像这样配置你的nginx。

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

这就是nginx。 现在对于Apache,你需要mod_proxy,它将在443上侦听并处理TLS终止,然后代理请求到节点侦听3000

<VirtualHost *:*>
  # your config here...

  ProxyPreserveHost On 
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/ 
</VirtualHost> 

https://httpd.apache.org/docs/2.4/mod/mod_proxy.html

我不确定你为什么要这样做,如果可以,我建议只使用nginx监听80,重定向到443,处理TLS终止,提供静态资产,并将代理转发给你后端。设置起来要简单得多。

示例

未经测试的nginx配置

# replace 'domain.com' with your domain name
# http server, redirects to https
server {
  listen 80;
  listen [::]:80;
  server_name example.com;
  return 301 https://example.com$request_uri;
}

# https server
server {
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name example.com;

  ssl on;

  # replace this with your cert+key path
  ssl_certificate /etc/ssl/private/YOUR_CERT.crt;
  ssl_certificate_key /etc/ssl/private/YOUR_SERVER_KEY.key;

  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:20m;
  ssl_session_tickets off;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;

  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';

  ssl_stapling on;
  ssl_stapling_verify on;

  # replace 'node-app' with your app name
  access_log /var/log/nginx/node-app.access.log;
  error_log /var/log/nginx/node-app.error.log;

  location / {
    # the path to your static assets
    root /var/www/your-app/public;

    try_files $uri $uri/ @nodebackend;
  }

  # all requests to locations not found in static path
  # will be forwarded to the node server
  location @nodebackend {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_pass http://localhost:3000;
    proxy_redirect off;
  }
}