mod_rewrite for trailing slash problem - apache

I'm pulling my hair out on what should be an insanely simple problem. We are running WebSphere IHS (Apache) through an F5 BigIP. BigIP is doing the https translation for us. Our url (changed for web, not valid) is https://superniftyserver.com/lawson/portal.
When someone types in just that without the slash after portal, Apache assumes "portal" to be a file and not a directory. When Apache finds out what it is, it sends the 301 Permanent Redirect. But since Apache knows only http, it sends the URL as http://superniftyserver.com/lawson/portal/ which then creates problems.
So I tried a server level httpd.conf change for mod_rewrite, this is one of the dozens of combinations I've tried.
RewriteEngine on
RewriteRule ^/lawson/portal(.*) /lawson/portal/$1
I also tried
RewriteRule ^/lawson/portal$ /lawson/portal/
Among many other things... What am I missing?

If you can't get an answer on the RewriteRule syntax, here are two other options for you: Write an custom iRule on BigIp (see F5 DevCentral) that looks for 301 responses and convert them to SSL; let the URL pass into your WebSphere server and do a programmatic redirect that sends out HTTPS. However, because F5 terminates the SSL connection, you have to set a custom header that you configure (see PQ86347) so the Java request.getScheme() works as you would expect.

Fixed!
SOL6912: Configuring an HTTP profile to rewrite URLs so that redirects from an HTTP server specify the HTTPS protocol
Updated: 8/7/07 12:00 AM
A ClientSSL virtual server is typically configured to accept HTTPS connections from a client, decrypt the SSL session, and send the unencrypted HTTP request to the web server.
When a requested URI does not include a trailing slash (a forward slash, such as /, at the end of the URI), some web servers generate a courtesy redirect. Without a trailing slash, the web server will first treat the resource specified in the URI as a file. If the file cannot be found, the web server may search for a directory with the same name and if found, send an HTTP 302 redirect response back to the client with a trailing slash. The redirect will be returned to the client in HTTP mode rather than HTTPS, causing the SSL session to fail.
Following is an example of how an HTTP 302 redirect response causes the SSL session to fail:
· To request an SSL session, a user types https://www.f5.com/stuff without a trailing slash.
· The client browser sends an SSL request to the ClientSSL virtual server, which resides on the BIG-IP LTM system.
· The BIG-IP LTM system then decrypts the request and sends a GET /stuff command to the web server.
· Since the /stuff file does not exist on the web server, but a /stuff/ virtual directory exists, the web server sends an HTTP 302 redirect response for the directory, but appends a trailing slash to the resource. When the web server sends the HTTP 302 redirect response, it specifies HTTP (not HTTPS).
· When the client receives the HTTP 302 redirect response, it sends a new request to the BIG-IP LTM virtual server that specifies HTTP (not HTTPS). As a result, the SSL connection fails.
Configuring an HTTP profile to rewrite URLs
In BIG-IP LTM version 9.x you can configure an HTTP profile to rewrite URLs so that redirects from an HTTP server specify the HTTPS protocol. To do so, perform the following procedure:
Log in to the Configuration utility.
Click Local Traffic.
Click Profiles.
Click the Create button.
Type a name for the profile.
Choose http from the Parent Profile drop-down menu.
Under Settings, set Redirect Rewrite to All, Matching, or Nodes, depending upon your configuration
For example:
o Choose All to rewrite any HTTP 301, 302, 303, 305, or 307 redirects to HTTPS
o Choose Matching to rewrite redirects when the path and query URI components of the request and the redirect are identical (except for the trailing slash)
o Choose Node to rewrite redirects when the redirect URI contains a node IP address instead of a host name, and you want the system to change it to the virtual server address
Click Finished.
You must now associate the new HTTP profile with the ClientSSL virtual server.

Try this:
# Trailing slash problem
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ https://<t:sitename/>$1/ [redirect,last]

LoadModule rewrite_module modules/mod_rewrite.so
make sure that line is somewhere in you httpd.conf file

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/lawson/portal$ RewriteRule ^(.*)$ https://superniftyserver.com/lawson/portal/ [R=301,L]

Related

.htaccess redirect to a new domain WITHOUT reload the page

Currently, I'm making a website and I would like this site to redirect (via .htaccess) to another domain WITHOUT reloading the page. Because in all the tutorials I saw, it loaded the page of the new domain. Outside what I want is that it keeps the page of the base domain while displaying the URL of the new domain.
Example:
redirect this site
https://DOMAIN1.US/folder1/folder2/page.html?param=1&param=2
to this site
https://DOMAIN2.US/folder1/folder2/page.html?param=1&param=2
i dont have the access to the main server config. Htaccess cannot "fake redirect" ??
What you are asking for is not a simple "redirect" (which is managed by the browser). You need to configure the server that hosts domain1.com as a "reverse proxy" - since this needs to be managed entirely server-side.
The user sends a request to domain1.com. The server at domain1.com then constructs an internal HTTP request (reverse proxy) to domain2.com. The response from domain2.com is then sent back to the server at domain1.com which then forwards the (possibly "rewritten") response back to the client.
This requires additional modules enabled on the server at domain1.com, ie. mod_proxy, mod_proxy_http and additional (optional) modules such as mod_proxy_html, etc. depending on your requirements.
Ideally, you would then configure this in the server config (or VirtualHost container). Notably, you would need to set ProxyPassReverse (in the server config) to cover the scenario of domain2.com issuing an external redirect to itself. The proxy server needs to rewrite the response headers so that the redirect goes to domain1.com, not domain2.com. ProxyPassReverse cannot be set in .htaccess.
You can then use mod_rewrite with mod_proxy by using the P flag. This part you can do in .htaccess. For example, to proxy the request from https://DOMAIN1.US/folder1/folder2/page.html?param=1&param=2 to https://DOMAIN2.US/folder1/folder2/page.html?param=1&param=2.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?domain1\.us [NC]
RewriteRule ^ https://domain2.us%{REQUEST_URI} [P]
If you have access to the server config then you can do this more simply with the ProxyPass directive (no need for mod_rewrite in this instance since the source and target URLs are the same).
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html

AWS ALB redirect to https

My Apache servers are behind an ALB/ELB. I'm terminating SSL at the load balancer. The load balancer listens on both 80 and 443. I want to redirect all http requests to https.
I have this rewrite rule in place in the vhost config:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
This works, but the issue is that I also have redirects in an htaccess file. When a redirect happens through the htaccess file, it redirects to http first and then the vhost config redirect picks it up and redirects to https. I want to eliminate the extra http redirect.
http://mysite.example.com/sub
301
https://mysite.example.com/sub
301
http://mysite.example.com/newsub - this redirect is htaccess
301
https://mysite.example.com/newsub
200
I'd like to gracefully get around having the htaccess redirect to http first. I can get around this by adding https://%{HTTP:Host} to rewrite rules. Is this the best way to do this:
RewriteRule ^sub$ https://%{HTTP:Host}/newsub [R=301,L]
Application Load Balancer now supports two new actions: redirect and fixed-response. You can configure these actions as part of the content-based routing rules, enabling you to offload this functionality to the load balancer. This simplifies deployments while benefiting from the scale, the availability, and the reliability of Elastic Load Balancing.
Here's what I did to make it work on AWS:
Example configuration for ALB redirection - HTTP -> HTTPS
https://aws.amazon.com/about-aws/whats-new/2018/07/elastic-load-balancing-announces-support-for-redirects-and-fixed-responses-for-application-load-balancer/
If your web servers are running behind an AWS Application Load Balancer and you configured at least one listener for HTTP port 80, you can redirect http to https directly by doing this:
Go to EC2 Console, then Load Balancing and Load Balancers from left menu.
Click on your ALB name checkbox, then select Listeners Tab. If you create two listeners for HTTP and HTTPS go to step 4.
If you did not set a HTTPS Listener on Load Balancer's first creation, then click on Add Listener. Choose HTTPS and Port (443 usually). In Default action(s) select Forward to... option and then your Target Group for your Load Balancer. Weight it's ok in 1. Choose the appropriate Security policy and then add your Default SSL certificate for your case (you must have a ssl certificate registered on AWS Certificate Manager or AWS IAM). Then click on Save. Test your settings going to https://load-balancer-dns-name or https://your-server-dns-name
To configure HTTP redirection, select the HTTP:80 checkbox and click on Edit button. In the Default action(s) click the thrash icon to remove Forward to current setting. Then click on Add action and select Redirect to option. Common values for this section are HTTPS, 443 port, Original host, path, query and 301 - Permanently moved. Finally, click on Update button at the right top of the page.
Now test going to http://load-balancer-dns-name or http://your-server-dns-name and you will be redirected to HTTPS.
Hope it helps!

Redirection on Apache (Maintain POST params)

I have Apache installed on my server and I need to redirect from http to https. The reason for this is our load balancer solution cannot hand https so requests come in on http and then we transfer them to https using the below lines in the httpd.conf file.
<VirtualHost 10.1.2.91:80>
Redirect 302 /GladQE/link https://glad-test.com/GladQE/link.do
</VirtualHost>
This works fine for GET requests but POST requests will lose the parameters passed on the URL. What would be the easiest way to perform this redirect and maintain POST params?
I need to get from http://glad-test.com/GladQE/link.do to here https://glad-test.com/GladQE/link.do maintaining POST params
Thanks
Tom
You can try with the HTTP status code 307, a RFC compilant browser should repeat the post request.
Reference: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
In contrast to how 302 was historically implemented, the request
method is not allowed to be changed when reissuing the original
request. For instance, a POST request should be repeated using another
POST request.
To change from 302 to 307, do that:
<VirtualHost 10.1.2.91:80>
Redirect 307 /GladQE/link https://glad-test.com/GladQE/link.do
</VirtualHost>
Standard Apache redirects will not be able to handle POST data as they work on the URL level. POST data is passed in the body of the request, which gets dropped if you do a standard redirect.
You have an option of either using a PHP script to transparently forward the POST request, or using a combination of Rewrite (mod_rewrite) and Proxy (mod_proxy) modules for Apache like follows:
RewriteEngine On
RewriteRule /proxy/(.*)$ http://www.example.com/$1 [P,L]
P flag passes the request to the Proxy module, so anything that comes to your site (via GET or POST doesn't matter) with a URL path starting with a /proxy/ will transparently be handled as a proxy redirect to http://www.example.com/.
For the reference:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
http://httpd.apache.org/docs/current/mod/mod_proxy.html
Either your public facing website MUST use SSL to protect confidentiality or there is no sensitive data enver passing through it, and no possibility that your site will ever be used for a lauinchboard for sslstripping (there's a very good reason why Google serve up search results over HTTPS).
If you are not encrypting traffic between browser and your site then why are you trying to encrypt them between your load balancer and your webserver? If you do happen to have a SSL termination outside the load balancer (a very silly approach) then using HTTPS between the load balancer and the webserver is far from efficient. The question also implies lots of other security problems like session fixation/sniffing and SSLStripping vulnerabilities.

Level of obscurity of destination URLs via mod_rewrite

To achieve a single layer of content delivery security, I'm looking into the possibility of obscuring a resource URL via an .htaccess RewriteRule:
RewriteEngine on
RewriteBase /js/
RewriteRule obscure-alias\.js http://example.com/sensitive.js
It would of course be implemented as:
<script type="text/javascript" src="obscure-alias.js"></script>
Because this is not a 301 redirect, but rather a routing scenario similar to that of many of our frameworks we used today, would it be safe to say that this RewriteRule adequately obfuscates the actual URL where this resource is located, or:
Can the destination URL still be found out via some HTTP header sniffing utility
Might a web browser be able to reveal the "Download URL"
I'm going to pre-answer my own questions by saying no to both since the "internal proxy" is taking place on the server-side and not on the client side if I understand it correctly: http://httpd.apache.org/docs/current/mod/mod_rewrite.html. I just wanted to confirm that when Apache goes to serve the destination URL, that it also isn't passing along information to the user agent what the URL was that it rewrote the original request as.
It depends on how you specify the redirect target.
If your http://example.com/ is running on the same server, there will be an internal redirect that is invisible to the client. From the manual:
Absolute URL
If an absolute URL is specified, mod_rewrite checks to see whether the hostname matches the current host. If it does, the scheme and hostname are stripped out and the resulting path is treated as a URL-path. Otherwise, an external redirect is performed for the given URL. To force an external redirect back to the current host, see the [R] flag below.
if the absolute URL points to a remote domain, a header redirect will be performed. A header redirect is visible to the client and will reveal the sensitive location.
To make sure no external redirect takes place, specify a relative URL like
RewriteRule obscure-alias\.js sensitive.js
Note that the sensitive JS file's URL can still be guessed.
To find out whether a request results in a header redirect, log in onto a terminal (eg. on a Linux server) and do
wget --server-response http://www.example.com
If the first HTTP/.... line (there may be more than one) is something that begins with a 3xx, like
HTTP request sent, awaiting response...
HTTP/1.1 302 Moved Temporarily
you are looking at a header redirect.
Possible using proxy throughput.
See http://httpd.apache.org/docs/2.4/rewrite/proxy.html
Also alluded to here as well: mod_rewrite not working as internal proxy

Apache rewrite rule - prevent rewritten URL appearing in browser URL bar

I have a rewrite rule which is looking for a particular URI. When it matches the particular URL it rewrites it with a proper file path so the required content can be found. It then changes the protocol to HTTPS and allows the request to pass through.
I have two problems;
I don't want the rewritten path to appear in the users browser - i want to maintain the vanity url
I do want the HTTPS protocol to appear indicating to the user that they are accessing the site over a secured conection.
I have tried a couple of options but no success. If i include the [R] flag the URL and protocol remain unchanged but that is not the desired effect
Any suggestions on how i can achieve this?
This is my rule;
RewriteMap redirectsIfSecure txt:/myserver/content/secure_urls.txt
RewriteCond ${lowercase:%{REQUEST_URI}} ^/(.+)$
RewriteCond ${redirectsIfSecure:%1|NOT_FOUND} !NOT_FOUND
RewriteRule ^(.*)$ https://myserver.com${redirectsIfSecure:%1} [PT]
From the mod_rewrite documentation:
If an absolute URL is specified, mod_rewrite checks to see whether the
hostname matches the current host. If it does, the scheme and hostname
are stripped out and the resulting path is treated as a URL-path.
Otherwise, an external redirect is performed for the given URL. To
force an external redirect back to the current host, see the [R] flag
below.
If you rewrite the request to a fully qualified URL (that is, anything starting with http://, https://, etc) that doesn't match your ServerName, then mod_rewrite will issue an HTTP redirect, which will cause the client browser to request the resource from the new location.
If you're not trying to switch between http and https you can use a proxy rule (the P flag) to have Apache make the request on behalf of the client and return the result, thus masking the rewritten URL.
However, if you're trying to upgrade from http to https (or the other way around), this will always require a client redirect.