{"slug":"access-aws-rds-privately-using-tailscale","title":"Access AWS RDS privately using Tailscale","tags":["tailscale","access-control","setup"],"agent_summary":"Last validated: Jan 5, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Access AWS RDS privately using Tailscale\r\n\r\nLast validated: Jan 5, 2026\r\n\r\nAmazon's Relational Database Service (AWS RDS) provides a managed relational\r\ndatabase accessible using SQL and other methods. RDS is an Amazon-managed service\r\nreached by using hostname, public IP address, or private IP address. To make RDS accessible to a\r\ntailnet, we use a [subnet router](https://tailscale.com/docs/features/subnet-routers).\r\n\r\n## [Prerequisites](https://tailscale.com/docs/install/cloud/aws/aws-rds\\#prerequisites)\r\n\r\nBefore you begin this guide, you'll need a Tailscale network set up and\r\nconfigured with at least one existing device. Read our [getting started guide](https://tailscale.com/docs/how-to/quickstart)\r\nif you need help with this.\r\n\r\nSetting up the RDS instance itself won't be covered here, we'll assume that RDS is\r\nalready in use. There are a number of different database engines available with RDS,\r\nfrom Amazon's own Aurora, MySQL, PostgreSQL, and more. The connectivity techniques\r\ndescribed here works with all of them.\r\n\r\nFor purposes of this topic, let's assume the RDS is set up in the `us-west-2` region.\r\n\r\n## [Step 1: Set up a subnet router](https://tailscale.com/docs/install/cloud/aws/aws-rds\\#step-1-set-up-a-subnet-router)\r\n\r\nFirst, [create an EC2 instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html)\r\nrunning Amazon Linux on either x86 or ARM. Tailscale produces Linux packages containing binaries\r\nfor both architectures, and the AWS ARM instances are very cost effective.\r\n\r\nSome AWS Regions have multiple data centers, each with an associated Availability Zone and\r\na subnet of IP addresses. RDS instances in a Region are reachable from all of these subnets,\r\nso the EC2 instance can be created on any of them. Other AWS managed services may require\r\nconnecting to a specific subnet.\r\n\r\nIf at least one side of a tunnel has \"easy NAT,\" where Tailscale can determine the UDP port\r\nnumber on the far side of the NAT device, then it will make\r\n[direct connections to minimize latency](https://tailscale.com/blog/how-tailscale-works).\r\nWhen setting the security policy, allow UDP port 41641 to ingress from any source. This will enable\r\n[direct connections](https://tailscale.com/docs/reference/faq/firewall-ports), to minimize latency.\r\n\r\n![Security Policy allow port 41641](https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsg-port-41641.ec775c1f.jpg&w=3840&q=75)\r\n\r\nThen SSH to the system and follow the steps to\r\n[install Tailscale on Amazon Linux](https://tailscale.com/docs/install/amazon-linux-2)\r\nand [configure subnet routing](https://tailscale.com/docs/features/subnet-routers).\r\nWhen running `tailscale up` or `tailscale set`, pass your VPC subnet to `--advertise-routes`.\r\nFor example, if the subnet address range is `172.31.0.0/16`, the command would be:\r\n\r\n```shell\r\ntailscale set --advertise-routes=172.31.0.0/16 --accept-dns=false\r\n```\r\n\r\nFor EC2 instances it is generally best to let Amazon handle the DNS configuration,\r\nnot have Tailscale override it, so we added `--accept-dns=false`.\r\n\r\nThe Windows, macOS, Android, iOS, and other clients all accept advertised routes by default, but\r\nLinux clients need to use `tailscale set --accept-routes=true` to use the routes being advertised\r\nby the subnet router in AWS.\r\n\r\n## [Step 2: Configure RDS security policy](https://tailscale.com/docs/install/cloud/aws/aws-rds\\#step-2-configure-rds-security-policy)\r\n\r\nWe need the RDS security policy to allow connection from the subnet router.\r\nThe RDS security policy can be found in the instance details of the RDS instance.\r\nWe add the security policy created for the EC2 subnet router instance.\r\n\r\n![Add subnet relay to RDS security policy](https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Frds-sg-add-ec2.00bc51a3.jpg&w=3840&q=75)\r\n\r\n## [Step 3: Add AWS DNS for your tailnet](https://tailscale.com/docs/install/cloud/aws/aws-rds\\#step-3-add-aws-dns-for-your-tailnet)\r\n\r\nFor the benefit of the _other_ nodes in the tailnet we'll set up\r\n[split DNS](https://tailscale.com/docs/reference/dns-in-tailscale#tailscale-dns-settings) to allow\r\nuse of the same DNS names as are used inside of AWS.\r\n\r\nThe AWS DNS server address is always [the base of the VPC subnet + 2](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_DHCP_Options.html#AmazonDNS).\r\nFor example, if the subnet is `172.31.0.0`, the DNS server will be `172.31.0.2`. In the\r\n[DNS](https://login.tailscale.com/admin/dns) page of the admin console, add the AWS DNS server and restrict\r\nit to the region-specific `rds.amazonaws.com` domain, for example, `us-west-2.rds.amazonaws.com`.\r\n\r\n![Adding a split DNS resolver for us-west-2.rds.amazonaws.com](https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faws-split-dns.b70fa376.jpg&w=828&q=75)\r\n\r\nWe recommend [hiding your DB instance from the internet](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html#USER_VPC.Hiding) to prevent access over the internet.\r\n\r\n## [Step 4: Remove public SSH access](https://tailscale.com/docs/install/cloud/aws/aws-rds\\#step-4-remove-public-ssh-access)\r\n\r\nAs we can now SSH to the system over the private Tailscale network, there is no reason to leave\r\nthe SSH port open on a public IP address. In the security group for the EC2 instance, delete the\r\nSSH rule allowing inbound connections.\r\n\r\n![Removing public SSH access](https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faws-disable-ssh.d2b1cf3c.jpg&w=3840&q=75)\r\n\r\n## [Step 5: Connect to RDS](https://tailscale.com/docs/install/cloud/aws/aws-rds\\#step-5-connect-to-rds)\r\n\r\nWe can now connect to RDS from any node in the tailnet, using the same DNS name as is used inside AWS.\r\n\r\nFor example, to access your RDS server from your personal computer, while logged into your tailnet:\r\n\r\n```shell\r\nmysqlsh --uri=admin@database-2.0123456789ab.us-west-2.rds.amazonaws.com:3306\r\n MySQL  database-2.0123456789ab.us-west-2.rds.amazonaws.com:3306 ssl  JS > \\sql\r\nSwitching to SQL mode... Commands end with ;\r\nMySQL  database-2.0123456789ab.us-west-2.rds.amazonaws.com:3306 ssl  SQL > show databases;\r\n+--------------------+\r\n| Database           |\r\n+--------------------+\r\n| demo               |\r\n| information_schema |\r\n| mysql              |\r\n| performance_schema |\r\n| sys                |\r\n+--------------------+\r\n5 rows in set (0.0297 sec)\r\n```\r\n\r\nUsing a subnet router lets you connect to many services within AWS, not just RDS, using their internal AWS IP address.\r\n\r\n![Project Logo](https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed)\r\n\r\nAsk AI\r\n\r\nreCAPTCHA\r\n\r\nRecaptcha requires verification.\r\n\r\nprotected by **reCAPTCHA**\r\n","html":"<h1>Access AWS RDS privately using Tailscale</h1>\n<p>Last validated: Jan 5, 2026</p>\n<p>Amazon's Relational Database Service (AWS RDS) provides a managed relational\r\ndatabase accessible using SQL and other methods. RDS is an Amazon-managed service\r\nreached by using hostname, public IP address, or private IP address. To make RDS accessible to a\r\ntailnet, we use a <a href=\"https://tailscale.com/docs/features/subnet-routers\">subnet router</a>.</p>\n<h2><a href=\"https://tailscale.com/docs/install/cloud/aws/aws-rds#prerequisites\">Prerequisites</a></h2>\n<p>Before you begin this guide, you'll need a Tailscale network set up and\r\nconfigured with at least one existing device. Read our <a href=\"https://tailscale.com/docs/how-to/quickstart\">getting started guide</a>\r\nif you need help with this.</p>\n<p>Setting up the RDS instance itself won't be covered here, we'll assume that RDS is\r\nalready in use. There are a number of different database engines available with RDS,\r\nfrom Amazon's own Aurora, MySQL, PostgreSQL, and more. The connectivity techniques\r\ndescribed here works with all of them.</p>\n<p>For purposes of this topic, let's assume the RDS is set up in the <code>us-west-2</code> region.</p>\n<h2><a href=\"https://tailscale.com/docs/install/cloud/aws/aws-rds#step-1-set-up-a-subnet-router\">Step 1: Set up a subnet router</a></h2>\n<p>First, <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html\">create an EC2 instance</a>\r\nrunning Amazon Linux on either x86 or ARM. Tailscale produces Linux packages containing binaries\r\nfor both architectures, and the AWS ARM instances are very cost effective.</p>\n<p>Some AWS Regions have multiple data centers, each with an associated Availability Zone and\r\na subnet of IP addresses. RDS instances in a Region are reachable from all of these subnets,\r\nso the EC2 instance can be created on any of them. Other AWS managed services may require\r\nconnecting to a specific subnet.</p>\n<p>If at least one side of a tunnel has \"easy NAT,\" where Tailscale can determine the UDP port\r\nnumber on the far side of the NAT device, then it will make\r\n<a href=\"https://tailscale.com/blog/how-tailscale-works\">direct connections to minimize latency</a>.\r\nWhen setting the security policy, allow UDP port 41641 to ingress from any source. This will enable\r\n<a href=\"https://tailscale.com/docs/reference/faq/firewall-ports\">direct connections</a>, to minimize latency.</p>\n<p><img src=\"https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsg-port-41641.ec775c1f.jpg&#x26;w=3840&#x26;q=75\" alt=\"Security Policy allow port 41641\"></p>\n<p>Then SSH to the system and follow the steps to\r\n<a href=\"https://tailscale.com/docs/install/amazon-linux-2\">install Tailscale on Amazon Linux</a>\r\nand <a href=\"https://tailscale.com/docs/features/subnet-routers\">configure subnet routing</a>.\r\nWhen running <code>tailscale up</code> or <code>tailscale set</code>, pass your VPC subnet to <code>--advertise-routes</code>.\r\nFor example, if the subnet address range is <code>172.31.0.0/16</code>, the command would be:</p>\n<pre><code class=\"language-shell\">tailscale set --advertise-routes=172.31.0.0/16 --accept-dns=false\n</code></pre>\n<p>For EC2 instances it is generally best to let Amazon handle the DNS configuration,\r\nnot have Tailscale override it, so we added <code>--accept-dns=false</code>.</p>\n<p>The Windows, macOS, Android, iOS, and other clients all accept advertised routes by default, but\r\nLinux clients need to use <code>tailscale set --accept-routes=true</code> to use the routes being advertised\r\nby the subnet router in AWS.</p>\n<h2><a href=\"https://tailscale.com/docs/install/cloud/aws/aws-rds#step-2-configure-rds-security-policy\">Step 2: Configure RDS security policy</a></h2>\n<p>We need the RDS security policy to allow connection from the subnet router.\r\nThe RDS security policy can be found in the instance details of the RDS instance.\r\nWe add the security policy created for the EC2 subnet router instance.</p>\n<p><img src=\"https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Frds-sg-add-ec2.00bc51a3.jpg&#x26;w=3840&#x26;q=75\" alt=\"Add subnet relay to RDS security policy\"></p>\n<h2><a href=\"https://tailscale.com/docs/install/cloud/aws/aws-rds#step-3-add-aws-dns-for-your-tailnet\">Step 3: Add AWS DNS for your tailnet</a></h2>\n<p>For the benefit of the <em>other</em> nodes in the tailnet we'll set up\r\n<a href=\"https://tailscale.com/docs/reference/dns-in-tailscale#tailscale-dns-settings\">split DNS</a> to allow\r\nuse of the same DNS names as are used inside of AWS.</p>\n<p>The AWS DNS server address is always <a href=\"https://docs.aws.amazon.com/vpc/latest/userguide/VPC_DHCP_Options.html#AmazonDNS\">the base of the VPC subnet + 2</a>.\r\nFor example, if the subnet is <code>172.31.0.0</code>, the DNS server will be <code>172.31.0.2</code>. In the\r\n<a href=\"https://login.tailscale.com/admin/dns\">DNS</a> page of the admin console, add the AWS DNS server and restrict\r\nit to the region-specific <code>rds.amazonaws.com</code> domain, for example, <code>us-west-2.rds.amazonaws.com</code>.</p>\n<p><img src=\"https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faws-split-dns.b70fa376.jpg&#x26;w=828&#x26;q=75\" alt=\"Adding a split DNS resolver for us-west-2.rds.amazonaws.com\"></p>\n<p>We recommend <a href=\"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html#USER_VPC.Hiding\">hiding your DB instance from the internet</a> to prevent access over the internet.</p>\n<h2><a href=\"https://tailscale.com/docs/install/cloud/aws/aws-rds#step-4-remove-public-ssh-access\">Step 4: Remove public SSH access</a></h2>\n<p>As we can now SSH to the system over the private Tailscale network, there is no reason to leave\r\nthe SSH port open on a public IP address. In the security group for the EC2 instance, delete the\r\nSSH rule allowing inbound connections.</p>\n<p><img src=\"https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faws-disable-ssh.d2b1cf3c.jpg&#x26;w=3840&#x26;q=75\" alt=\"Removing public SSH access\"></p>\n<h2><a href=\"https://tailscale.com/docs/install/cloud/aws/aws-rds#step-5-connect-to-rds\">Step 5: Connect to RDS</a></h2>\n<p>We can now connect to RDS from any node in the tailnet, using the same DNS name as is used inside AWS.</p>\n<p>For example, to access your RDS server from your personal computer, while logged into your tailnet:</p>\n<pre><code class=\"language-shell\">mysqlsh --uri=admin@database-2.0123456789ab.us-west-2.rds.amazonaws.com:3306\r\n MySQL  database-2.0123456789ab.us-west-2.rds.amazonaws.com:3306 ssl  JS > \\sql\r\nSwitching to SQL mode... Commands end with ;\r\nMySQL  database-2.0123456789ab.us-west-2.rds.amazonaws.com:3306 ssl  SQL > show databases;\r\n+--------------------+\r\n| Database           |\r\n+--------------------+\r\n| demo               |\r\n| information_schema |\r\n| mysql              |\r\n| performance_schema |\r\n| sys                |\r\n+--------------------+\r\n5 rows in set (0.0297 sec)\n</code></pre>\n<p>Using a subnet router lets you connect to many services within AWS, not just RDS, using their internal AWS IP address.</p>\n<p><img src=\"https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed\" alt=\"Project Logo\"></p>\n<p>Ask AI</p>\n<p>reCAPTCHA</p>\n<p>Recaptcha requires verification.</p>\n<p>protected by <strong>reCAPTCHA</strong></p>\n"}