I try to redirect the traffic from the nginx proxy (PROXY_IP) to the Wildfly instance (WILDFLY_IP). The java project is reachable with the url http://WILDFLY_IP:8080/PROJECT_NAME. I want to hide the project name, that the users can access http://PROXY_IP/ and see the same. The nginx proxy is also used to enforce HTTPS.
My config looks like this:
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name PROXY_IP;
ssl_certificate xxxx;
ssl_certificate_key xxxx;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/proxy.access.log;
error_log /var/log/nginx/proxy.error.log;
location / {
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_pass http://WILDFLY_IP:8080/PROJECT_NAME;
proxy_read_timeout 90;
proxy_redirect http://WILDFLY_IP:8080/PROJECT_NAME https://PROXY_IP;
}
location /PROJECT_NAME {
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_pass http://WILDFLY_IP:8080/PROJECT_NAME;
proxy_read_timeout 90;
proxy_redirect http://WILDFLY_IP:8080/PROJECT_NAME https://PROXY_IP;
}
}
The configuration forwards the traffic to the Wildfly instance and enforce https, but it redirects the user from http://PROXY_IP/ to https://PROXY_IP/PROJECT_NAME
I think you can just do this with a rewrite.
location /PROJECT_NAME {
....
rewrite /PROJECT_NAME/(.*) /$1 break;
....
}
Related
So we have a setup where nginx is our reverse proxy that uses proxy_pass to apache tomcat in several locations. The issue we encountered is this:
If a URI contains a dot/period as a trailing value (e.g. http://example.com/sub/john-doe.), this is not properly forwarded to tomcat.
As per the access log in tomcat, "period" was excluded/removed from the URI path.
(http://example.com/sub/john-doe.). --> (http://192.168.1.10:8080/sub/john-doe)
Testing directly to tomcat via local access (http://192.168.1.10:8080/sub/john-doe.) works fine. The "period" was not removed.
What is the correct configuration for this in nginx?
TIA
nginx 1.19 (windows)
Common configuration
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
add_header X-XSS-Protection "1; mode=block";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 4000M;
location /sub {
proxy_pass http://<ip>:8080/sub
}
I use nginx reverse proxy to connect tomcat and nginx config is:
server {
listen 80;
listen [::]:80;
server_name magnet.s-m.local;
location / {
proxy_pass http://tomcat:8080/magnet/;
proxy_cookie_path /magnet /;
proxy_redirect off;
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-Host $server_name;
}
}
every this is ok but when I want to redirect user spring add project name to redirect path.
#RequestMapping(value = "/login",method = RequestMethod.POST)
public String loginCheck(HttpSession session, #RequestParam("username") String user, #RequestParam("password") String password){
session.setAttribute("username",user);
return "redirect:/home";
}
this code redirect to http://magnet.s-m.local/magnet/home but I want to redirect http://magnet.s-m.local/home
if I use RedirectView it's work nice but using redirect:/home is better because I can decide to redirect or load jsp file if login failed.
Try removing proxy_redirect and proxy_set_header Host parameters from your nginx configuration:
location / {
proxy_pass http://tomcat:8080/magnet/;
proxy_cookie_path /magnet /;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
You also can specify the proxy_redirect more in detail, but it should be activated.
Using nginx/1.10.2 proxy and tomcat7 I'm trying to get the actual remote ip address in java webapp by request.getRemoteAddr() but always getting 127.0.0.1. Here's what I did:
CentOS proxy pass: setsebool -P httpd_can_network_connect true
& No config on tomcat7 other than the http/ajp port change.
Nginx config:
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log off;
client_body_in_file_only clean;
client_body_buffer_size 32K;
client_max_body_size 50M;
sendfile on;
send_timeout 300s;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
index index.php index.html index.htm;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
Nginx proxy config:
upstream my_tomcat {
server 127.0.0.1:81;
}
server {
listen 80;
server_name sub.domain.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://my_tomcat;
proxy_redirect off;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
}
}
server {
listen 80;
server_name www.sub.domain.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://my_tomcat;
proxy_redirect off;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
}
}
You should use the HTTP header X-Real-IP to get the real remote ip.
The 'how' is written below
request.getHeader("X-Real-IP")
The 'why' is that, the proxy adds the real client-ip in the http header X-Real-IP as part of the proxying process.
Accoding Remote IP address from Nginx set IP to header:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
after that it available at application with
req.getHeader("X-Forwarded-For")
Also may be useful: blacklist IPs in NGINX and
check blacklisted IP
Unless things have changed a lot since I last looked, your use of request.getRemoteAddr() will always return the address of the proxy host. You must examine the headers added by the proxy server to extract the actual host identity. What you get (hostname or IP address) will depend on what the nginx proxy does.
Tomcat 7/8/9 has a Valve for this very purpose, the Remote IP Valve.
By default it will examine the request header for "X-Forwarded-For", which is the standard header that a proxy will add. Then when request.getRemoteAddr() is called it returns the actual remote address.
For example, place the following in server.xml in the <Engine> level:
<!-- Replaces the apparent client remote IP address and hostname for
the request with the IP address list presented by a proxy or a
load balancer -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
requestAttributesEnabled="true"
internalProxies="127\.0\.0\.1" />
NOTE: if you want the actual remote address used in the access logs, you also need the to configure the AccessLogValve: add requestAttributesEnabled="true" to it.
I am trying to deploy two instances of a Vaadin Spring application using nginx to redirect requests to the appropriate instance.
The first server should be available at www.example.org/, the second one at www.example.org/second/, both at port 80. The first server listens to port 9002, the second to port 9003.
My nginx configuration looks like this:
server_name www.example.org localhost;
root /;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
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_cookie_path ~*^/.* /;
proxy_pass http://127.0.0.1:9002/;
proxy_redirect off;
}
location /second/ {
proxy_set_header X-Forwarded-Host $host/second;
proxy_set_header X-Forwarded-Server $host/second;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host/second;
proxy_cookie_path ~*^/.* /;
proxy_pass http://127.0.0.1:9003/;
proxy_redirect off;
}
}
The first server works completely fine.
I can also access the second server; requests to any of its URLs correctly redirect me to its login page. As soon as i click a button, i get a session expired message. From the nginx access logs, it looks like the button click triggers a POST request which goes to /vaadinServlet/UIDL/?v-uiId=0 and returns code 200 (OK).
I believe the request should really go to /second/vaadinServlet/UIDL/?v-uiId=0. Thus, i am stuck on the login page.
Am i correct in my assumption that the vaadinServlet request goes to the wrong URL? If so, how do i get it to go to the correct one?
I am thinking of using nginx to extract the necessary information from the referral URL but i believe it should be possible to configure Vaadin/Spring to handle this case.
How to get client's ip behind upstream in nginx?
Now I use next configs:
# upstream listener
upstream ts {
server localhost:841 weight=10 max_fails=3 fail_timeout=10s;
server 10.1.3.209:8080 backup;
}
# server listener
server {
listen 80;
server_name 10.9.24.45;
location / {
proxy_pass http://ts;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# app listener
server {
listen 841;
server_name localhost;
charset utf-8;
access_log /var/log/nginx/access_ts.log;
error_log /var/log/nginx/error_ts.log;
client_max_body_size 16M;
set $www /www;
set $root $www/apps/ts/ROOT;
include /etc/nginx/sites-available/locations;
location / {
proxy_pass http://localhost:840;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include /etc/nginx/sites-available/location-config;
}
}
In my java app I use X-Real_IP header to get client's ip and all were fine, but after I start use another config with upstream I see only 127.0.0.0. Think this correct, but I need to get a real ip for my app.
How can I get a real ip behind nginx upstream?
I see some answers like proxy_set_header realip $remote_addr, but what can I do without my java app change.
i had the same issue, the problem is the header you forward change
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Into:
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;