Ao Jiao
Ao Jiao

Reputation: 51

Amazon EC2 - Listen for HTTPS request and Redirect to SpringBoot

I have a frontend React application hosted on Amazon Amplify and a backend SpringBoot application hosted on Amazon EC2.

My domain can only send https request but SpringBoot by default is http. My question is how can my EC2 instance listen to HTTPS request and then redirect to http port in SpringBoot.

I checked other posts and seems like you should not add SSL to your SpringBoot application, but rather to the Load Balancer in front of it. At the end of the today, this is what I want:

POST https: xxx.xxx.xxxx:443/user/signin
---> http: xxx.xxx.xxxx:8080/user/signin

---------------------------------------- update ----------------------------------------

Marcin has provided a top level idea on how to solve this, thank you!

I also attached the step-by-step solution for people like me, please see answers below

Upvotes: 4

Views: 2854

Answers (2)

Ao Jiao
Ao Jiao

Reputation: 51

Below is the complete steps to take to convert your http api to https using aws ec2

disclaimer: I only researched for couple hours, some concept might be inaccurate or wrong, but following this guide does gets the job done, correct me for misleading information


(1) springboot:

keep your server port on 8080 and don't change it to https (443)


(2) make sure your EC2 instance has the correct *VPC* and *IPv4 CIDR* set up

go to Instances -> Description -> VPC ID and then click on it

you should now see the list of VPCs, find the one that associated with your instance

In detail -> IPv4 CIDR -> check if it has two or more values in below format:

xxx.xx.0.0/16

xxx.xx.0.0/16


(3) skip this step if you have two IPv4 CIDR set up

select your VPC instance -> click Actions -> EDIT CIDRS -> Add new IPv4 CIDR

make sure two IPv4 CIDR are in different zone

more information on IPv4 CIDR:

https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html


(4) now we want to create an application load balancer that listens to https:443 request

select HTTP HTTPS Application Balancer and for each step (as shown in aws)

step 1. Load Balancer Protocol and Port: https: 443

step 1. Availability Zones: now is the time to select your VPC and two zones

step 2. Security Setting choose a certificate from ACM (assume you have one on Route 53)

step 3. Security Group: make sure to select the same group as your EC2 instance

step 4. Routing http: 8080, target type: instance

step 5. Register Targets select your EC2 instance, on port 80, please don't forget!


(5) now load balancer set up, double check security group of your EC2 instance

go to instances -> Description -> Security Group and click on it

for inbound rule, keep port 443, 22, 80, 8080 don't remove 8080

443 is for https, 22 for ssh client, 80 for tomcat


(6) now find the ips to use for the https request

this is not the public ip address of your EC2 instance

your application is behind a load balancer, the ip address should be the network interface IP. each network interface IP associates with a subnet ID that your VPC uses.

so go to Network Interfaces in your EC2 console. select any of your network interface IDs with a subnetId under your EC2's VPC.

click Details -> and scroll down to find the public IP you need


(7) before start next step, make sure you have the following:
  1. a domain hosted in Route 53 (I have one for my frontend UI)
  2. SSL certificated got from aws Certificate Manager
  3. you should have put this SSL to your load balancer in step 3

if don't know what to do, check this stackOverFlow post for answers:

Adding SSL to domain hosted on route 53 AWS


(8) before next step, make sure you understand the following:

If you directly test your https request in postman, you will likely succeed.

However you will fail if using in production, like this:

axios.get("https:xxx.xxx.xxx:443/user/signin");

(failed)net:ERR_CERT_COMMON_NAME_INVALID

This is because whatever static IP you are using, does not match the AName for your SSL certificate. For example, if your domain name is helloworld.com, your backend API request should be https://helloworld.com/user/signin


(9) create a subdomain and config it in Route 53

I'm getting lazy, please see the link below:

https://aws.amazon.com/premiumsupport/knowledge-center/create-subdomain-route-53/


(10) final step!!!!!!

Now you have a working subdomain, let's use it for your network interface IP

For test, you can pick any IP from the list of network interface IPs. Go to Route 53 -> Hosted Zones -> select your subdomain, example: api.helloworld.com -> create record

Record Format

  1. name: api.helloworld.com
  2. type: A
  3. Routing: Simple
  4. Value: <your_network_interface_ip_address_multiple>

(11) sorry not yet ready

please wait for couple of days for DNS record to be updated, if DNS can interpret your subdomain, let's say api.helloworld.com into your network interface IP and since you can already test the correctness of your IP in postman, you should be ready to go!

--------------------------- end of useful information ---------------------------

Upvotes: 1

Marcin
Marcin

Reputation: 238957

If you want to keep using only the instance (no load balancer or cloudfront), then you need to get your own domain for it. Then you have to register a valid, public SSL certificate for that using, e.g. letsencyrpt. Once you have that, you can setup nginx on the instance to accept the https connections, and forward to your spring boot as http.

The easier route is to use application load balancer. You still need your own domain, but once you have it, you can easly get free SSL cert from AWS ACM and then deploy it on the balancer. No need to change your instance. So it would be:

Client ---(HTTPS)---> ALB ---(HTTP)---> EC2

Upvotes: 0

Related Questions