Apache and 302 redirect issues - apache

I want to temporary bypass a 302 browser redirect by configuring Apache to rewrite all incoming HTTP requests from an external to an internal address before proxy-ing the request to a tomcat server listening on localhost. Reason being that the internal address is not exposed to the user environment. Ultimately the problem should be solved by reconfiguring the application to not redirect the initial browser request to an internal URL for authentication (the OPENAM XUI login page) but for now a workaround is needed.
My first attempt to achieve this was by using the standard ProxyPass and ProxyPassReverse directives but it seems that a 302 redirect request causes the client to break out of the proxy. My hope is now that that with help of the mod_rewrite engine I can make the redirect request not happening by configuring an internal-to-external http-request "translator". Unfortunately all my attempts to achieve such a setup have failed.
Question: is it possible to rewrite all incoming http requests from "https://external.app-server.com/app1/" to "https://internal.app-server.com/app1/" before the request is proxied to a localhost tomcat instance?
My currrently (not working) Apache config:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^https://internal\.app-server\.com
RewriteRule "^/app1(.\*)" http://localhost:8080/app1$1
RewriteRule "^/openam(.\*)" https://localhost:8081/openam$1
SSLProxyEngine on
ProxyPreserveHost off
# ProxyPass /app1 http://localhost:8080/app1/
ProxyPassReverse /app1 http://localhost:8080/app1/
# ProxyPass /openam http://localhost:8081/openam
ProxyPassReverse /openam http://localhost:8081/openam

You will need 2 VirtualHost configurations.
Scenario:
users connect to https://external.example.com/app1
this proxies to https://internal.example.com/app1
this proxies to Tomcat at localhost:PORT
Your Apache configuration could look like:
Listen 443
# Responds to external.example.com requests
<VirtualHost *:443>
ServerName external.example.com
CustomLog "logs/external.access.log" common
ErrorLog "logs/external.error.log"
LogLevel debug
# TODO SSL directives
ProxyPass "/app1" "https://internal.example.com:8080/app1"
ProxyPassReverse "/app1" "https://internal.example.com:8080/app1"
</VirtualHost>
# Responds to internal.example.com requests
<VirtualHost *:443>
ServerName internal.example.com
CustomLog "logs/internal.access.log" common
ErrorLog "logs/internal.error.log"
LogLevel debug
# TODO SSL directives
ProxyPass "/app1" "http://localhost:8080/"
ProxyPassReverse "/app1" "http://localhost:8080/"
</VirtualHost>
Note: modify the port with the real Tomcat port you are using (instead of 8080).
Note 2: split your logs, it makes debugging must easier.
Note 3: can be used in HTML files, not apache configuration.
Note 4: to comment out a configuration line, put #. I do not know what \# does...
OR
If the server that responds to external.example.com and internal.example.com is the same, you can proxy both to tomcat directly.
You would do it like this:
Listen 443
# Responds to external.example.com requests
<VirtualHost *:443>
ServerName external.example.com
CustomLog "logs/external.access.log" common
ErrorLog "logs/external.error.log"
LogLevel debug
# TODO SSL directives
ProxyPass "/app1" "http://localhost:8080/"
ProxyPassReverse "/app1" "http://localhost:8080/"
</VirtualHost>
# Responds to internal.example.com requests
<VirtualHost *:443>
ServerName internal.example.com
CustomLog "logs/internal.access.log" common
ErrorLog "logs/internal.error.log"
LogLevel debug
# TODO SSL directives
ProxyPass "/app1" "http://localhost:8080/"
ProxyPassReverse "/app1" "http://localhost:8080/"
</VirtualHost>

Related

Apache2 https forward proxy with ProxyRemote

I'm currently trying to set up an Apache2 that (as a temp solution) hands out a .pac file and (kinda) serves as a proxy on the same port.
I say kinda acts as a proxy as it only needs to redirect traffic to the real proxy server.
Here is my virtual host config:
<VirtualHost *:8001>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyRequests On
ProxyVia On
SSLProxyEngine On
<If "req('Host') == '192.168.122.95:8001'">
DirectoryIndex pacfile1.pac
</If>
ProxyRemote "*" "http://xx.xx.xx.xx:3128"
</VirtualHost>
This works for http connections but not for https. I don't need to do any SSL termination on the Apache, just forward everything to the real proxy.
Can anyone help me out why this is not working for https?

Use Apache To Run SSL On Port 8980 Specifically

I have a web service which I access by typing the following URL exactly as is (character for character):
http://10.115.252.127:8980/opennms/login.jsp
The website files are served from /opt/opennms/jetty-webapps/opennms/
My objective is to use Apache (httpd.conf) to force any traffic to this URL to use SSL and no longer HTTP.
I have successfully installed the SSL certificates with no issues.
I have configured a VirtualHost directive to redirect port 80 to 443
Only sites under /var/www/html/* are being successfully redirected.
Example: http://10.115.252.127/numbers successfully redirects to https://10.115.252.127/numbers
http://10.115.252.127/charts successfully redirects to https://10.115.252.127/charts
But, when I type in the URL http://10.115.252.127:8980/opennms/login.jsp it is always served as HTTP...how do I make it served as HTTPS like the others? I have checked the forums and all the posts assume you will always be redirecting port 80 and dont say anything about how to use SSL in the scenario I explained. I have the same issue with another service running on port 3000 http://10.115.252.127:3000/login
===extract from my httpd.conf===
<VirtualHost *:80>
ServerName 10.115.252.127
Redirect permanent / https://10.115.252.127/
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/httpd/conf/ssl.crt/cert_mtocb2500lbscorp.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/mtocb2500-lbscorp.key
ServerName 10.115.252.127
#Documentroot /var/www/html
</VirtualHost>
Based on your confirmation of my understanding, here is what you can do:
############################################################################
Listen 80
# All connections on port 80 are redirected to port 443
<VirtualHost *:80>
ServerName www.example.com
CustomLog "logs/80_access.log" combined
ErrorLog "logs/80_error.log"
Redirect permanent / https://www.example.com
# No documentRoot, no content
</VirtualHost>
############################################################################
Listen 443
# All URI are answered from the documentRoot directory
# EXCEPT /openms, which is proxied to :8980
<VirtualHost *:443>
ServerName www.example.com
# temporary, remove when tests done
LogLevel debug
CustomLog "logs/443_access.log" combined
Errorlog "logs/443_error.log"
SSLEngine on
SSLCertificateFile /etc/httpd/conf/ssl.crt/cert_mtocb2500lbscorp.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/mtocb2500-lbscorp.key
# For your redirection to 8980
ProxyPass /opennms "https://www.example.com:8980/"
ProxyPassReverse /opennms "https://www.example.com:8980/"
documentRoot "/yourdir/apache/htdocs"
DirectoryIndex index.html
</VirtualHost>
Prerequisites
you must load proxy modules
you must load rewrite module
port 8980 is linked to some other software. Apache does not handle 8980.

Reverseproxy Apache configuration is allowing unwanted traffic through the server

To allow the access to a specific server not publicly available, we've structured an architecture with a Apache webserver exposed on internet, and we would like to configure it as Reverse Proxy to redirect only some requests to the private server.
This is the piece of httpd.conf file:
Listen 5000
<VirtualHost *:5000>
ServerAdmin webmaster#localhost
ServerName servername
ErrorLog /etc/httpd/conf/error.log
#<Location />
# ProxyPass "http://...:5000/"
# ProxyPassReverse "http://...:5000"
# Order allow,deny
# Allow from all
#</Location>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass "/" "http://...:5000/" interpolate connectiontimeout=30 timeout=12000
#RewriteRule ^(.*) "http://...:5000/$1"
#ProxyPassMatch ^(.*) "http://...:5000/$1"
ProxyPassReverse "/" "http://...:5000/"
</VirtualHost>
Whenever we put Listen 5000 a lot of undesired traffic pass through the server to other servers on Internet.
In the code above the commented lines are some of attempts I've done.
What is wrong in the configuration that is not blocking the server to works as proxy for everything?
Thank you in advance for the help
IF you want to deny some paths from being proxied you have to use the "!": here is a link to the documentation explaining how to do it http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass

Setup crafter cms studio for access via apache web server proxy and ajp connector

I need to setup crafter cms studio within the authoring part to be able to access from remote host (e.g. VPS). I'm using Tomcat ajp connector via Apache web server proxy.
I've tried do it like adding the virtual host:
<VirtualHost *:80>
ServerName studio
DocumentRoot /home/web-apps/crafter/bin/apache-tomcat/webapps/studio
RewriteEngine On
ProxyPreserveHost On
# Send requests to Engine's Tomcat
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
# This is where errors related to this virtual host are stored
ErrorLog logs/mysite-error.log
# This is where access logs are stored
CustomLog logs/mysite-access.log combined
</VirtualHost>
But not really succeeded. I can see only the default page which always tells me: "Crafter CMS has no site configured for this domain. Please configure the site you want to show or select a site on the authoring environment." when I'm requesting it like http://my_remote_host_ip/studio
Anyone has ever challended problem like this?
What you have looks right. Perhaps you can try:
clearing your cookies for my_remote_host_ip
clearing your browser cache
removing DocumentRoot directive (not really needed in this particular case)
This works for me:
<VirtualHost *:80>
ServerName myserver
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
ErrorLog ${APACHE_LOG_DIR}/authoring-error.log
CustomLog ${APACHE_LOG_DIR}/authoring-access.log combined
</VirtualHost>
<VirtualHost *:443>
ServerName myserver
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/my.crt
SSLCertificateKeyFile /etc/apache2/ssl/my.key
SSLCertificateChainFile /etc/apache2/ssl/their.crt
ProxyPreserveHost On
# Studio
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
ErrorLog ${APACHE_LOG_DIR}/authoring-error.log
CustomLog ${APACHE_LOG_DIR}/authoring-access.log combined
</VirtualHost>
Another approach is to try the community edition on AWS and see if that works with your browser. Then you can look at how that's configured and copy the config: https://aws.amazon.com/marketplace/pp/B08374YPTP?qid=1581949339014&sr=0-2&ref_=srh_res_product_title

Redirect specifc HTTPS request to a specific port with apache

I have a problem to redirect some request to an other port. Here's my configuration:
I have a public domain like XXXX.ddns.net
I have a Rapsbian server with apache and files in my /var/www folders are correctly served (angular website)
On the same Raspbian server there is a REST server running on the 3000 port
This is running on HTTPS with SSL(letsencrypt)
I would like that all requests to XXXX.ddns.net/api/* to be redirected to the 3000 port.
I change the .htaccess file and the rewrite rule seems to works on local but I can't make it working from my internet site. API requests achieve with a error 500.
Here is my current .htaccess file:
RewriteEngine On
RewriteRule ^api/(.*) https://localhost:3000/api/$1 [QSA]
# not sure if it should be http or https in the rule but nothing works
#RewriteRule ^api/(.*) http://localhost:3000/api/$1 [QSA]
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested pattern is file and file doesn't exist, send 404
RewriteCond %{REQUEST_URI} ^(\/[a-z_\-\s0-9\.]+)+\.[a-zA-Z]{2,4}$
RewriteRule ^ - [L,R=404]
Here is my current 000-default-le-ssl.conf file (in /etc/apache2/sites-available):
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ServerName XXXX.ddns.net
SSLCertificateFile /etc/letsencrypt/live/XXXX.ddns.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/XXXX.ddns.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
<Location /api>
ProxyPass http://127.0.0.1:3000/api
ProxyPassReverse http://127.0.0.1:3000/api
</Location>
</VirtualHost>
</IfModule>
If someone could help me to achieve it...
Thanks!
Your self-found solution looks strange to me. You switch on the SSLProxyEngine and than disable all security measures. Is the backend API running under HTTPS and HTTP at port 3000 at the same time? This is not possible.
I use this setup (apache as proxy to backend application) pretty often and would suggest the following configuration:
As I did not understand the purpose of the rewrite directives I left them out. The VirtualHost at port 80 always redirects HTTP requests to HTTPS. If this works add permanent to the directive (permanent is cached by some browsers, see comment in VirtualHost *:80).
The VirtualHost for HTTPS serves content from your DocumentRoot at /var/www/html. The Directory directive takes care that only correctly addressed files are served (no lookups possible). The VirtualHost also provides the proxy for the /api on the same server on port 3000.
It should work for apache 2.4 if your letsencrypt configuration is correct (fill-in the XXXX). Both VirtualHost configurations can be written into a single file, usually located in /etc/apache2/sites-available with a symlink to /etc/apache2/sites-enabled. Please remove/rename your .htaccess file and other configurations before testing this configuration. If you need access control through apache this could also be configured directly in the VirtualHost configuration.
<VirtualHost *:80>
ServerName XXXX.ddns.net
# Always https
Redirect / https://XXXX.ddns.net/
# Redirect permanent / https://XXXX.ddns.net/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName XXXX.ddns.net
# These are your SSL settings; your responsibility
SSLCertificateFile /etc/letsencrypt/live/XXXX.ddns.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/XXXX.ddns.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# Your document root; where the JavaScript application lives
DocumentRoot /var/www/html
<Directory /var/www/html/ >
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride None
Order Allow,Deny
Allow From All
</Directory>
# Reverse proxy settings for api
ProxyRequests Off
ProxyPreserveHost On
<Location /api >
ProxyPass http://127.0.0.1:3000/api
ProxyPassReverse http://127.0.0.1:3000/api
</Location>
</VirtualHost>
Thanks for your help. I don't really know how but it works now!
I dont rember exactly what i did, but the last one was to modify my 000-default-le-ssl.conf file like this:
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
<Location /api>
ProxyPass http://127.0.0.1:3000/api/
ProxyPassReverse http://127.0.0.1:3000/api/
ProxyPass https://127.0.0.1:3000/api/
ProxyPassReverse https://127.0.0.1:3000/api/
</Location>