what tools should I use on AWS to map a port - amazon-web-services

I have a jfrog factory(port 8081) and jfrog docker( port 8082) running on an EC2 instance
with route53 I defined the url of the domain xxx.io and also two subdomains jrog.xxx.io and docker.xxx.io
with certificate manager I applied for a SSL certificate for the domain xxx.io who normaly is available as well for the subdomain if i dont make any mistakes .
What tools do I need to set up so that when a user enters the url jfrog.xxx.io it is redirected to the jfrog instance (port 8081) but the port of this instance must be mapped to 443 ?

You can use an application load balancer to achieve it.
The load balancer works with target groups and you will need 2 target groups for your load balancer. First target group will map the https (443) to your jfrog docker and the second target group will map https (443) to your jfrog factory.
The target group for jfrog factory will look like:
The target group for jfrog docker will look like below.
P.S: My instance is unhealthy because it has nothing in it, just a dummy instance.
Important things in the target group is the port mapping of your application and the target type. Then register your EC2 instance with the target groups.
Now in your load balancer, choose the tab Listeners and View/Edit rules for the listener of type HTTPS (443).
Then add new rules using a condition host header which will then redirect traffic to your target groups based on your subdomains (host header), it should look something like below. P.S I do not have SSL certificates, so I have used http itself, https should not be any different.
The finally you must make a DNS entry of type CNAME to map your domain (xxx.io) to the load balancer's DNS name.
This is where you will get the load balancer's DNS name:

Related

How to Map Sub Domains created in Route 53 to application running in EC2 instance with different port

I have springboot application with different ports hosted in ec2 instance
Domain in Route 53
Domain Name : mydomain.com
App A - 8081,
App B - 8085,
App c - 8088
Instance IP : 10.xx.xx.xx
domain :
test1.mydomain.com point to 10.xx.xx.xx:8081/landingpage &
test2.mydomain.com point to 10.xx.xx.xx:8085/landingpage &
test3.mydomain.com point to 10.xx.xx.xx:8088/landingpage
I have some idea in creating Load Balancer and Target Groups in beginner level.
Your views are always welcome.
As stated by Marcin, Route53 can't resolve port, this is a workaround. Assuming you already open two ports on your EC2 instance:
Create 2 target groups. One to port 8085, one to port 8088. Register your instance to those 2 target groups
Create application load balancer (ALB). Create 2 CNAME record with subdomain as your need, route both to your ALB DNS
Optional: Create a certificate for your domain (ACM), it should able SSL on *.example.com, register the certificate to your HTTPS load balancer.
Create listening rule on port 443 of your ALB (80 if you don't use SSL), route depending on your host name, each host name will route to one target group.
Route53 is DNS web service. It only resolves names to IP addresses, not ports nor URL paths. For that you need to either setup a load balancer for your instance, or using nginx on the instance to manage ports and url path redirections.
You can't do what you want in DNS using Route 53. See Can DNS point to specific port? - Webmasters Stack Exchange There are several ways to implement what you want:
Virtual hosts and reverse proxy
It is very common to run Apache on Nginx on your server on ports 80/443 for HTTP/HTTPS respectively. Both support virtual hosts where you point multiple domain names to the same server and the forward the requests to other ports. See What is a "reverse proxy" in webmastering?
Multiple load balancers
You could create multiple Amazon ELBs that forward requests to different ports. Then Route 53 could point each domain to its own load balancer.
Content delivery network (CDN)
Amazon's CDN is called Cloudfront. It has sit between your site and your visitors and do the mapping that you want.

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
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:
a domain hosted in Route 53 (I have one for my frontend UI)
SSL certificated got from aws Certificate Manager
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
name: api.helloworld.com
type: A
Routing: Simple
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 ---------------------------
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

Setup a single AWS load balancer for multiple .net core applications hosted as websites on a single EC2 instance

Framework: .Net core 2.0
Hi everyone,
I have deployed let's say 3 applications on the same EC2 instance which are websites (front end angular js and 2 web apis for authentication and communication). How do I setup a single load balancer for catering requests for all of the 3 websites using HTTPS?
These websites communicate among each other for authentication and providing the required data between them.
The websites are deployed on the EC2 using hostnames on the IIS and they are accessible directly through the hostnames. Is there another/better way to deploy them instead of hostnames only?
When setting up a load balancer, you would have to configure listeners for it, wherein you mention the ports through which you would want to access your application. And in the listeners you would have to mention target groups to which you would route traffic, based on hostnames / host headers.
So, here are the steps to follow.
Since all your traffic has to anyway go to the same instance, you would have to create one target group and register the instance that you have already created with traffic routed through the 80 port.
Now, coming back to the ELB configuration, you would need to create a HTTP listener (port 80) that would have a default rule to redirect all traffic to HTTPS (port 443).
In the same ELB, create a HTTPS:443 listener, where (usually) you would have different listener rules depending on what are the hostnames of your sites in IIS. But just for simplicity, configure the default rule to route all traffic to the target group created in the step above (once we check if traffic is flowing right, we can change the configuration to improve security).
That's all!
With the right security group whitelisting, your traffic should flow into your instance through the ELB.
Congratulations! That should be enough...
... unless you want to make sure that ONLY the requests related to those sites flow into your instance, then, once you are sure that the traffic flow is right, you can create another listener rule in your ELB's HTTPS:443 listener, wherein you can configure the following setting:
IF Host Header is frontend.website.com OR webapi1.website.com OR webapi2.website.com THEN Forward to (target group created in Step 1)

Route different ports of same host to different instances

I have a registered domain, let's say example.com, and 3 different services running at AWS:
Static web application, currently hosted at Amazon S3; port 80
TCP service, hosted in an EC2 instance; port 3333
TCP service, hosted in another EC2 instance; port 4444
All 3 services should be accessible - if possible - from the Internet by using the same hostname but different ports, i.e.
www.example.com:80 --> S3 web app
www.example.com:3333 ---> EC2 instance 1
www.example.com:4444 ---> EC2 instance 2
First question is: Is this possible at all? Or should I rather use different host names like www.example.com, service1.example.com...?
If it is possible, how would it be set up and which AWS services can I use? I am still pretty new to AWS and read about (Elastic) Load Balancer, CloudFront, Route 53 but I still don't get how I could achieve my goal.
Without any further AWS service it seems to be impossible to configure a DNS entry to point to the S3 bucket, as this doesn't have a static IP address.
Any hints for a quick solution would be appreciated, as this setup is for a demo only. There won't be many users accessing the services, so from this perspective, a load balancer is not necessary and it's also not necessary for the setup to scale up at the moment.
Is this possible at all?
Answer is Yes.
You could have a proxy server setup to proxy the traffic according to your needs:
Setup a DNS record for www.example.com which resolves to your proxy
IP (Could be one of those instances you already have).
Configure your proxy (multiple choices nginx, squid etc) to
listen on www.example.com and the given ports and forward the traffic
accordingly to the EC2 server IPs and the S3 website CNAME.
Is it worth it for your use case? No Unless you want to try it as an exercise.
Should I rather use different host names ...? Yes
Just create a hosted zone in Route53 for your domain, and create subdomains for the different services www.example.com, service1.example.com.
First question is: Is this possible at all?
Without super-complex setups, it is only possible for your TCP apps with a type of load balancers called Application Load Balancer. http://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html
With ALB you can create different target groups each of your TCP apps (EC2 instance 1 port 3333 and EC2 instance 2 port 4444), then define custom listeners on the load balancer to route port 3333 to the first target group and port 4444 to the second target group.
But ALB is unable to route to S3 or CloudFront distribution.

AWS SSL certificate with Elastic Beanstalk: HTTPS site not reachable

When I associate an AWS certificate with my Elastic Beanstalk app and visit the domain using https, I get 'This site can’t be reached, mydomain.com refused to connect.' I can visit the site using http.
I created a security certificate with AWS's ACM. I added my domain name, example.com, along with additional names that were sub domains to the certificate. In my app's environment 'Loading balancing' section I set this up:
I setup the SecurityGroup named awseb-e-abc123-stack-* for my environment as follows:
There is another security group named awseb-e-abc123-stack-AWSEBLoadBalancerSecurityGroup-*, which is as follows. It has the same name tag as the above group, which is the same as my environment name:
It seems, though, that the entries of the "AWSEBLoadBalancerSecurityGroup" security group does nothing, as removing all the entries still allows HTTP traffic to work.
In .elasticbeanstalk\securelistener.config, I have the following
option_settings:
aws:elb:listener:443:
SSLCertificateId: <my certificate's ARN>
ListenerProtocol: HTTPS
InstancePort: 80
It seems, though, if I add a syntax error in this file, the deployment still succeeds.
Here is the output of curl -vL https://<my domain>:
* Rebuilt URL to: https://<my domain>/
* Trying <my elastic IP>...
* connect to <my elastic IP> port 443 failed: Connection refused
* Failed to connect to <my domain> port 443: Connection refused
* Closing connection 0
curl: (7) Failed to connect to <my domain> port 443: Connection refused
I used a separate domain name register to setup my domain name, and set up my domain's DNS A records IP address equal to my Elastic IP.
[edit]
I had mentioned above that changing the rules of the load balancer security group does nothing. This was because my EC2 instances's security group was pointing to the instance's security group, not the security group of the load balancer. When I pointed the EC2's security group to the load balancer's security group, the security group's rules are execercized. I verified this by removing all the rules from the load balancer security group, and seeing that no requests are accepted. However, if I add back the HTTP and HTTPS rules to the load balancer security group but remove all the rules from the instance security group, all HTTP requests are going through. This is NOT expected behavior because the load balancer is supposed to forward traffic to the instance. What seems to be happening is (1) the instance and load balancer security groups are not at all related to the instance and load balancer and (2) no traffic is going to the load balancer.
Is there anything else I'm missing?
[edit 2]
I misread gkrizek's comment. If I use the public DNS of the load balancer, I am able connect using either HTTP or HTTPS. I am able to connect to both versions using telnet. So instead of creating an A record that set testdomain.com to my Elastic IP, I created a sub.testdomain.com CNAME record set to the load balancer. Now I am able to browse to both http://sub.testdomain.com and https://sub.testdoamin.com. Two questions:
Is it OK to use the load balancer's public DNS in the CNAME record? I can't use the *.elasticbeanstalk.com URL because it could change, so I'm wondering if the same situation applies here
How can I secure https://testdomain.com (no sub domain). It seems like with this method, it is impossible to have https://testdomain.com since I cannot create an A record with an domain name.
The issue is that you have to create a CNAME record with your domain and use the load balancer DNS name as the address. If you use the Elastic IP, the requests will not go to the load balancer.
To answer my last questions:
AWS says this is OK
You cannot directly do this because AWS does not allow you to assign an Elastic IP to a load balancer. What you can do is have a URL record that redirects testdomain.com to https://www.testdomain.com