As we know ssl provides the extra layer of security. Every packet transferred between client and server is encrypted using public or private key cryptography. Now a days everyone ensuring to protect their web application through ssl certificate. If you have developed your web application by using Spring then you are at right place. Here you will learn how to install ssl certificate without paying anything.
There are multiple ways to generate ssl certificates. Even Java also has provided a tool(keytool). If you will use keytool then you can enable https but still you will see Not Secure in the browser URL like this.
Hence we are here to make this as secure with green color https URL. To make this green https, we will use Let's Encrypt. Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for Transport Layer Security encryption at no charge. So Let's follow the steps.
Step 1:
Stop the application or server running on the port 80 or 443. You can check whether any application or server running or not on a particular port by using lsof command.
lsof -i :8080
To stop the application or server, you can use kill command.
kill -9 pid
Step 2:
You need to install the certbot on your server. You can open the server terminal by using ssh command.
ssh alt@xxx.xxx.xxx.xxxwhere xxx is your server ip address. Now use this command to install certbot if you have Ubuntu operating system.
sudo apt-get update -y && sudo apt-get upgrade -y sudo apt-get install software-properties-common sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-apache
Step 3:
Now generate the ssl certificate by using the following command.
certbot certonly -a standalone -d api.example.comwhere api.example.com is your domain name. This will generate the 4 .pem files inside etc/letsencrypt/live/api.example.com-0001/.
To goto this directory, use this command.
cd / cd etc/letsencrypt/live/api.example.com-0001/To see the files in the current directory use the ls command.
lsThis will show the following files list.
cert.pem chain.pem fullchain.pem privkey.pem README
Step 4:
As we know Spring supports .p12 file for ssl certification. Hence we need to convert the .pem files into .p12 file. To generate PKCS12 file from PEM files we shall have to use openssl command.
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out api_example_com.p12 -name myalias -CAfile chain.pem -caname rootHint:
-out will the converted file name
-name will be your alias name
This will ask to enter password. After entering the password, again it will ask the password. You will have to enter the password 2 times.
Step 5:
Finally, it will generate the api_example_com.p12 file in the current directory. Now you need to copy this file in Spring Boot Maven project resource directory(src/main/resources/). To copy the file from server location to local machine, you can scp command but I will recommend to first copy the file to your ubuntu home location because there may be a lot of users present that OS.
cp api_example_com.p12 /home/myusername/ exit exitNow you are in local machine terminal. From here you need to copy the file from server machine home location to your local machine.
scp alt@xxx.xxx.xxx.xxx:api_example_com.p12 .Hint: Here . means current directory. You can change it your appropriate directory. This will be downloaded into your home directory.
Step 6:
Now copy this(api_example_com.p12) file and paste in src/main/resources of your Spring Boot project. Now do some changes in your application.properties file
server.ssl.enabled=true server.ssl.key-store=classpath:api_example_com.p12 server.ssl.key-store-password=mypassword server.ssl.keyStoreType=PKCS12 server.ssl.keyAlias=myalias http.port=80 server.port=443
Step 7:
Here you need to take special care. After saving this configuration in your application.properties file, if you start the server locally, it will fail to start. Because the .p12 has mapped to your ip xxx.xxx.xxx.xxx and your current ip is 127.0.0.1 that is localhost. Hence only this will start on your server. To avoid this happening, you can use profile concept of Spring. Hence you need to create another property file ie application-prod.properties then cut and paste those ssl configuration in application-prod.properties file and remove from application.properties file.
You need to write one more line in application.properties file
spring.profiles.active=prodNow if you want to start the server locally then comment this and start.
#spring.profiles.active=prodIt will start locally without ssl but when you want to start the server on server machine then you need to uncomment this config.
Step 8:
This is an optional step but I will recommend to do. In this step you need to write a config class
that will redirect every request that is coming via http to https.
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.beans.factory.annotation.Value; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Profile("prod") @Configuration public class TomcatConfig { @Value("${http.port}") private int httpPort; @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(initiateHttpConnector()); return tomcat; } private Connector initiateHttpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(httpPort); connector.setSecure(false); connector.setRedirectPort(8443); return connector; } }
Congrats! You are done. Feel free to comment, if you have any doubt.
Great ๐
ReplyDeleteGreat
ReplyDeleteเคเคเคฌ เคญाเค
ReplyDelete๐ค
ReplyDeleteIf it were necessary to enable http 2, how would I do it?
ReplyDeleteCan you elaborate your question pls?
DeleteBy the way if you are asking to make all the request mandatory to be https then step8 will work.
Good article on SSL configuration in spring boot.
ReplyDeleteAwsm work good work....on SSL configuration....๐๐ป๐๐ป๐๐ป๐๐ป
ReplyDelete