I have a private RDS instance that I want to connect to using bastion host.
I've found a couple of tutorial on how to set it up which doesn't seem too advanced, but I struggle to understand what a bastion host actually is.
All the tutorials I've seen just creates an empty ec2 instance (bastion host) and edit the RDS security group to allow incoming traffic from it and voila, connection from local machine is working.
What I struggle to understand is that there's no configuration on the ec2 instance that enables this behaviour.
Wouldn't that mean that any server that have access to RDS could be used as a bastion host?
For example, I have an EKS cluster where I host a couple of services.
Some of these services are supposed to have access to RDS.
So in order for the services to access RDS I put RDS in the same VPC and Security Group as eks-nodegroups.
Even though the services that need access to RDS aren't publicly accessible, there are publicly accessible services that are running in the same VPC and Security Group.
Would I then be able to use one of the publicly accessible services as a bastion host in order to gain access to RDS from anywhere, thus making it public?
From Bastion - Wikipedia:
A bastion or bulwark is a structure projecting outward from the curtain wall of a fortification, most commonly angular in shape and positioned at the corners of the fort:
It 'sticks out' from the walled portion of the city and provides added security by being able to target attackers attempting to scale the wall. In a similar way, a bastion host 'sticks out' from a walled computer network, acting as a secure connection to the outside world.
When using an Amazon EC2 instance as a Bastion Host, users typically use SSH Port Forwarding. For example, if the Amazon RDS database is running on port 3306, a connection can be established to the Bastion server like this:
ssh -i key_file.pem ec2-user#BASTION-IP -L 8000:mysql–instance1.123456789012.us-east-1.rds.amazonaws.com:3306
This will 'forward' local port 8000 to the bastion, which will then forward traffic to port 3306 on the database server. Thus, you can point an SQL client to localhost:8000 and it would connect to the Amazon RDS server. All software for making this 'port forward' is part of the Linux operating system, which is why there is no configuration required.
Yes, you can use anything as a Bastion Host, as long as it has:
The ability to receive incoming connections from the Internet
The ability to (somehow) forward those requests to another server within the VPC
A Security Group that permits the inbound traffic from the Internet (or preferably just your IP address), and the target resource permits incoming traffic from this security group
Related
I'm wondering if I need port forwarding compatible Vpn given my tasks below:
Ill be connecting to aws services such as documentDB and RDS while travelling.
As a result, I plan on purchasing a dedicated IP VPN, so I can work while travelling, and add my VPN's static IP address to AWS to grant me access.
I'm working with a java spring boot backend. It connects to the documentDB and RDS and performs CRUD operations.
Does my VPN need to be port forwarding compatible?
I'm planning to purchase NordVPN with a dedicated IP, but might have to look into other VPNs port forwarding is required.
Some AWS services are VPC only, i.e. accessible only from the same VPC network. One of those services is DocumentDB, in order to connect directly from your laptop you'll have to create an ssh tunnel and port forward.
Having said that, you could have a bastion host in AWS configured with the right access, ssh (Linux) or RDP (Windows) to it and connect from that host.
The other option is https://aws.amazon.com/vpn/
If one has a publicly accessible rds database on aws, and wants to instead use a bastion ec2 instance to access and perform database functions (anyone on the internet should be able to use the app and perform database functions in accordance with the features provided by the app), how should one go about performing this shift? I have tried searching the internet but often I get loads of information with terminology that isn't entirely easy to digest. Any assistance would be greatly appreciated.
Again, I want the general public to be able to use and access the app's provided db functions, but not have them be able to access the database directly.
A typical 3-tier architecture is:
A Load Balancer across public subnets, which sends traffic to...
Multiple Amazon EC2 instances in private subnets, preferable provisioned through Amazon EC2 Auto Scaling, which can scale based on demand and can also replace failed instances, which are all talking to...
A Database in a private subnet, preferably in Multi-AZ mode, which means that a failure in the database or in an Availability Zone will not lose any data
However, your application may not require this much infrastructure. For low-usage applications, you could just use:
An Amazon EC2 instance as your application server running in a public subnet
An Amazon RDS database in a private subnet, with a security group configured to permit access from the Amazon EC2 instance
Users would connect to your application server. The application server would connect to the database. Users would have no direct access to the database.
However, YOU might require access to the database for administration and testing purposes. Since the database is in a private subnet, it is not reachable from the Internet. To provide you with access, you could launch another Amazon EC2 instance in a public subnet, with a security group configured to permit you to access the instance. This instance "sticks out" on the Internet, and is thus called a Bastion server (named after the part of a castle wall that sticks out to allow archers to fire on invaders climbing the caste wall).
You can use port forwarding to connect to the Bastion server and then through to the database. For example:
ssh -i key.pem ec2-user#BASTION-IP -L 3306:DATABASE-DNS-NAME:3306
This configures the SSH connection to forward localhost:3306 to port 3306 on the named database server. This allows your local machine to talk to the database via the Bastion server.
You will need to create private subnets for this and update DBsubnet groups accordingly with private subnets only. Moreover in DB security group add bastion and app instances security group as source for db port.
Like if you're using mysql engine, allow 3306 for target instances secuirty group id's.
I've read that the best security practice for making EC2 instances Internet-accessible is to place them in a private VPC subnet, create a Bastion host in a public VPC subnet and use a security group to only allow connections from the Bastion Host and then do key forwarding to login to private instances.
However, it seems AWS offers various configurations which seem to provide similar functionality to an actual Bastion host. For instance using a Security group on a public subnet seems pretty good, and if someone gets access to your Bastion it seems likely that they're not far away from your private keys. In any case, is there anywhere I could find more info on this topic?
It's a matter of minimizing attack surface.
With a bastion host your only exposure to the open internet (ex any load balancers) is port 22, which is backed by a relatively trustworthy piece of software.
It's also a single point of management: you define one security group that identifies IP addresses that are allowed to contact the bastion, and you create a single authorized_keys file that contains public keys of your authorized users. When a user leaves, you delete a line from each.
By comparison, if you rely solely on security groups to protect publicly-accessible hosts, you need to replicate the same settings on every group (and remove/update them as needed). And if you allow SSH access to those hosts, you have to distribute the authorized_keys file after every change.
Although I can't recommend doing this, it's at least rational to open port 22 on the bastion host for world access. If you have a lot of users, or those users connect via tethered cellphones, it may even be reasonable. That's something that you'd never, ever want to do with arbitrary services.
You can find best practices of using Bastion Host here: https://docs.aws.amazon.com/quickstart/latest/linux-bastion/architecture.html
Access to the bastion hosts are locked down to known CIDR scopes for
ingress. This is achieved by associating the bastion instances with a
security group. The Quick Start creates a BastionSecurityGroup
resource for this purpose.
Ports are limited to allow only the necessary access to the bastion
hosts. For Linux bastion hosts, TCP port 22 for SSH connections is
typically the only port allowed.
Note that it is pretty common to create an SSH tunnel to connect to a given resource through your Bastion Host: https://myopswork.com/transparent-ssh-tunnel-through-a-bastion-host-d1d864ddb9ae
Hope it helps!
Let me answer this question in a more simple way.
First one needs to understand the bastion host (some people call it a jump box).
The trick is that only one server, the bastion host, can be accessed via SSH from THE INTERNET (it should be restricted to a specific source IP address). All other servers can only be reached via SSH from the bastion host.
This approach has three security advantages:
You have only one entry point into your system, and that entry point does nothing but SSH. The chances of this box being hacked are small.
If one of your web servers, mail servers, FTP servers, and so on, is hacked, the attacker can’t jump from that server to all the other servers.
It’s important that the bastion host does nothing but SSH, to reduce the chance of it becoming a security risk
Hope this help to understand others!
I'm trying to create a realistic network setup for a multi-tiered web application. I've created a new VPC within AWS with 1 x public subnet & 2 x private subnet. I then created a Postgres instance within the private subnet and set it to not publicly accessible. This adds an extra layer of security around the database, but how do I then access the database from my local IP?
I created a security group & assigned my IP to the inbound rules & assigned that to the DB instance during creation:
But I still have no way of connecting to it? Do I need to create a VPN and connect to my VPC via the VPN and then connect to the DB instance? Within the proposed architecture, how do you connect to the DB?
What I'm trying to achieve is an architecture which will allow me to create Lambda functions which communicate with the DB via the API Gateway and serve data to a web frontend. So I want the DB protected via the private subnet. But I also want to be able to connect directly to the DB from my local laptop.
At the moment - the RDS instance is running in the VPC, but I don't know how to connect to it. DoI need to set up an Internet Gateway / VPN / EC2 instance and jump to the DB?
You have implemented excellent security by placing the Amazon RDS database into a private subnet. This means it is not accessible from the Internet, which blocks off the majority of potential security threats.
However, it also means that you cannot connect to it from the Internet.
The most common method to achieve your goals is to launch an Amazon EC2 instance in the public subnet and use it as a Bastion or Jump Box:
You SSH into the Bastion
The Bastion can then connect you to other resources within the VPC
Since you merely wish to connect to a database (as opposed to logging into another server), the best method is to use SSH with port forwarding.
In Windows, this can be done using your SSH client -- for example, if you are using PuTTY, you can configure Tunnelling. See: How to Configure an SSH Tunnel on PuTTY
For Mac/Linux, use this command:
ssh -i YOUR-KEYPAIR.pem -L 5555:RDS-ENDPOINT:5432 ec2-user#YOUR-BASTION-SERVER
You then point the SQL client on your laptop to: localhost:5555
The 5555 can be any number you wish. It is merely the "local port" on your own computer that will be used to forward traffic to the remote computer.
The RDS-ENDPOINT is the Endpoint of your RDS database as supplied in the RDS console. It will be similar to: db.cnrffgvaxtw8.us-west-2.rds.amazonaws.com
BASTION-SERVER is the IP address or DNS name of the Jump Box you will use to connect
Then, any traffic sent to localhost:5555 from your SQL client will be automatically sent over the SSH connection to the Bastion/Jump Box, which will then forward it to port 5432 on the RDS database. The traffic will be encrypted across the SSH connection, and establishment of the connection requires an SSH keypair.
I referred a lot of articles and videos to find this answer.
yes, you can connect to rds instances in private subnets
we have two ways to connect
With server: By using ec2 in the public subnet and using it as a bastion host. we can connect to pg admin by ssh tunneling
Serverless: By using client VPN endpoint. create a client VPN endpoint and associate the subnets and allow the internet to the private subnets. and then download the configuration file and install open VPN GUI and import the configuration file and add the keys and then connect the open VPN. Now try to connect to pgadmin, it will connect.
for steps: https://docs.google.com/document/d/1rSpA_kCGtwXOTIP2wwHSELf7j9KbXyQ3pVFveNBihv4/edit )
My security group inbound rules are as follows:
WebAccess
HTTP TCP 80 0.0.0.0/0
SSH TCP 22 0.0.0.0/0
and
DB
MYSQL/Aurora TCP 3306 sg-0252186b (WebAccess)
My instances are setup like this:
Instance 1, web server - security group WebAccess
Instance 2, web server - security group WebAccess
Instance 3, DB server - security
group DB
If my understanding is correct, anyone should be able to access HTTP and SSH on my web servers, and only a member instance of WebAccess group should be able to access the DB server. However, the DB server is not accessible from the web servers.
When I change the 3306 rule to be open to allow inbound from anyone, I can access it fine (also from my local computer, as expected).
Please could somebody help me understand where I'm going wrong?
Thanks,
Chris
When you change the security-group to 0.0.0.0/0 and you are able to access the DB later on from your desktop that means your instance has been enabled for public access (i.e. having a public IP). When you connect to such a instance traffic leaves the subnet to the internet and comes back in. Because of that, the traffic no longer originates on your web instance but from the internet. You would need to use the web instances public IPs in that case.
Also please note, the way you have worded your question/comments, suggest you use the IP of the RDS instead of the hostname. This works if you use a single AZ RDS deployment. It won't work if you use multi-AZ or convert this RDS instance to multi-AZ (HA setup). The reason is, that during a failover AWS updates the DNS name to point to the new master. If your application is using an IP no fail over will occur.
Even worse: if you use an IP and single-AZ now but later decide to upgrade to a multi-AZ your application will continue to work until the first failover (most likely due to maintenance)