
Case 1 : application is powered by Elastic Beanstalk with Tomcat
Solution :
edit /etc/httpd/conf.d/elasticbeanstalk.conf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- /etc/httpd/conf.d/elasticbeanstalk.conf --> | |
<virtualhost> | |
... | |
RewriteEngine On | |
RewriteCond %{HTTP:X-Forwarded-Proto} !https | |
RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R] | |
</virtualhost> |
Case 2 : application is running in tomcat with or without apache httpd service on EC2 only
Solution:
edit server.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<connector enablelookups="false" port="8080" redirectport="443"> | |
</connector> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<security-constraint> | |
<web-resource-collection> | |
<web-resource-name>Protected Context</web-resource-name> | |
<url-pattern>/*</url-pattern> | |
</web-resource-collection> | |
<user-data-constraint> | |
<transport-guarantee>CONFIDENTIAL</transport-guarantee> | |
</user-data-constraint> | |
</security-constraint> |
Both above 2 solutions won't work , because SSL is configured at load balancer layer not application container level with aws.
You would end up infinite loop as request coming on unsecured channel (80 or 8080) is redirected to load balancer on 443 ,and load balancer would send request to unsecured port (80 or 8080), then this unsecured port would be redirected to load balancer 443 again , the loop never ends.
A working solution would be there are 2 containers (tomcat) listening on different unsecured ports , one (8089) is purely for redirect to secured channel another (8080) is where actual application is deployed.
I use spring boot for purpose of redirecting (from 8089 to 443) which you can download the source from there : https://github.com/junjun-dachi/spring-util/tree/master/spring-boot-enforce-https and a sample code below:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.junjun.spring.util; | |
import org.apache.catalina.Context; | |
import org.apache.catalina.connector.Connector; | |
import org.apache.tomcat.util.descriptor.web.SecurityCollection; | |
import org.apache.tomcat.util.descriptor.web.SecurityConstraint; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; | |
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; | |
import org.springframework.context.annotation.Bean; | |
@SpringBootApplication | |
public class Application { | |
public static void main(String[] args) { | |
SpringApplication.run(Application.class, args); | |
} | |
@Bean | |
public EmbeddedServletContainerFactory servletContainer() { | |
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() { | |
@Override | |
protected void postProcessContext(Context context) { | |
SecurityConstraint securityConstraint = new SecurityConstraint(); | |
securityConstraint.setUserConstraint("CONFIDENTIAL"); | |
SecurityCollection collection = new SecurityCollection(); | |
collection.addPattern("/*"); | |
securityConstraint.addCollection(collection); | |
context.addConstraint(securityConstraint); | |
} | |
}; | |
tomcat.addAdditionalTomcatConnectors(createHttpConnector()); | |
return tomcat; | |
} | |
private Connector createHttpConnector() { | |
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); | |
connector.setScheme("http"); | |
connector.setSecure(false); | |
connector.setPort(8089); | |
connector.setRedirectPort(443); | |
return connector; | |
} | |
} |
Type below on the command line to run the application :
nohup $JAVA_HOME/bin/java -jar spring-enforce-https.jar > /dev/null 2>&1 & echo $! > run.pid
Reference :
1 : http://msnider.github.io/blog/2013/12/06/force-https-slash-ssl-on-amazon-elastic-beanstalk/
2 : http://www.emind.co/how-to/how-to-force-https-behind-aws-elb
3 : https://edwardsamuel.wordpress.com/2015/07/17/enable-https-and-http-redirect-on-aws-elastic-beanstalk/
4 : http://tkurek.blogspot.sg/2013/07/tomcat-7-http-to-https-redirect.html
Nice article, users are attracted when they see your post thanks for posting keep updating AWS Online Training Hyderabad
ReplyDelete