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
Related
I want to open port 80 for http and port 433 for https. The port 80 should be redirected to 433. I set the server port in application.properties to port 80:
server.port=80
And to redirect I followed the official spring documentation and created this small class:
public class HTTPSRedirector {
#Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.redirectToHttps();
return http.build();
}
}
But now the server times out and when I try using curl with the following command:
curl -v http://www.example.com/
I get a Bad request response because SSL/TLS is enabled. If I try to ping / contact the https port like this:
curl -v https://www.example.com/
then I get the message that the port is not opened and the connection was refused. How can I open both ports 80 and 433 in my Java spring project?
This is the way how I finally fixed it:
I used the bean listed in my question. This bean redirects all http requests to https.
ADDITIONALLY to that I set the server port to:
server.port=443
which is the default port for https. With these two changes the server works fine and everything is 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
I've created telegram bot on Java with rubenlagus api.And now I can't setup webhook. I know these rules for webhook:
*Supports IPv4, IPv6 is currently not supported for Webhooks.
*Accepts incoming POSTs from 149.154.167.197-233 on port 443,80,88 or 8443.
*Is able to handle TLS1.0+ HTTPS-traffic.
*Provides a supported, non-wildcard, verified or self-signed certificate.
*Uses a CN or SAN that matches the domain you’ve supplied on setup.
*Supplies all intermediate certificates to complete a verification chain.
I have a domain name with verified ssl certificate.Qualys test shows A+ rank.Server Supports IPv4. 443
port is listening. And server accepts incoming POSTs from 149.154.167.197-233 on port 443. I use this rubenlagus api method for creating TelegramApi
private static TelegramBotsApi createNoSelfSignedTelegramBotsApi() throws TelegramApiException {
return new TelegramBotsApi(
"src/main/resources/server.jks",//path to KeyStore for the server
"myPassword", //Key store password for the serve
"https://example.com:443", //External url
"https://localhost:443"); //Internal url
}
I've obtained server.jks via these commands
openssl pkcs12 -export -in mydomain.net.crt -inkey mydomain.key > keypair.p12
keytool -importkeystore -srckeystore keypair.p12 -destkeystore server.jks -srcstoretype pkcs12
This is my code:
ApiContextInitializer.init();
TelegramBotsApi botsApi = new TelegramBotsApi(
"src/main/resources/server.jks",
"mypassword",
"https://example.com:443",
"https://localhost:443");
BotHook webhookBot = new BotHook(options);
botsApi.registerBot(webhookBot);
When i start program, i recieve this
Jul 28, 2018 3:27:59 PM
org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:443]
Jul 28, 2018 3:27:59 PM org.glassfish.grizzly.http.server.HttpServer
start
INFO: [HttpServer] Started.
But bot don't work.I see this in server's logs:
2018/07/29 15:08:43 [error] 1166#1166: *453 openat() "/var/www/www->root/data/www/example.net/callback/WebhookClass failed (2: No such file or >directory),
client: 149.154.167.227, server: example.net request: "POST >/callback/WebhookClass HTTP/1.1", host: "example.net"
It seems like Grizzly can't handle http request. When i'm trying to check it via this curl command
curl -X POST -i http://217.0.0.1:443/callback
I recieve this
curl: (7) Failed to connect to 217.0.0.1 port 443: Connection timed out
I checked many times all parameters passed in TelegramBotsApi constructor.
Seems like problem with your infrastructure, not code. TelegramBotsApi starts http Grizzly server on port 443 which handles bot related requests from Telegram. Telegram will access server by it's external URL https://example.com:443.
Server's logs your provided looks like it is Nginx, am I right? So I assume your have Nginx server configured to accept requests for https://example.com:443. Requests from Telegram are handled by Nginx and not by Grizzly server. Nginx answers with 404 because it has no handlers configured on /callback/* path.
You have several options to make requests from Telegram sent to example.com to be forwarded to Grizzly:
Run your program on server where nginx is running. You need use another port, 8443 for example. Setup your server's firewall rules to allow incoming connections on 8443.
Configure nginx to forward all http request matching /callback/* to your Grizzly server. Add following to server section of nginx config file:
location /callback {
proxy_pass https://<YOUR_TELEGRAM_BOT_SERVER>:443;
}
Where YOUR_TELEGRAM_BOT_SERVER is host name or IP of server running your program. When registering bot api make sure to use the same certificate as your nginx server.
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.
I'm developing app for GAE. Currently GAE dev server doesn't support https, so I managed to create a HTTPS proxy using nginx. The problem is that I also have a third party service that uses my app, but only can make requests using HTTPS, i.e. it can make request https://localhost, but won't proceed http://localhost. Inside my app I use the library of the service that internally uses req.getRequestURL() from HttpServletRequest. So, the request: Request (to https: //localhost) -> nginx proxy -> Request (to http: //localhost) -> dev GAE server. And req.getRequestURL() returns "http: //localhost" which doesn't match that in the request field (it's a special field in the request specified by the protocol of the service) and the library throws exception. What can I do?
My nginx config:
server {
listen 443 ssl; # The ssl directive tells NGINX to decrypt
# the traffic
server_name localhost;
ssl_certificate ls.crt; # This is the certificate file
ssl_certificate_key ls.key; # This is the private key file
location / {
proxy_pass http://localhost:8080;
}
}