apache rewrite rule for URL - apache

My java application is deployed on tomcat and i am using rewrite rule from apache to access the application using apache.
My application name is my.war deployed on tomcat/webapps/my/
i am using following rewrite rule in httpd.conf
RewriteEngine On
ProxyPreserveHost On
RewriteRule ^/$ \
http://localhost:8082/my [P]
RewriteRule ^/(my/.*)$ \
http://localhost:8082/$1 [P,R,L]
when i open www.mydomain.com/ it changed the url to www.mydomain.com/my/
i don't want this , i want the url be www.mydomain.com/ and it should open the landing page of my application.

You should use mod_proxy's ProxyPass instead:
ProxyPass / http://localhost:8082/my/

You need to install the application as your "ROOT" application on tomcat. Tomcat will automatically make that .war the base URL when you land on tomcat. To do this, just rename your "my.war" to "ROOT.war" and redeploy it.
Note, on some Tomcat instances, there will be a pre-installed default "ROOT" application for managing some Tomcat settings and apps via a web UI. Deploying your own ROOT.war will naturally replace this utility.

Related

How to fix directory traversal vulnerability on Tomcat 9

I have a JEE service on a Tomcat 9 container (Debian 10.8). In front of it an Apache Web Server + mod_proxy_ajp.
In my VH I do not have any ProxyPass rule for /manager/html context but if on a Web client I rewrite my URL adding /..;/manager/html (e.g.: https://www.example.org/site/..;/manager/html) the Tomcat Manager asks for crediatials.
Is there a trick to avoid it? Maybe using modsecurity?
Thanks.
I solved the problem using a mod_security rules:
SecRule REQUEST_URI "#rx ..;/" "phase:1,severity:'CRITICAL',deny,id:129"
It works.
Since path parameters are only used in Tomcat for session tracking (as an alternative to cookies), you can safely remove them in Apache2 from the .. path segment :
RewriteEngine on
RewriteRule ^(.*)/\.\.;[^/]*(.*)$ $1/..$2 [N]
Alternatively you can remove them altogether:
RewriteEngine on
RewriteRule ^(.*);[^/]*(.*)$ $1$2 [N]
and configure Tomcat to use only cookies for session tracking in $CATALINA_BASE/conf/web.xml:
<session-config>
...
<tracking-mode>COOKIE</tracking-mode>
</session-config>

apache2 - RewriteRule just change the name

I have a folder with content in it. URL to it: http://www.example.com/something/
Is it possible now to rewrite the URL to this: http://www.example.com/learning/?
If yes, how?
Note: Folder something has some subfolders and a lot of HTML and PHP Files, including CSS and JS stuff.
Second note:: I can just edit my httpd.conf
Edit:
I'm using apache2 and jboss. apache2 just for the proxy and rewrite module. So my jboss application can be reached at this location: http://www.example.com:1231/something/.
I just defined that the jboss application ca be reached under port 80 at this url http://www.example.com/something/.
Now i wanna do the redirect like above.
This should work:
RewriteEngine On
RewriteRule ^/something(.*) http://www.example.com:1234/learning$1 [P]

Configure apache on elastic beanstalk

I'm developing with django on elastic beanstalk and I want to make two changes to apache configuration:
1.
redirect www.domain.com to domain.com
2.
redirect http://domain.com to https://domain.com
I don't have experience with apache configuration, googling it gave me the idea that I should put RewriteRules in .htaccess file.
example:
How to force https on amazon elastic beanstalk without failing the health check
I couldn't find instructions on how to do it with elastic beanstalk configuration (.ebextensions), I tried to simply put a .htaccess file in my root filder and deploy but it didn't work.
Does anyone know how it's possible to add the RewriteRules in elastic beanstalk?
Having www.example.com go to example.com can be done with a CNAME in DNS if you don't care about having it actually being a redirect. If you need a redirect, you can add it to the Apache config below. The primary point of this answer is to detail how you modify Apache config on Elastic Beanstalk (because doing this properly is not very straight forward).
This answer assumes you have already enabled https in the load balancer security group, added the SSL certificate to the load balancer, added 443 to the ports forwarded by the load balancer, and pointed your domain name at the Elastic Beanstalk environment with Route 53 (or equivalent DNS service).
Amazon Linux 2
Most AWS Linux version 2 based platforms have the option to pick Apache as your proxy host. This can be done by going to "Configuration" > "Software" >
"Container Options" and setting "Proxy Server" to "Apache", or adding the following to one of your .config files in .ebextensions:
option_settings:
aws:elasticbeanstalk:environment:proxy:
ProxyServer: apache
On AWS Linux 2, Apache is configured exclusively through adding files to your codebase in .plaform/httpd/conf.d/, from which they will get added to the server's Apache config. You can no longer edit Apache files through .ebextensions.
To do an HTTP to HTTPS redirect using Apache, add a configuration file named .platform/httpd/conf.d/ssl_rewrite.conf to your codebase (relevant AWS docs) with the following contents:
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
Note that nginx can be configured in a similar way, namely by adding a .conf file to .platform/nginx/conf.d/ (though the contents of this file will obviously be different).
Amazon Linux 1
All you need to do is add the following to one of your .config files in the .ebextensions directory of your project:
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
Explanation
This is moderately straight forward outside of Elastic Beanstalk. One usually adds an Apache rewrite rule like the following:
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Or, if behind a load balancer, like we are in this case:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
However, these configurations only work within a <VirtualHost> block. Changing the RewriteCond to an <If> block allows it to work properly outside of a <VirtualHost> block, allowing us to put in in a standalone Apache config file. Note that standard Apache setup on CentOS (including the setup on ElasticBeanstalk) inculdes all files matching /etc/httpd/conf.d/*.conf, which matches the file path where we are storing this file.
The -n '%{HTTP:X-Forwarded-Proto}' part of the condition prevents it from redirecting if you are not behind a load balancer, allowing you to have shared configuration between a production evironment with a load balancer and https, and a staging environment that is single instance and does not have https. This is not necessary if you are using load balancers and https on all of your environments, but it doesn't hurt to have it.
Bad solutions I have seen
I have seen a lot of bad solutions to this problem, and it is worth going through them to understand why this solution is necessary.
Use Cloudfront: Some people suggest using non-cached Cloudfront setup in front of Elastic Beanstalk to do the HTTP to HTTPS redirect. This adds a whole new service (thus adding complexity) that isn't exactly appropriate (Cloudfront is a CDN; it's not the right tool for forcing HTTPS on inherantly dynamic content). Apache config is the normal solution to this problem and Elastic Beanstalk uses Apache, so that's the way we should go.
SSH into the server and...: This is completely antithetical to the point of Elastic Beanstalk and has so many problems. Any new instances created by autoscaling won't have the modified configuration. Any cloned environments won't have the configuration. Any number of a reasonable set of environment changes will wipe out the configuration. This is just such a bad idea.
Overwrite the Apache config with a new file: This is getting into the right realm of solution but leaves you with a maintenance nightmare if Elastic Beanstalk changes aspects of the server setup (which they very well may do). Also see the problems in the next item.
Dynamically edit the Apache config file to add a few lines: This is a decent idea. The problems with this is that it won't work if Elastic Beanstalk ever changes the name of their default Apache config file, and that this file can get overwritten when you least expect: https://forums.aws.amazon.com/thread.jspa?threadID=163369
this is an easy solution
ssh into your EC2 instance
copy the contents of /etc/httpd/conf.d/wsgi.conf into a local file called wsgi.conf which will be placed in the base folder of your application
Edit the local version of wsgi.conf and add the following redirect rules within the < VirtualHost> < /VirtualHost> tags
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
Change the “/status” to whatever page you are using as a health check page.
Save the file
Edit your < app>.conf file inside your .ebextensions directory to add a container command to copy this version of wsgi.conf over Amazon’s version
container_commands:
01_syncdb:
command: "django-admin.py syncdb --noinput" leader_only: true
02_collectstatic:
command: "django-admin.py collectstatic --noinput"
03_wsgireplace:
command: 'cp wsgi.conf /etc/httpd/conf.d/wsgi.conf'
...
Deploy the code.
The deployed version of wsgi.conf at /etc/httpd/conf.d/wsgi.conf will now include the necessary redirect rules.
It should work and the file will be properly updated for each deployment. The only thing to watch for is if Amazon changes their base wsgi.conf file contents in the future, then your copy may no longer work.
Source : rickchristianson
This is very well explained in AWS documentation as below:
To extend the Elastic Beanstalk default Apache configuration, add .conf configuration files to a folder named .ebextensions/httpd/conf.d in your application source bundle. The Elastic Beanstalk Apache configuration includes .conf files in this folder automatically.
~/workspace/my-app/
|-- .ebextensions
| -- httpd
| -- conf.d
| -- myconf.conf
| -- ssl.conf
-- index.jsp
To override the Elastic Beanstalk default Apache configuration completely, include a configuration in your source bundle at .ebextensions/httpd/conf/httpd.conf.
~/workspace/my-app/
|-- .ebextensions
| `-- httpd
| `-- conf
| `-- httpd.conf
`-- index.jsp
If you override the Elastic Beanstalk Apache configuration, add the following lines to your httpd.conf to pull in the Elastic Beanstalk configurations for Enhanced health reporting and monitoring, response compression, and static files.
IncludeOptional conf.d/*.conf
IncludeOptional conf.d/elasticbeanstalk/*.conf
Note
To override the default listener on port 80, include a file named
00_application.conf at
.ebextensions/httpd/conf.d/elasticbeanstalk/ to overwrite the
Elastic Beanstalk configuration.
For a working example, take a look at the Elastic Beanstalk default configuration file at /etc/httpd/conf/httpd.conf on an instance in your environment. All files in the .ebextensions/httpd folder in your source bundle are copied to /etc/httpd during deployments.
Further details can be seen on this link under Extending and overriding the default Apache configuration. Better to use correct approach instead of patches or workarounds.
Just for reference for others, using Zags' solution to redirect non-www to www, add this to your .ebextensions/your_file.config:
files:
"/etc/httpd/conf.d/www_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
<If "'%{HTTP_HOST}' !~ /^www\./">
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</If>

How to force https on elastic beanstalk?

I can't seem to force https on the free usage tier of elastic beanstalk.
I have tried the following suggestion at How to force https on amazon elastic beanstalk without failing the health check
Using this Apache rewrite rule
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} !^/status$
RewriteCond %{REQUEST_URI} !^/version$
RewriteCond %{REQUEST_URI} !^/_hostmanager/
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
When I try that, http requests do not get redirected to https as I would like. Instead, the http page loads normally. I've also tried to use the X-Forwarded-Port header with the same result.
I've also tried the following rewrite rule
RewriteCond %{SERVER_PORT} 80
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
And this rule causes a redirect loop. So it would seem that the apache rewrite rules don't pick up the Elastic Load Balancer headers X-Forwarded-Port and X-Forwarded-Proto, but also a redirect loop isn't what I am going for either.
Please help. I am new to AWS, Elastic Beanstalk, and not very familiar with Apache rules. I am not too sure where to go from here. Thanks.
This answer assumes you have already enabled https in the load balancer security group, added the SSL certificate to the load balancer, have both ports 80 and 443 being forwarded by the load balancer, and pointed your domain name at the Elastic Beanstalk environment with Route 53 (or equivalent DNS service).
Option 1: Do the redirect with Apache
This is only possible if you are on an Elastic Beanstalk environment that uses Apache (AWS Linux 2 based deployments can be configured to use Apache). It may not work for a docker-based deployment.
Amazon Linux 2
Most AWS Linux version 2 based platforms have the option to pick Apache as your proxy host. This can be done by going to "Configuration" > "Software" >
"Container Options" and setting "Proxy Server" to "Apache", or adding the following to one of your .config files in .ebextensions:
option_settings:
aws:elasticbeanstalk:environment:proxy:
ProxyServer: apache
Having done that, add a configuration file named .platform/httpd/conf.d/ssl_rewrite.conf to your codebase (relevant AWS docs) with the following contents:
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
Amazon Linux 1
All you need to do is add the following to one of your .config files in the .ebextensions directory of your project:
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
Explanation
This is moderately straight forward outside of Elastic Beanstalk. One usually adds an Apache rewrite rule like the following:
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Or, if behind a load balancer, like we are in this case:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
However, these configurations only work within a <VirtualHost> block. Changing the RewriteCond to an <If> block allows it to work properly outside of a <VirtualHost> block, allowing us to put in in a standalone Apache config file. Note that standard Apache setup on CentOS (including the setup on ElasticBeanstalk) inculdes all files matching /etc/httpd/conf.d/*.conf, which matches the file path where we are storing this file.
The -n '%{HTTP:X-Forwarded-Proto}' part of the condition prevents it from redirecting if you are not behind a load balancer, allowing you to have shared configuration between a production evironment with a load balancer and https, and a staging environment that is single instance and does not have https. This is not necessary if you are using load balancers and https on all of your environments, but it doesn't hurt to have it.
Option 2: Do the redirect with the ALB
This is only possible if you are using an Application Load Balancer. Amazon has instructions for how to do that here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html
All you need to do is add the following to one of your .config files in the .ebextensions directory of your project to replace the http listener with a redirect:
Resources:
AWSEBV2LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn:
Ref: AWSEBV2LoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: redirect
RedirectConfig:
Host: "#{host}"
Path: "/#{path}"
Port: "443"
Protocol: "HTTPS"
Query: "#{query}"
StatusCode: "HTTP_301"
Bad solutions I have seen
I have seen a lot of bad solutions to this problem, and it is worth going through them to understand why this solution is necessary.
Use Cloudfront: Some people suggest using non-cached Cloudfront setup in front of Elastic Beanstalk to do the HTTP to HTTPS redirect. This adds a whole new service (thus adding complexity) that isn't exactly appropriate (Cloudfront is a CDN; it's not the right tool for forcing HTTPS on inherantly dynamic content). Apache config is the normal solution to this problem and Elastic Beanstalk uses Apache, so that's the way we should go.
SSH into the server and...: This is completely antithetical to the point of Elastic Beanstalk and has so many problems. Any new instances created by autoscaling won't have the modified configuration. Any cloned environments won't have the configuration. Any number of a reasonable set of environment changes will wipe out the configuration. This is just such a bad idea.
Overwrite the Apache config with a new file: This is getting into the right realm of solution but leaves you with a maintenance nightmare if Elastic Beanstalk changes aspects of the server setup (which they very well may do). Also see the problems in the next item.
Dynamically edit the Apache config file to add a few lines: This is a decent idea. The problems with this is that it won't work if Elastic Beanstalk ever changes the name of their default Apache config file, and that this file can get overwritten when you least expect: https://forums.aws.amazon.com/thread.jspa?threadID=163369
EDIT: While I love this answer, it is now very old. AWS has come up with new services (like Certificate Manager) that make part of this answer obsolete. Additionally, using the .ebextensions folder with Apache is a cleaner way to handle this redirect as explained above.
If you are hosting your website on S3, parts of this answer may still be useful to you.
This worked for me:
Upload the certificate to AWS using the aws console command. The command structure is:
aws iam upload-server-certificate --server-certificate-name CERTIFICATE_NAME --certificate-body "file://PATH_TO_CERTIFICATE.crt" --private-key "file://YOUR_PRIVATE_KEY.pem" --certificate-chain "file://YOUR_CERTIFICATE_CHAIN.ca-bundle" --path /cloudfront/
In your Elastic Beanstalk application, go to Configuration -> Network Tier -> Load Balancing and click the gear icon.
Select Secure listener port as 443. Select Protocol as HTTPS. Select the CERTIFICATE_NAME from step 2 for SSL certificate ID. Save the configuration.
Go to your Console. Click EC2 Instances. Click Load Balancers. Click through the load balancers. Click Instances and scroll down to see the EC2 instances assigned to that load balancer. If the EC2 instance has the same name as your Application URL (or something close), take note of the DNS Name for the load balancer. It should be in the format awseb-e-...
Go back to your Console. Click CloudFront. Click Create Distribution. Select a Web distribution.
Set up the distribution. Set your Origin Domain Name to the load balancer DNS name you found in step 5. Set the Viewer Protocol Policy to Redirect HTTP to HTTPS. Set Forward Query Strings to Yes. Set Alternate Domain Names (CNAMEs) to the URL(s) you want to use for your application. Set SSL Certificate to the CERTIFICATE_NAME you uploaded in step 2. Create your distribution.
Click on your distribution name in CloudFront. Click Origins, select your origin, and click Edit. Ensure your Origin Protocol Policy is Match Viewer. Go back. Click Behaviors, select your origin, and click Edit. Change Forward Headers to Whitelist and add Host. Save.
Note: I wrote a longer guide as well.
With the new Application Load Balancers you can do this fairly trivially now...
Ensure you setup one of these at the time you setup an EB environment (still defaults to classic load balancer I believe). You could not change the type once the environment is created, so recreate it
Once this is done, go to your EC2 settings -> Load Balancers. Click on the load balancer you created for your EB environment.
You must ensure that you have setup a HTTPS listener prior to this task so make sure you listen on HTTPS 443 with an SSL cert and forward traffic to your instances with HTTP on 80.
Then add a new listener which listens on HTTP and add a default action of "Redirect to:". Make sure you set HTTPS as the protocol, 443 as the port, "Original host, path, query" as the option and finally 301 as the HTTP response code.
Once this listener is added ensure that you update your EC2 Load Balancer security group to accept both HTTPS and HTTP connections, you will see small warning sign on the listener to remind you!
Chris
The most upvoted doesn't work for me.. the <If> directive only works with Apache 2.4+, but ElasticBeanstalk has version 2.2.x.
So, following the same advice as above. Create a file called .ebextensions/https_rewrite.config with the following content
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
This seems to work for me.
On how to build this file into your WAR file, see this answer
Edit: Zags solution is more general and correct. I recommend it over mine (which is specific to a python env)
Here's a clean and quick solution that I came up with that avoids hacking wsgi.conf or using CloudFront
In your .ebextensions/some_file.config:
# Redirect HTTP to HTTPS
"/etc/httpd/conf.d/https_redirect.conf":
mode: "000644"
owner: root
group: root
content: |
<Directory /opt/python/current/app/>
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</Directory>
I feel like this is too easy, but seems to be working fine.
Also note that I am explicitly redirecting HTTP instead of "not HTTPS".
I am trying to redirect an elastic beanstalk with loadbalancer in 2018. None of the above answers works in my environment. Several issues I encoutered:
I was trying the most voted answer, but my tomcat is version 2.7. It does not support .
I was using container_commands and copy the 00_applications setting. AWS simply ignores it.
So finally I got it working by reading this:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-tomcat-proxy.html
Here is what I do:
I recreated the folder structure:
.ebextensions
- httpd
-conf.d
-ssl.conf
And then this is the content of ssl.conf
<VirtualHost *:80>
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
<Proxy *>
Order Allow,Deny
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
Hope this will help.
It's work for me with the next command:
RewriteCond %{HTTP:X-Forwarded-Port} !=443
and without the https check:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
It's look like ELB change the value of X-Forwarded-Proto to http (even on TCP protocol).
None of the above answers worked for me but some helped me to figure out the answer that worked for me
Also I found the below url which helped
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-tomcat-platform.html
I created the file structure mentioned in above url to change 2 files
httpd.conf
00_application.conf
copy the whole httpd.conf from your instance and put it in your code under .ebextention under the folder structure mentioned in the above link. Then just add below line to that file in your project
LoadModule rewrite_module modules/mod_rewrite.so
Do that same for 00_application.conf, copy it from your instance and place it in your codebase under .ebextention under httpd/conf.d/elasticbeanstalk/00_application.conf
Now edit this file and add the below between VirtualHost
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Now deploy your code
It should work.
On elastic beanstalk you can just add your on configuration so that AWS overwrite their, it will allow you to overwrite the web-server configuration and submit your own configuration.
Simply add the following file under the path: .ebextensions\httpd\conf.d
File content:
<VirtualHost *:80>
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP_USER_AGENT} !ELB-HealthChecker
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
The '.ebextensions' is the standard configuration folder in AWS and the rest just point to which file and folder you wish to overwrite.
If the file or folder doesn't exist simple create them.
I had a difficult time figuring this out so after I came up with a solution I wrote a detailed explanation of my solution to hopefully help someone else. This is specific to Tomcat 8, Apache2, and Spring Boot app. There are really useful ebextension examples in the AWS labs github.
Summary of what worked for me:
Create a file at /src/main/webapp/.ebextensions/httpd/conf.d/elasticbeanstalk.conf
Add rewrite conds/rules being careful to include "LoadModule rewrite_module modules/mod_rewrite.so"
Deploy to AWS EBS
Here is an example Spring Boot app.
I have following configurations for elastic beanstalk (64bit Amazon Linux 2016.09 v2.3.1 running Tomcat 8 Java 8).
I created a directory .ebextensions and added a .config YAML file with the rewrite conditions
Zagas solution described above (which is very complex) doesn't work for me.
Because "If" condition is unknown
Because of Apache 2.2 I don't have mod_rewrite.so included in my httpd.conf file
This solution make more sense for me, but also this doesn't work. Nothing happens, and I cannot see file "ssl_rewrite.conf" under "conf.d" directory.
Third tried solution was to add "run.config" and "ssl_rewrite.conf" files under ".ebextendsion" directory.
run_config contains
container_commands:
copy-config:
command: "cp .ebextensions/ssl_rewrite.conf /etc/httpd/conf.d"
ssl_rewrite.conf contains
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
ssl_rewrite.conf is created under "conf.d" direcotry but redirect from http to https doesn't work.
The only worked solution for me was to add the following lines in "/etc/httpd/conf.d/elasticbeanstalk/00_application.conf"
<VirtualHost *:80>
......
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
......
</VirtualHost>
but this is a temporary solution and if a machine is replaced my https redirection is gone.
Just in case anybody is still struggling:
I've struggled for some time and finally, I've found a GitHub (from AWS team) with all AWS configs and the example below works for the HTTP>HTTPS redirection for Apache 2.2. (For configs for Apache 2.4 and Nginx please see the link below).
Apache 2.2
Create a file in the root directory of your app:
YOUR_PROJECT_ROOT/.ebextensions/httpd/conf.d/elasticbeanstalk.conf
(In case of using IntelliJ / Java make sure it go added to the final .WAR artifact)
Add the following lines to enable the redirection in the virtual host:
<VirtualHost *:80>
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP_USER_AGENT} !ELB-HealthChecker
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
For more examples for Apache 2.4 and Nginx please visit this GitHub repository:
https://github.com/awsdocs/elastic-beanstalk-samples/tree/master/configuration-files/aws-provided/security-configuration/https-redirect/java-tomcat
Also, there is plenty more useful configuration and examples available.
Regards
Enabling HTTPS through an environment variable
I needed to enforce HTTPS only for our production environment, and not for the development and staging ones which are also on Elastic Beanstalk but do not use a load balancer (and therefore cannot be assigned a certificate directly).
I use an environment variable USE_HTTPS. We copy the the ssl_rewrite.conf file if and only if USE_HTTPS is set to true.
.ebextensions/files/ssl_rewrite.conf
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</If>
.ebextensions/https.config
files:
"/home/ec2-user/https_setup.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
echo "USE_HTTPS env var: ${USE_HTTPS,,}"
outfile=/etc/httpd/conf.d/ssl_rewrite.conf
if [ "${USE_HTTPS,,}" == "true" ]; then
echo "Configure SSL rewrite"
cp .ebextensions/files/ssl_rewrite.conf $outfile
chmod 644 $outfile
chown root:root $outfile
else
[ -f $outfile ] && rm $outfile
echo "Do not use SSL"
exit 0
fi
container_commands:
01_https_setup:
command: "/home/ec2-user/https_setup.sh"
Note that if you change USE_HTTPS, you need to redeploy your application for the change to take effect. You can also remove the echo commands in the https.config file if you wish.
AWS has also some documentation on this.
If you're using an application load balancer, add the file http-to-https.config to your .ebextensions folder and then add the following config (Don't forget to put in the ARN of your https certificate):
NOTE: Please be sure that you haven't yet added a listener on port 443 via the EB console. If you did so, delete the listener before adding the .config file.
Resources:
AWSEBV2LoadBalancerListener:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: '443'
Host: '#{host}'
Path: '/#{path}'
Query: '#{query}'
StatusCode: HTTP_301
LoadBalancerArn:
Ref: AWSEBV2LoadBalancer
Port: 80
Protocol: HTTP
AWSEBV2LoadBalancerListenerHTTPS:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
Certificates:
- CertificateArn: Replace with Certificate ARN
DefaultActions:
- Type: forward
TargetGroupArn:
Ref: AWSEBV2LoadBalancerTargetGroup
LoadBalancerArn:
Ref: AWSEBV2LoadBalancer
Port: 443
Protocol: HTTPS
The advantage of using your LB for this is that your config will be agnostic to the server you use like nginx, apache, etc.
I found an answer from here to be helpful.
All I did was make the health check path /index.php instead of / in the application load balancer default process.
Why don't you simply put an .htaccess file in the root folder? That way you can simply test and debug it. And if you include it in the .zip, it will automatically deployed on all instances again.
Simply use .htaccess:
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Please note that the most voted answer is a bit old now.
The answer by A Paul is actually the correct answer. The link provided in his answer is by AWS (so it is the recommended method to override your Apache configuration to make the redirection from HTTP to HTTPS when running your application on Elastic Beanstalk).
There is one very important thing to note. If you are deploying more than 1 web app, then adding the .ebextensions folder inside one of your web app is not going to work. You will notice that Non of the configurations you specified are being written or created. If you are deploying multiple Web Apps on Elastic Beanstalk environment, then you will need to read this article by AWS
Java Tomcat Deploy Multiple WAR files on Elastic Beanstalk
In general, you will need to have the following structure before you issue the eb command on it to deploy the WAR files:
MyApplication.zip
├── .ebextensions
├── foo.war
├── bar.war
└── ROOT.war
if .ebextentions folder exists inside each WAR file, then you will notice that it is completely ignored and no configuration changes will be performed.
Hope this helps someone else.
We have solved it on our backend by handling X-Forwarded-Proto properly.
This is our Grails config but it will help you with the idea:
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
grails.plugin.springsecurity.secureChannel.secureHeaderName = 'X-Forwarded-Proto'
grails.plugin.springsecurity.secureChannel.secureHeaderValue = 'http'
grails.plugin.springsecurity.secureChannel.insecureHeaderName = 'X-Forwarded-Proto'
grails.plugin.springsecurity.secureChannel.insecureHeaderValue = 'https'
grails.plugin.springsecurity.secureChannel.definition = [
[pattern: '/**', access: 'REQUIRES_SECURE_CHANNEL']
]
To extend another two answers to this question https://stackoverflow.com/a/43026082/8775205, https://stackoverflow.com/a/42035023/8775205.
For spring boot users who deploy their services on AWS with ELB, and need step by step guide, you can add an ****.conf file under src/main/webapp/.ebextensions/httpd/conf.d/ in your project.
src
--main
----java
----resources
----webapps
------.ebextensions
--------httpd
----------confd
------------****.conf
****.conf looks like the following. Noticed that I have my testing site with a single instance, so I add a condition to exclude it.
<VirtualHost *:80>
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP_USER_AGENT} !ELB-HealthChecker
RewriteCond %{HTTP_HOST} !testexample.com #excludes test site
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
After this, remember to add a "resource" under maven-war-plugin in your pom.xml in order to pick up the above configuration.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<!-- some other resource configured by yourself-->
</resource>
<resource>
<directory>src/main/webapps/.ebextensions</directory>
<targetPath>.ebextensions</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
<version>2.1.1</version>
</plugin>
Finally commit and push your code, wait AWS codebuild and codepipeline to pick up your code from your repository and deploy to beanstalk environment, or simply pack your project into a war file and upload it to your AWS beanstalk environment
AWS do not accept unserscores (_) in headders, while we can use (-), So Remove underscores from the header variables, example:- header_var_val = "some value" replace it with headervarval = "some value". It works for me.
All of the above answers are outdated in 2022, since AWS made silent changes to ElasticBeanstalk without updating the documentation properly.
However it has become very simple to do it from the AWS console when using a load balancer. You just need to disable the listener on the 80 port (http) once you created the https listener (environment -> configuration -> load balancer). And that's it.
No more problem with health checks since they are performed directly on the instance, not on the load balancer.
If you use a Load Balanced environment you can follow the instructions for Configuring HTTPS for your AWS Elastic Beanstalk Environment and at the end disable the HTTP port.
Note that currently the AWS Free Usage Tier includes the same amount of hours for an Elastic Load Balancing (ELB) as for an EC2 Micro Instance.
this is an easy solution
ssh into your EC2 instance
copy the contents of /etc/httpd/conf.d/wsgi.conf into a local file called wsgi.conf which will be placed in the base folder of your application
Edit the local version of wsgi.conf and add the following redirect rules within the < VirtualHost> < /VirtualHost> tags
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
Change the “/status” to whatever page you are using as a health check page.
Save the file
Edit your < app>.conf file inside your .ebextensions directory to add a container command to copy this version of wsgi.conf over Amazon’s version
container_commands:
01_syncdb:
command: "django-admin.py syncdb --noinput" leader_only: true
02_collectstatic:
command: "django-admin.py collectstatic --noinput"
03_wsgireplace:
command: 'cp wsgi.conf ../wsgi.conf'
...
Deploy the code.
The deployed version of wsg.conf at /etc/httd/conf.d/wsgi.conf will now include the necessary redirect rules.
It should work and the file will be properly updated for each deployment. The only thing to watch for is if Amazon changes their base wsgi.conf file contents in the future, then your copy may no longer work.
Autor rickchristianson

url rewriting on localhost

I have WAMP installed on my local machine. I have configured the apache module for rewrite_mod and trying a very basic example to redirect
RewriteEngine on
RewriteRule ^alice.html$ bob.html
As per this rule when I hit alice.html I should be viewing bob.html content. But, I think the url rewriting is not effective.
I have /test folder placed under www and alice.html and bob.html both are place inside the test folder.
Any advice to resolve this.
Thanks
This is resolved.
Did you enable the mod_rewrite module for Apache ? You need to enable this module for using rewrite directives. Don't forget to restart Apache after enabling the module.