HAProxy application server response other port - java

I have serverA with haproxy and configuration:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
daemon
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
frontend http-in
bind *:80
default_backend servers
backend servers
option httpchk OPTIONS /
option forwardfor
stats enable
stats refresh 10s
stats hide-version
stats scope .
stats uri /admin?stats
stats realm Haproxy\ Statistics
stats auth admin:pass
cookie JSESSIONID prefix
server tomcat1 serverB:10039 cookie JSESSIONID_SERVER_1
server tomcat2 serverC:10039 cookie JSESSIONID_SERVER_2
Now, i goes to http://serverA/admin?stats and got statistic. On servers serverB and serverC installed WebSphere Application Server and WebSphere Portal Server (WAS it is like Tomcat and WPS it is like any application deployed to Tomcat). It hosts on port 100039. Now i goes to http://serverA/wps/portal and got my portal, but when i click on any link to any page, i got redirect to http://serverA:100039/wps/portal/bla/bla, this happens because WPS response with its port - 100039, but my haproxy configuration listen only 80 port. What i've tried:
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
For an example, in nginx i got like this:
My application hosts on 3000 port and usefull part of my nginx configuration looks like this:
location #ruby {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_read_timeout 300;
proxy_pass http://app; #upstream app
}
How i can do this in HAProxy?

This question is similar to WebSphere Portal behind reverse proxy and getServerPort()
I think the issue is that WebSphere Application Server (traditional) doesn't honor host headers properly, which can impact getting reverse proxies to work.
Try the settings recommended in that other answer (adjust the apache configuration setting for haproxy), and all should be well.

In your backend section, use "http-request set-header" to set $WSSP and $WSSN to your client-visible hostname and port. They will then be used for self-referential redirects.
Or, set the websphere custom properties trusthostheaderport and com.ibm.ws.webcontainer.extractHostHeaderPort (http://www-01.ibm.com/support/docview.wss?uid=swg21569667) to respect the port in the Host: header.
With this option you may need to ask HAProxy to set the host header to the clients view with "http-request set-header Host" also in the backend section. I'm not sure what the default is.

Related

Configuring VirtualHost in Spring Boot application embedded Tomcat server in Windows

I have a private Windows server running a Spring Boot jar file and I can access it via the IP address. I have a few websites available which I am able to access via the IP address and filters. (Note that this is running on port 54654 as I have other WEB APIs as well). I have a new domain registered online and I would like to access the server by the domain name which would redirect to my server address.
But the issue is, the browser shows the IP address instead of the domain name. I tried forward with masking but it is not working as I expected (it puts the site inside an iFrame and I cannot access browser properties etc). I want to access my site like www.abc.com and it should not change to <host-ip-address>:<port>. I understand the issue is from server side and do not know how to make it remain in the domain name. I tried a new entry with hosts.txt file but it does not seem to work.
I have searched for solution online for hours and could not find a specific solution for Spring Boot and changing VirtualHost settings in tomcat is not clear to me in this case. Is there any settings for this in application.properties file?
So this is the summary of things I learnt from this requirement. Thank you #PiotrP.Karwasz for your extended support.
You can run your server in any port but the domain name provider can only point to the default port (80)
If you change your forwarding setting AFTER you have edited your A record, your domain will be moved to Parked state (Parked is when your domain is shown as "taken" to others who visit it and it will not point to your A record's IP address). In such case, you have to modify your A record again.
You can use nginx to configure reroute from http port (80) to any port your server runs in. My nginx configuration:
server {
listen 80;
server_name <my-site>.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:<my-port>";
}
}
Domain name changes will take time to reflect in DNS (24-48 hours) and you can check it by clearing cache or by incognito window (private browsing).

HAProxy1.7 forward client IP to backend

I'm trying to forward source/client_ip(%ci) that reaches haproxy to the applicaion using X_FORWARDED_FOR.
HA-Proxy version 1.7.9 2017/08/18
global
log 127.0.0.1 local1 info
daemon
user vcap
group vcap
maxconn 64000
spread-checks 4
defaults
maxconn 64000
option http-server-close
option httplog
option forwardfor
frontend http-in
mode http
bind :80
log global
option forwardfor except 127.0.0.1
frontend https-in
mode http
log global
bind :443 ssl crt /data/haproxy/ssl/server.pem
option forwardfor except 127.0.0.1
use_backend https-backend
http-request set-header SSL_CLIENT_CERT_USER %{+Q}[ssl_c_s_dn(cn)]
http-request set-header SSL_CLIENT_CERT %{+Q}[ssl_c_der,base64]
http-request set-header SSL_CLIENT_CERT_USED %[ssl_c_used] if no_user_cert
backend https-backend
mode http
log global
balance roundrobin
option forwardfor header X-Client
Java app does the following:
String ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
Having the above config in place, I get haproxy's IP in the application log and not the actual source IP.
Adding set-header in the frontend or backend or on both sides did not help:
http-request set-header X-CLIENT-IP %[src].
Am i doing it wrong?
You should update to the lates 1.7 version https://www.haproxy.org/bugs/bugs-1.7.9.html
You define option forwardfor header X-Client therefore your App should get the X-Client header.
String ipAddress = request.getHeader("HTTP_X_CLIENT");
Doc: option forwardfor

Open Trip Planner over HTTPS

I'm trying to deploy a solution using Open Trip Planner, and everything is OK if I use HTTP, but apparently the HTTPS connection doesn't work.
I've followed the official docs but with no success, apparently the internal server is running, it logs that the expected HTTPS port is listening and the port is actually shown as listening by the OS (Windows 10 Pro) but no secure connection can be established (I tried the "curl" and "open-ssl" tests in the page but both failed)
This is the document I refer to:
http://docs.opentripplanner.org/en/latest/Security/#security
Please any help is appreciated, thanks in advance
Is using a reverse proxy like nginx an option for you? That way nginx can handle the HTTPS requests, and then pass them onto opentripplanner.
Here's an example nginx configuration:
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/cacert.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
server_name opentripplanner.example.com;
proxy_pass http://127.0.0.1:8000;
}
References:
https://manual.seafile.com/deploy/https_with_nginx.html
https://nginx.org/en/docs/beginners_guide.html

How to get real http request in Tomcat behind an Apache?

I'm running a Tomcat webserver on http port 8080. In front I have an Apache that handles https ssl connections.
How can I know if the client made a request using http:// or https://? Because the following shows http always, because the Apache internally sends only http:8080 requests to the Tomcat of course. So the initial scheme requested is lost here.
HttpServletRequest req;
req.getRequestURL().toString(); // always shows http://....
Apache should add following request headers as explained in mod_proxy docs:
X-Forwarded-For - The IP address of the client.
X-Forwarded-Host - The original host requested by the client in the Host HTTP request header.
X-Forwarded-Server - The hostname of the proxy server.
Additionally X-Forwaded-Proto with the original protocol can be added as explained in this example:
<VirtualHost *:443>
<strong>RequestHeader set X-Forwarded-Proto "https"</strong>

Redirect Subdomain to working HTTPS-Tomcat (with NGINX)

I have a working tomcat-webapplication at https://very-ugly-and-anoying-domain-name.com:8443/webdir/index.xhtml
Now I want to shorten it to https://appname.nice.com, so it redirects to my internal https://very-ugly-and-anoying-domain-name.com:8443/appname/
For all other applications, I use Nginx to redirect a subdomain http://appname.nice.com to http://very-ugly-and-anoying-domain-name.com:8081/appname/ with
server {
listen 80;
server_name appname.nice.com;
location / {
proxy_pass http://ugly-looooooooooong.domain.com:8081;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
root /data/www/appname;
error_page 403 404 502 503 504 /error.html;
location /error.html {
allow all;
internal;
}
}
But I never had the topic of redirecting a https connection. I think need NOT the stuff of adding the keystore to Nginx because it's already in tomcat.
I do not need HTTP to HTTPS or HTTPS to HTTP. Maybe there is a way to set this directly in Tomcat, but I am not so used to tomcat-config.
How does it work?
Your config doesn't do a "redirect", it simply proxies the request to the host with the "ugly" domain name. For redirect, you would have to return a specific redirect code. For HTTPS, you would need a certificate which has the domain name appname.nice.com in its Subject Alternative Name field because the SSL handshake will look for it. Configure the virtual server with ssl on and use that certificate to terminate SSL. Then you can use a similar config to proxy the HTTPS request to the "ugly" domain name.

Categories