如何为 tomcat 服务器配置 nginx 反向代理?

如何为 tomcat 服务器配置 nginx 反向代理?

好吧,我被赋予了“现代化”更新世应用的任务,但我无法完成这项工作。让我解释一下:

我有一系列 tomcat 服务器,每个服务器都有以下结构:

(partner1 - tomcatServer1)
http://myServerIp1:8080/ ->tomcat index
http://myServerIp1:8080/webapp1 ->webapp1(main)
http://myServerIp1:8080/webapp2 ->webapp2
(partner2 - tomcatServer2)
http://myServerIp2:8080/ ->tomcat index
http://myServerIp2:8080/webapp1 ->webapp1(main)
http://myServerIp2:8080/webapp2 ->webapp2
http://myServerIp2:8080/webapp3 ->webapp3

正如您所看到的,首先我发现了几个非常明显的问题。

  1. 首先,他们使用公共 IP,这使得查找 SSL 证书的任务变得复杂(但这将在后面解决)。
  2. 每个服务器包含多个应用程序。

我最初的想法是“现代化”应用程序,使用一个域并通过一个专用的 nginx 服务器,创建一个使用以下结构的反向代理

(partner1 - tomcatServer1)
http://partner1.myDomain.com/ ->webapp1(main)
http://partner1.myDomain.com/webapp2 ->webapp2
(partner2 - tomcatServer2)
http://partner2.myDomain.com/ ->webapp1(main)
http://partner2.myDomain.com/webapp2 ->webapp2
http://partner2.myDomain.com/webapp3 ->webapp3

一旦实现这一点,我就会开始与使用 SSL 作斗争。我之所以这么说,是因为我不希望在没有先检查它是否能正常工作的情况下就开始使用 SSL,因为我甚至无法为 tomcat 索引创建一个好的 proxy_pass,因为它只加载文本而不加载图像。如果我进行了重定向,就不会出现问题,但这个想法是客户端停止使用 IP,最终拥有一个严肃的域

当然,我不仅尝试过 tomcat 索引,之前我还直接尝试过 webapp1,发现它没有给出错误...但它什么也没显示。看到这个是当我去查看索引时,我意识到它也没有很好地加载。

一开始我认为可以通过在tomcat中为每个webapp创建一个virtualhost来解决这个问题,因为我觉得这个问题比较暴力,直接对http://myServerIp1:8080/webapp1/进行proxy_pass,但是一旦配置了tomcat的虚拟主机,结果还是一样的,完全是白页。

我需要帮助,我认为最好的开始方式是从头开始。让我们看看你是否能帮助我让 tomcat 索引正确加载

为此,我暂时保留没有虚拟主机的 tomcat 配置,这将是 tomcat 索引的 nginx 配置http://partner1.myDomain.com/(稍后,如果加载顺利,我将开始使用该应用程序进行测试)

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    index index.html index.htm index.nginx-debian.html;
    server_name partner1.myDomain.com;

    location / {
        proxy_pass  http://myServerIp1: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;
        try_files $uri $uri/ =404;
    }
}

可以看到,这是对 Debian 中默认的 nginx 文件进行了小幅修改。如果我查看浏览器的开发工具,可以发现它在“tomcat.css、favicon.ico...”等元素的加载方面存在问题。

答案1

你的情况类似这个问题。Tomcat 不知道它正在被代理,并且生成的绝对 URL 以 开头http://myServerIp:8080

您需要添加一个远程IpValve给你<Host>

<Valve className="org.apache.catalina.valves.RemoteIpValve"
       protocolHeader="X-Forwarded-Proto" />

并进行设置requestAttributesEnabled=trueAccessLogValve以便日志包含真实的 IP)。

NGINX 需要向 Tomcat 发送Host和标X-Forwarded-ForX-Forwarded-Proto

proxy_set_header Host $server_name;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

X-Real-IP标题已包含在内X-Forwarded-For)。

修改配置后,运行在 Tomcat 上的应用程序将表现得像在 上一样partner1.example.com:80。此外,当您切换到 时HTTPS,Tomcat 将知道请求来自安全通道并生成https://链接。

编辑:在更新后的配置中,您将代理页面的绝对路径从 更改为/myWebapp//我不建议这样做:Tomcat 将 的 cookie 路径设置为JSESSIONID上下文路径/myWebapp/,因此 Web 浏览器永远不会将 cookie 发回。请改用如下配置:

    location = / {
        return 301 http://partner1.example.com/myWebapp/;
    }

    location / {
        proxy_pass http://myServerIp.8080;
        include    nginxconfig.io/proxy.conf;
    }

将客户端从 重定向//myWebapp/,但其他方面保持路径不变。

笔记:myDomain.com是属于某人的有效域名,因此最好使用为文档保留的域在问题和答案中。

答案2

我最终在不接触 tomcat 的情况下到达那里,事实上我设法看到了如下应用程序: http://myServerIp.8080/myWebapp/--> http://partner1.myDomain.com/

但后来我遇到了另一个问题。启动应用程序后,jsessionid 不会得到维护,并且会在每个请求中更新。我尝试过以下解决方案: 使用 Nginx 作为反向代理将 samesite 添加到 cookies 使用 nginx 作为 tomcat 的反向代理会导致每个 ssl 请求产生新的 jsessionid https://stackoverflow.com/questions/53542525/nginx-how-to-take-value-from-header-and-set-it-into-cookie 现在我已尝试按照您的指示修改 tomcat。但是 Jsessionid 一直在变化,我设法进入应用程序,但当我发出该请求时它再次发生变化,当我进入应用程序时一切都失败了,它显示我未经授权。

这是我的配置

---------------
-----nginx.conf
---------------
user                 www-data;
pid                  /run/nginx.pid;
worker_processes     auto;
worker_rlimit_nofile 65535;

events {
    multi_accept       on;
    worker_connections 65535;
}

http {
    charset              utf-8;
    sendfile             on;
    tcp_nopush           on;
    tcp_nodelay          on;
    server_tokens        off;
    log_not_found        off;
    types_hash_max_size  2048;
    client_max_body_size 16M;

    # MIME
    include              mime.types;
    default_type         application/octet-stream;

    # Logging
    access_log           /var/log/nginx/access.log;
    error_log            /var/log/nginx/error.log warn;

    # Load configs
    include              /etc/nginx/conf.d/*.conf;
    include              /etc/nginx/sites-enabled/*;
}

---------------
-----General
---------------


# favicon.ico
location = /favicon.ico {
    log_not_found off;
    access_log    off;
}

# robots.txt
location = /robots.txt {
    log_not_found off;
    access_log    off;
}

# gzip
gzip            on;
gzip_vary       on;
gzip_proxied    any;
gzip_comp_level 6;
gzip_types      text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

---------------
-----Proxy
---------------


proxy_http_version                 1.1;
proxy_cache_bypass                 $http_upgrade;

# Proxy headers
proxy_set_header Upgrade           $http_upgrade;
proxy_set_header Connection        "upgrade";
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;
proxy_set_header X-Forwarded-Host  $host;
proxy_set_header X-Forwarded-Port  $server_port;

# Proxy timeouts
proxy_connect_timeout              60s;
proxy_send_timeout                 60s;
proxy_read_timeout                 60s;


---------------
-----webapp
---------------


server {
    listen      80;
    listen      [::]:80;
    server_name partner1.myDomain.com;

    # logging
    access_log  /var/log/nginx/partner1.myDomain.com.access.log;
    error_log   /var/log/nginx/partner1.myDomain.com.error.log warn;

    # reverse proxy
    location / {
        proxy_pass http://myServerIp.8080/myWebapp/;
        include    nginxconfig.io/proxy.conf;
    }

    # additional config
    include nginxconfig.io/general.conf;
}

相关内容