HTTPD Proxy Change Response Address - apache

My setup is as follows:
client -> proxy(dnsname eg. https://test.com) -> Jetty webapp(1.2.3.4)
The webapp sends a redirect response back (to an authentication webapp) to the client. It automatically points to the proxy via dnsname eg. https://proxy/auth and cannot be configured further.
The issue with this is the webapp will pass redirects back to the client and the client cannot resolve https://proxy as I can't make it a dns entry. Is it then possible for the proxy to intercept the traffic from the webapp (https://proxy) and change it to https://test.com? Even better can the proxy autodetect the entry dns name and append it to any responses from the webapp?
I'd envisioned the following:
client request https://test.com/page1-> hits proxy which resolves to webapp -> webapp gives redirect response via https://proxy/auth -> proxy intercepts and changes redirect to https://test.com/auth
I need this so that everything behind the proxy isn't machine nor ip specific. I can shift and deploy to any environment.

I figured this out eventually. You can just modify the redirect headers in the location field.
Header edit Location "(^http[s]?://proxy)" "https://whatevernameyouwant"

Related

Reverse proxy and rewrite URL in NGINX

I want to redirect requests to our internal repository servers without edit repository addresses in package manager's configuration. Here is the scenario:
Add internal IP (NGINX Server) address to hosts file as "ubuntu.com" or any other domain in each server.
Reverse proxy http or https requests which wants reach "ubuntu.com" or other domains to repository server address with different port as http request.
Would you please comment some samples for this scenario?
I can do reverse proxy, but I need some samples to rewrite URL if needed and replace domain with repository server address.

httpd proxy any domain

Is it possible to configure a vhost on httpd that accepts any domain received and proxies to the actual website? Like subdomain wildcard but for the domain.
I'm assuming that tools like Squid Proxy can do this just fine, I'm just curious if it can be done with apache.
Sure that is possible, but you don't even need a proxy for that. The apache http server offers the concept of a "default virtual host". Which is exactly what you want: that host is responsible to respond to incoming requests to http hosts that do not have a specific configuration.
The default typically simply is the first of all hosts defined inside an apache http server.
An alternative I personally use is to setup the virtual hosts by just a basic configuration (name, admin and the like), but to include the actual content configuration (DocumentRoot and rewriting stuff) from a separate file). That way you can easily share the same setup between many virtual hosts but still have individual configuration options per domain, subdomain, http host, however you want to call that (there is no difference for the http server anyway, it is all http hosts).

ktor redirecting to 0.0.0.0 when doing an https redirect

I've added an http redirect to my Ktor application and it's redirecting to https://0.0.0.0 instead of to the actual domain's https
#ExperimentalTime
fun Application.module() {
if (ENV.env != LOCAL) {
install(ForwardedHeaderSupport)
install(XForwardedHeaderSupport)
install(HttpsRedirect)
}
Intercepting the route and printing out the host
routing {
intercept(ApplicationCallPipeline.Features) {
val host = this.context.request.host()
i seem to be getting 0:0:0:0:0:0:0:0 for the host
Do i need to add any special headers to Google Cloud's Load Balancer for this https redirect to work correctly? Seems like it's not picking up the correct host
As your Ktor server is hidden behind a reverse proxy, it isn't tied to the "external" host of your site. Ktor has specific feature to handle working behind reverse proxy, so it should be as simple as install(XForwardedHeaderSupport) during configuration and referencing request.origin.remoteHost to get actual host.
Let's try to see what's going on.
You create a service under http://example.org. On the port 80 of the host for example.org, there is a load balancer. It handles all the incoming traffic, routing it to servers behind itself.
Your actual application is running on another virtual machine. It has its own IP address, internal to your cloud, and accessible by the load balancer.
Let's see a flow of HTTP request and response for this system.
An external user sends an HTTP request to GET / with Host: example.org on port 80 of example.org.
The load balancer gets the request, checks its rules and finds an internal server to direct the request to.
Load balancer crafts the new HTTP request, mostly copying incoming data, but updating Host header and adding several X-Forwarded-* headers to keep information about the proxied request (see here for info specific to GCP).
The request hits your server. At this point you can analyze X-Forwarded-* headers to see if you are behind a reverse proxy, and get needed details of the actual query sent by the actual user, like original host.
You craft the HTTP response, and your server sends it back to the load balancer.
Load balancer passes this respone to the external user.
Note that although there is RFC 7239 for specifying information on request forwarding, GCP load balancer seems to use de-facto standard X-Forwarded-* headers, so you need XForwardedHeaderSupport, not ForwardedHeaderSupport (note additional X).
So it seems either Google Cloud Load Balancer is sending the wrong headers or Ktor is reading the wrong headers or both.
I've tried
install(ForwardedHeaderSupport)
install(XForwardedHeaderSupport)
install(HttpsRedirect)
or
//install(ForwardedHeaderSupport)
install(XForwardedHeaderSupport)
install(HttpsRedirect)
or
install(ForwardedHeaderSupport)
//install(XForwardedHeaderSupport)
install(HttpsRedirect)
or
//install(ForwardedHeaderSupport)
//install(XForwardedHeaderSupport)
install(HttpsRedirect)
All these combinations are working on another project, but that project is using an older version of Ktor (this being the one that was released with 1.4 rc) and that project is also using an older Google Cloud load balancer setup.
So i've decided to roll my own.
This line will log all the headers coming in with your request,
log.info(context.request.headers.toMap().toString())
then just pick the relevant ones and build an https redirect:
routing {
intercept(ApplicationCallPipeline.Features) {
if (ENV.env != LOCAL) {
log.info(context.request.headers.toMap().toString())
// workaround for call.request.host that contains the wrong host
// and not redirecting properly to the correct https url
val proto = call.request.header("X-Forwarded-Proto")
val host = call.request.header("Host")
val path = call.request.path()
if (host == null || proto == null) {
log.error("Unknown host / port")
} else if (proto == "http") {
val newUrl = "https://$host$path"
log.info("https redirecting to $newUrl")
// redirect browser
this.context.respondRedirect(url = newUrl, permanent = true)
this.finish()
}
}
}

Haproxy as reverse proxy problem in ssl pathtrough

I setup haproxy as reverse proxy in our organization . we want when the client request for some web site like lenovo or oracle or etc. …the request must be passed through our reverse proxy server .(because our client set our dns server and i defined reverse proxy’s ip as those such domain in our dns server). i using SSL passthrough .but i have some problem in this case.
1- some time haproxy doesnt work fine and have problem to load right certificate.for example when i want to see www.amazon.com haproxy load wrong certificate(SSL_ERROR_BAD_CERT_DOMAIN) so firefox prevent to load website. in this case i have www.intel.com in haproxy config so haproxy getting confused and load www.amazon.com with intel certificate website.
2-I want all sub domain of website like *.oracle.com or *.lenovo.com passed through our reverse proxy so we don’t need to register sub domains of website one by one in haproxy server .
i try with -reg or matching pattern method but all of them need to final destination.
3- some time redirection cant work properly and we facing http to https redirection error .(some time client enter lenovo.com or intel.com (means http requesting).to over come this problem i defined http frontend and redirect all request to https except one hypothetical request by acl . but my issue some time appear.
This is simple done by req_ssl_sni and writing simple acl to forward request but attention to just write single forntend and backend ,because multi frontend and backend cause a confusing in haproxy.

Request Header (Host attribute) lost/Reset from WebSeal to Apache web server

URL (https://xyz.abc.com/cc) when load balancer see /cc it will forward request to WebSeal (Revers Proxy server).
WebSeal add/set (Header Host : xyz.abc.com) and forward request to Apache2 (web server). In web seal we have standard junction (/cc) which will process the request from LB.
When request comes to Apache2 it loosing HOST header value (xyz.abc.com) and reset it to Apache2 server name (xyzapacheweb1)
Now finally request pass from apache2 to Liferay Portal (6.2) and it showing URL (xyzapacheweb1) instead of (xyz.abc.com)
Liferay need HOST name when web server fronting so we have to hard code URL (in property file or in apache2)
We want to remove Hard-Code value and pass dynamic host name so we can use multiple URLs for individual applications.
Note : When we don't have WebSeal in picture it preserve the HOST name. i.e. Apache2 show actual domain name (xyz.abc.com)
Can you please help me to resolve this problem?
Let me know if you need more info.
If you're using mod_proxy to forward from apache to tomcat you're missing the option
ProxyPreserveHost On
This is because of forwarding through http. If you're using ajp this is automatically taken care of for you by the protocol.
I'm not sure of the equivalent option for webseal though, maybe the apache one helps you to find it
I came up with two solutions.
Temporary :
Set custom header attribute in request from WebSeal i.e. domain-host-name. From LB -> WebSeal set the host value to this variable.
Apache web server is able to retrieve this value because it's not default request header. Based on the domain-host-name value Set Header HOST value from Apache webserver for Liferay.
remove web.server.host.name property in Liferay it will automatically get the HOST value (which was set by Apache).
Set xyz.abc.com if domain-host-name is set to xyz.abc.com
SetEnvIf domain-host xyz.abc.com HAVE_MyRequestHeader
RequestHeader set Host xyz.abc.com env=HAVE_MyRequestHeader
Set abc.xyz.com if domain-host-name is set to abc.xyz.com
SetEnvIf domain-host abc.xyz.com HAVE_MyRequestHeader_1
RequestHeader set Host abc.xyz.com env=HAVE_MyRequestHeader_1
This is a temporary solution because here we have to hardcode host name check in Apache. So if there is new URL then you have to configure it in Apache.
Permanent :
WebSeal has Virtual Junction concept. Where webseal can be configure to play virtual hosting role.
Please refer : http://www-01.ibm.com/support/knowledgecenter/SSPREK_6.1.1/com.ibm.itame.doc_6.1.1/am611_webseal_admin642.htm%23vhost-scenario1?lang=en
Let me know if you are facing similar type issue I can help to resolve it.