Proxy balancer and Apache Virtual Host multiple domains - apache

We have the following configuration, one apache HTTP server which proxies AJP requests to an application on another as in the Proxy balancer configuration below.
The problem we have is the application only understands one HOST http header, i.e exampledomain.com, but we require www.exampledomain.com to be rewritten to exampledomain.com however still show the www.exampledomain.com address.
We also have HTTP proxies in between the browser and hitting the Apache server, and do not want this content to be cached!
The following is our configuration:
<Proxy balancer://ajp-cluster>
Order deny,allow
Allow from all
BalancerMember ajp://10.10.10.11:8009
</Proxy>
<VirtualHost *:80>
ServerName exampledomain.com
ServerAlias exampledomain.com *.exampledomain.com
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.exampledomain.com
RewriteRule ^/(.*)$ http://exampledomain.com/$1 [L,R=301,E=nocache:1]
## Set the response header if the "nocache" environment variable is set
## in the RewriteRule above.
Header always set Cache-Control "no-store, no-cache, must-revalidate" env=nocache
## Set Expires too ...
Header always set Expires "Thu, 01 Jan 1970 00:00:00 GMT" env=nocache
ProxyPass / balancer://ajp-cluster/
ProxyPassReverse / balancer://ajp-cluster/
</VirtualHost>

Related

Spinnaker HTTPS configuration through Apache

My Spinnaker is running in Kubernetes with service type: LoadBalancer and added below azure annotations to take internal subnet private ip address to expose service internally.
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-load-balancer-internal-subnet: subnetName
I've one ubuntu VM where Apache is installed. Created self signed certificated and terminated in apache configurations, and I'm able to access apache home page using HTTPS.
Then I've created proxy rule to Spinnaker service IP address. Basically I want to access Spinnaker from Apache HTTPS --> to internally HTTP traffic towards kubernetes service.
Here is Apache configurations:
xxxx#xxxx:/etc/apache2/sites-available$ ls -ltrh
total 28K
-rw-r--r-- 1 root root 1332 Jul 16 18:14 000-default.conf
-rw-r--r-- 1 root root 6338 Jul 16 18:14 default-ssl.conf
drwxr-xr-x 2 root root 4096 Dec 12 17:24 abc
-rw-r--r-- 1 root root 680 Dec 12 13:04 abc.conf
drwxr-xr-x 2 root root 4096 Dec 12 14:29 xyz
-rw-r--r-- 1 root root 1151 Dec 12 13:08 xyz.conf
cat abc/00-redirect-to-https.conf
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^spinnaker$ / [L,R=302]
cat abc.conf
<VirtualHost *:80>
ServerAdmin webmaster#localhost
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/abc_error.log
CustomLog ${APACHE_LOG_DIR}/abc_access.log combined
<IfModule mod_headers.c>
RequestHeader unset X-Forwarded-For
RequestHeader unset X-Forwarded-Host
RequestHeader unset X-Forwarded-Server
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set X-Forwarded-Port "80"
</IfModule>
# Apache will try to set application/json based on mime type
# This behaviour casing problems with empty json responses from spring
RemoveType json
Include sites-available/abc/*.conf
</VirtualHost>
cat xyz/00-spinnaker.conf
ProxyPass /spinnaker balancer://spinnaker
ProxyPassReverse /spinnaker balancer://spinnaker
ProxyRequests Off
AllowEncodedSlashes NoDecode
<Proxy balancer://spinnaker>
BalancerMember http://172.18.1.99:9000/spinnaker loadfactor=1 keepalive=On retry=0
ProxySet lbmethod=bytraffic
</Proxy>
cat xyz.conf
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName FQDN
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/xyz_error.log
CustomLog ${APACHE_LOG_DIR}/xyz_access.log combined
<IfModule mod_headers.c>
RequestHeader unset X-Forwarded-For
RequestHeader unset X-Forwarded-Host
RequestHeader unset X-Forwarded-Server
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</IfModule>
SSLEngine on
SSLProtocol -ALL +TLSv1 +TLSv1.1 +TLSv1.2
SSLHonorCipherOrder On
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
SSLCertificateFile /etc/apache2/certs/ca.cert
SSLCertificateKeyFile /etc/apache2/certs/ca.key
# Apache will try to set application/json based on mime type
# This behaviour casing problems with empty json responses from spring
RemoveType json
Include sites-available/xyz/*.conf
</VirtualHost>
if I request this url in browser https://apacheServerDomainName/spinnaker then it redirects to spinnaker internally,
But then if I want to go any other page in spinnaker say click on projects, applications etc. then it won't work because url will change to https://apacheServerDomainName/applications and this will give 404 because it assumes to get the page from local ubuntu apache server,
whereas that request should also redirect and response from spinnaker.
please advise what kind of apache rewrite rule could help to achieve this requirement or any other suggestion..
Follow these steps
deploy nginx ingress controller
Define Ingress rule for Spinnaker including TLS certificate in a secret
Nginx controller would do TLS termination allowing external connections over HTTPS

Proxy reversing SSL server in Apache

I am struggling with proxy reversing an SSL server in Apache.
Right now I have many websites under many subdomains in one domain.
For example:
gitlab.mydomain.com
nextcloud.mydomain.com
plex.mydomain.com
All the websites use Letsencrypt certificates so they are HTTPS enabled.
The thing is, that so far no server running at my localhost was HTTPS. For example Plex is running as a standalone HTTP server on my localhost which I simply proxy reverse using Apache and in the internet it is secured with Letsencrypt.
Now I need to proxy reverse an already secured HTTP server. Namely Jenkins - it is running with Letsencrypt on my localhost for various reasons. I should also mention that the certificate used to encrypt it on localhost is the same as the certificate I use in Apache.
So my Jenkins is running on port 8443 and my Apache configuration for Jenkins is the following:
# Just to redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName jenkins.mydomain.com
ServerAlias www.jenkins.mydomain.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
<Virtualhost *:443>
ServerName jenkins.mydomain.com
ServerAlias https://jenkins.mydomain.com
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Proxy https://localhost:8443/jenkins*>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /jenkins http://localhost:8443/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8443/jenkins
ProxyPassReverse /jenkins http://jenkins.mydomain.com/jenkins
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Forwarded-Ssl on
RewriteEngine on
RewriteRule "^/$" "/jenkins/" [R]
SSLEngine on
SSLCertificateFile path/to/fullchain.pem
SSLCertificateKeyFile path/to/privkey.pem
</Virtualhost>
However, with this configuration I get an error 502 (Proxy Error):
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /jenkins/.
Reason: Error reading from remote server
The 502 you're getting is because Apache isn't receiving a response from http://localhost:8443/jenkins. This is the first issue that needs to be resolved before anything else can work. Ensure that you are able to access Jenkins by utilizing cURL.
For example: curl http://localhost:8443/jenkins if no response then try curl https://localhost:8443/jenkins if no response there, then I'd take a look and see if Jenkins is configured properly.
There are a couple things I did notice that should be updated in your Virtual Host configuration.
ServerAlias https://jenkins.mydomain.com should be ServerAlias www.jenkins.mydomain.com as https:// should not be included in a ServerAlias directive, plus you may want to be able to get to the site using https://www.jenkins.mydomain.com since that's in the non-https directive. You also most likely will want to include a rewrite in your https virtual host that rewrites www.jenkins.mydomain.com to jenkins.mydomain.com.
You probably don't need the second ProxyPassReverse directive.

Apache configurations to restrict requests with specific string in request URL

I have one URL configured on Apache. Here is configuration
<VirtualHost 192.168.1.82:443>
ServerName test.ex.com
Header always set Strict-transport-Security "max-age=63072000; includeSubDomain; preload"
Header always append X-Frame-Options SAMEORIGIN
Header set X-XSS-Protection: "1; mode=block"
ProxyRequests On
ProxyPass /cong http://192.168.4.185:8081/cong
ProxyPassReverse /cong http://192.168.4.185:8081/cong
ErrorLog logs/test.ex.com-error_log
CustomLog logs/test.ex.com-access_log common
SSLEngine on
SSLCertificateFile /etc/httpd/*.ex.com/36287365__.ex.com.cert
SSLCertificateKeyFile /etc/httpd/*.ex.com/36287365__.ex.com.key
Header add P3P "CP=\"NOI DSP COR CURa ADMa DEVa OUR IND OTC\""
</VirtualHost>
With above configurations, I am allowing all the request comes to https://test.ex.com/cong/. I want to restrict some specific request comes with string "getUserPattern" in request string like https://test.ex.com/cong/module/getUserPattern/final
Tried with ProxyBlock getUserPattern but didn't work. Is there any way/configuration to restrict such URLs at apache level only or redirect to https://test.ex.com/cong.
First, you probably want to disable forward (standard) proxy requests (Setting ProxyRequests to Off does not disable use of the ProxyPass directive):
ProxyRequests Off
If you want to redirect any request containing getUserPattern to https://test.ex.com/cong, add these two directives above your current ProxyPass rules:
RedirectMatch "getUserPattern" "https://test.ex.com/cong"
ProxyPassMatch "getUserPattern" !

WebSocket through SSL with Apache reverse proxy

On the client side, I am trying to establish the wss connection:
var ws = new WebSocket("wss://wsserver.com/test")
and it returns an error:
WebSocket connection to 'wss://wsserver.com/test' failed: Error during WebSocket handshake: Unexpected response code: 400
The full headers are:
Request Headers
GET wss://wsserver.com/test HTTP/1.1
Host: wsserver.com
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: https://website.net
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
Sec-WebSocket-Key: Tj9AJ5TKglNf5LoHsQTpvQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:https://website.net
Connection:close
Content-Length:18
Content-Type:text/plain; charset=utf-8
Date:Fri, 21 Apr 2017 21:03:45 GMT
Server:Apache/2.4.18 (Ubuntu)
Vary:Origin
X-Content-Type-Options:nosniff
The server side is running on go at port 8888 behind an Apache reverse proxy. This is the Apache configuration:
<VirtualHost *:443>
ServerName website.com
ProxyPreserveHost On
ProxyRequests Off
ProxyPass "/" "wss://localhost:8888/"
mod_proxy and mod_proxy_wstunnel are installed.
Is there something missing here? It seems like the request goes through but no connection is established.
I ended up solving this problem by using this configuration for the virtual host, which filters requests using the HTTP headers:
<VirtualHost *:443>
ServerName website.com
RewriteEngine On
# When Upgrade:websocket header is present, redirect to ws
# Using NC flag (case-insensitive) as some browsers will pass Websocket
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule ^/ws/(.*) wss://localhost:8888/ws/$1 [P,L]
# All other requests go to http
ProxyPass "/" "http://localhost:8888/"
I'm leaving this as a reference in case it helps others
In order to place a secure reverse proxy server in front of an insecure websocket server, you could do this:
<VirtualHost *:443>
SSLEngine on
SSLProxyEngine on
SSLProtocol -all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
SSLCipherSuite HIGH:aNULL:eNULL:EXPORT:DES:RC4:!MD5:!PSK:!SRP:!CAMELLIA
SSLCertificateFile /path/to/cert
SSLCertificateKeyFile /path/to/key
SSLCertificateChainFile /path/to/chain
ServerName website.com
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:8888/$1 [P,L]
</VirtualHost>
This will take a request inbound for wss://website.com:443, and reverse proxy it to ws://localhost:8888.
If the websocket server is also secure, you can simply change
ws://localhost:8888 to
wss://website.com:8888
This is my setup of virtualhost that worked for me, I have .netcore app on docker with SignalR as a websocket service.
On 5000 my .netcore app is running, and on /chatHub my signalR listens.
Will be helpful for future comers with same problem.
<IfModule mod_ssl.c>
<VirtualHost *:443>
RewriteEngine On
ProxyPreserveHost On
ProxyRequests Off
# allow for upgrading to websockets
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:5000/$1 [P,L]
ProxyPass "/" "http://localhost:5000/"
ProxyPassReverse "/" "http://localhost:5000/"
ProxyPass "/chatHub" "ws://localhost:5000/chatHub"
ProxyPassReverse "/chatHub" "ws://localhost:5000/chatHub"
ServerName site.com
SSLCertificateFile /etc/letsencrypt/live/site.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/site.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Source: http://shyammakwana.me/server/websockets-with-apache-reverse-proxy-with-ssl.html
# pimgeek's Comment:
I think instead of
RewriteRule ^/nodered/comms wss://localhost:1880/nodered/comms [P,L]
you could have utilized $1 as follow:
RewriteRule ^/nodered/comms$ wss://localhost:1880/$1 [P,L]
Also, this should work aswell:
RewriteRule ^/nodered/comms$ wss://localhost:1880$1 [P,L]
Notice the not needed / after the port, since $1 includes already a / at the beginning
In my case, I needed to activate "SSLProxyEngine on" to make the whole thing works...
I ended up with this 2 lines solution on Debian / Apache 2.4 (used port is 4321)
SSLProxyEngine on
ProxyPass /wss wss://127.0.0.1:4321/

Apache No 'Access-Control-Allow-Origin' header

I tried to search between old questions but i didn't find how to figure out my issue
I have a LF site; all works pretty good; when i go on http://localhost:8080/ i have no problem and no error is shown on firebug and/or chrome console
I configured then, an Apache HTTP Server. All seems to me correct but when i try the URL http://localhost I see my site but some resources are not loaded. In chrome console (but also in firebug) I get the following error:
2(index):1 Font from origin 'http://localhost:8080' has been blocked
from loading by Cross-Origin Resource Sharing policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
I don't know how to figure out this issue. It seems to me an Apache configuration mistake.
This is my virtual host configuration:
<VirtualHost *:80>
#CORS
<Directory "/var/www/">
AllowOverride All
Order allow,deny
allow from all
</Directory>
# Always set these headers.
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
# Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request.
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
ProxyPass /c http://localhost:8080/c
ProxyPassReverse /c http://localhost:8080/c
ProxyPass /si http://localhost:8080/si
ProxyPassReverse /si http://localhost:8080/si
ProxyPass /image http://localhost:8080/image
ProxyPassReverse /image http://localhost:8080/image
ProxyPass /documents http://localhost:8080/documents
ProxyPassReverse /documents http://localhost:8080/documents
ProxyPass /html http://localhost:8080/html
ProxyPassReverse /html http://localhost:8080/html
ProxyPass /sprite http://localhost:8080/sprite
ProxyPassReverse /sprite http://localhost:8080/sprite
ProxyPass /combo http://localhost:8080/combo
ProxyPassReverse /combo http://localhost:8080/combo
ProxyPass / http://localhost:8080/web/mySimpleLog
ProxyPassReverse / http://localhost:8080/web/mySimpleLog
ErrorLog logs/mySimpleLog-error_log
CustomLog logs/mySimpleLog-access_log common
</VirtualHost>
It seems to me all correct... is there any other option i should put?
Do you have any idea where I'm wrong?
Thank you
Angelo
You're setting your CORS headers only on port 80, but the cross-origin part is from port 80 to port 8080 -- you should move the Header set ... outside of virtual host context or duplicate it in your 8080 vhost.