Mastering Connectivity: CG-NAT Solutions with Tailscale
Ayaan Bordoloi
Posted on January 29, 2024
Recently, the CEO of Supabase tweeted about the importance of transitioning from IPv4
to IPv6
. This is due to the shortage of IPv4
addresses, and major cloud providers like AWS are set to start charging for IPv4
addresses starting from February 1, 2024.
Not everyone is fully ready to adopt IPv6
because of its complexities. To lawfully and technically circumvent these issues, I will demonstrate two methods in two clouds which I learned in The Cloud Seminar recently. These solutions don't always work, but in most cases, one can definitely bypass the restrictions.
First, I will discuss what tailscale is and how we can use tailscale to translate a private IPv4
address to public IPv4
address using CGNAT CIDR.
Tailscale
Tailscale is a VPN service that enables encrypted point-to-point connections using the open source WireGuard protocol, making devices and applications accessible anywhere in the world, securely and effortlessly. It offers speed, stability, and simplicity over traditional VPNs.
We will use tailsacle to convert our private IPV4
address to public IPV4
address using CGNAT CIDR. So, what CGNAT does is it involves the translation of private IP addresses used within a local network into a smaller set of public IP addresses when the traffic passes through the ISP's network.
Cloud Machine Access via Console Connect
Now, I will be working in the Hetzner cloud to demonstrate how we can SSH into our cloud machine without a public IP using tailscale.
Steps:
- Login to the console and create a project in the cloud.
- Start creating your server by adding the required machine details. ( I picked an ubuntu machine)
While creating the server in my Hetzner Cloud console, I unchecked the Public IPv4
option and only checked the public IPv6
option because it was charging me a certain amount of money to enable it.
- Finally, create the server after filling in all the required details for the machine you need.
- After creating your server, your server dashboard will be visible. (I named my server tailscale-connect)
- At the top of your server dashboard you will see a console connect option, click on that.
- The instance connection will open and you will see the following screen:
Now, to log in to the server, it asks for a login username and login password, which we don't know. We will reset the login username and password to connect to the server.
- Navigate to the rescue screen on your server dashboard and click
"Reset Root Password."
(After clicking, you will receive a new root password. Save it somewhere.)
Now, refresh the page and open the console connect terminal again to login with the new root password. (Type your new root password which you generated in the previous step.)
You will see the following screen after successfully logging into your server-
- The top arrow indicates the private
IPv4
address, and the arrow below indicates theIPv6
address that the cloud provided us.- Since, we didn't enable the public
IPv4
address(because of extra cost) we didn't get one.
Even though we connected to the instance through the console, we still haven't connected it through our machine, and it is not possible to do so without a public IPv4
address. To circumvent this issue, we will use tailscale.
Tailscale installation
Head to the terminal and install tailscale on your linux machine with the following command:
curl -fsSL https://tailscale.com/install.sh | sh
- Once your installation is complete, type
tailscale up
and go to the link that tailscale provided in the terminal. - You will see the following screen:
- Sign in to tailscale using any of the provided methods.
- You will see the following screen after singing up-
- The tailscale dashboard displays all the devices connected to your network.(Currently it's only your local machine)
- Now, we will connect the cloud machine to the same network and then access it through our local machine without a public
IPv4
address.
Let's see how to do that in the next steps.
Tailscale: SSH connect without Public IP
- Head to the cloud machine terminal that we logged into earlier.
- We will install tailscale on this machine and connect it to the network that we created previously.
- Type the following command to install tailscale on your cloud machine
curl -fsSL https://tailscale.com/install.sh | sh
- Once your installation is complete, type
tailscale up
and go to the link that tailscale provided in the terminal. - On the sign-up page, sign in with the same account that you used to sign up on your local machine.( In my case, I used my github account.)
- Once you have signed in, you will now see two machines on the dashboard: one being your local machine and the other being your cloud machine.
Now that we have connected the two machines on the same network, we can access the cloud machine through our local machine without requiring a public
IPv4
address.Copy the CGNAT IP of your cloud machine provided by Tailscale from your dashboard.
Open your terminal and type the following to connect to your cloud machine
ssh root@[CGNAT-IP]
- Now, you have successfully connected to your cloud machine through your local machine without requiring a public
IPv4
address. How cool is that?!!
We don't need the console login terminal anymore, so we can close it and directly access the machine via our machine terminal.
EC2: SSH connect without public IPv4
Now, to implement the above method, we need to log in to the server using the cloud provider's console connect. Unfortunately, AWS console connect doesn't support public IPv6
addresses, only IPv4
. AWS will charge $0.005 per IP per hour for public IPv4
, leading to high costs. To address this, create a Jump box (Bastion Host) in the public subnet using a public IPv4
address and connect other machines through it using private IPs. This reduces costs, as only one machine is billed for the public IPv4
address, with others connected via private IPs.
Steps:
- Log into your AWS console.
- Head over to the VPC section and create a VPC for your instances.
- In the VPC section, create two subnets (Public & Private) allowing
IPv4
CIDR blocks for both and aIPv6
CIDR block for private only. - Create an Internet gateway (IGW) and attach it to your VPC.
- Create a route table and associate it with the public subnet. Edit the route and add a destination of
0.0.0.0
, choosing the destination as the IGW you created in the previous step. - Similarly, create a Route table and associate it with the private subnet. No need to edit route here.
- Head over to EC2 instances and create a key pair first.
- Create an EC2 instance (JUMPBOX) in the public subnet of your VPC, allowing the option for auto-assigning a
public IPv4
. In the security group, allow SSH from my IP. - Try to SSH into it from your terminal and see if it's working.
- Next, create one or two instances (test instances) in the private subnet of your VPC. Disable the auto-assign public
IPv4
address and enable the auto-assignIPv6
address.
- We cannot SSH into the Test instances because we have disabled the public
IPv4
option. We only have a privateIPv4
address and anIPv6
address. To SSH into the test instances, we will use the JUMPBOX, which has anIPv4
address assigned to it. - Head over to config file in the .ssh folder.
cd .ssh
code .
- Paste the following in the config file
Host JUMPBOX
HostName [Public IP of JUMPBOX]
ForwardAgent yes
StrictHostKeyChecking ask
IdentityFile ~/.ssh/[private-key]
User ubuntu
Host [Private IP of test instance]
ProxyCommand ssh -q -W %h:%p JUMPBOX
ForwardAgent yes
IdentityFile ~/.ssh/[private-key]
User ubuntu
Host [Private IP of 2nd test instance]
ProxyCommand ssh -q -W %h:%p JUMPBOX
ForwardAgent yes
IdentityFile ~/.ssh/[private-key]
User ubuntu
- Please update the above file with the details of your own machine and then save and exit.
- Add the following rule in the security group of your test instances and then save it.(Custom IP is the CIDR of your VPC)
- Now, head over to the terminal and ssh into your test instances through your private IP.
- This is how we can SSH into our instances without a public
IPv4
address. This method can reduce the cost to a great extent. You can also install a NAT gateway in your public subnet to access the internet on these machines.
Conclusion
In this blog, I discussed how we can SSH into our cloud machines from our local machine without the use of public IPv4
addresses, and with the help of Tailscale using the CGNAT CIDR, thus saving the cost of using a public IPv4 address. I also discussed how we can create a JUMPBOX to do the same but with the cost of paying for only one IPv4
network rather than paying for IPv4
addresses for all the machines. These are some great alternatives to save the extra cost without transitioning into IPv6
addresses.
Posted on January 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.