DEV Community

Cover image for Mastering Connectivity: CG-NAT Solutions with Tailscale
Ayaan Bordoloi
Ayaan Bordoloi

Posted on

Mastering Connectivity: CG-NAT Solutions with Tailscale

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.

Image description
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.

Image description

  • 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)

Image description

  • At the top of your server dashboard you will see a console connect option, click on that.

Image description

  • The instance connection will open and you will see the following screen:

Image description

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.)

Image description

  • 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-

Image description

  • The top arrow indicates the private IPv4 address, and the arrow below indicates the IPv6 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
Enter fullscreen mode Exit fullscreen mode
  • 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:

Image description

  • Sign in to tailscale using any of the provided methods.
  • You will see the following screen after singing up-

Image description

  • 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
Enter fullscreen mode Exit fullscreen mode
  • 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.

Image description

  • 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]
Enter fullscreen mode Exit fullscreen mode

Image description

  • Now, you have successfully connected to your cloud machine through your local machine without requiring a public IPv4 address. How cool is that?!!

Image description

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 a IPv6 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.

Image description

  • 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-assign IPv6 address.

Image description

  • We cannot SSH into the Test instances because we have disabled the public IPv4 option. We only have a private IPv4 address and an IPv6 address. To SSH into the test instances, we will use the JUMPBOX, which has an IPv4 address assigned to it.
  • Head over to config file in the .ssh folder.
cd .ssh
code .
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  • 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)

Image description

  • Now, head over to the terminal and ssh into your test instances through your private IP.

Image description

  • 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.

Top comments (2)

Collapse
 
thosch66 profile image
Thomas Schewe

You donβ€˜t need to reset the password of the root-account. You can upload your public ssh-key to Hetzner and they will load it into the cloud instance. Ghis will allow you to access the machine via ssh passwordless.

(It is an security risk to use password authentication for ssh on any machine that is connected to the internet.)

Collapse
 
ayaan49 profile image
Ayaan Bordoloi • Edited

It requires a public IP to ssh into the machine, and public IP is not free. The point of this blog was to ssh into the machine without the use of public IP to reduce cost. We just needed a way to somehow get into the machine and install Tailscale so that we could connect the machine to our Tailscale network and ssh using that. That is the reason I used the password authentication method.

However, I missed a step where we needed to disable all root access and password based access after installing Tailscale. This will help us tackle that security risk. Thanks for bringing it to my notice.