{"slug":"access-your-virtual-private-cloud-vpc","title":"Access your virtual private cloud (VPC)","tags":["tailscale","access-control"],"agent_summary":"Last validated: Jan 5, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Access your virtual private cloud (VPC)\r\n\r\nLast validated: Jan 5, 2026\r\n\r\nThis topic is a quick guide for setting up a Linux [subnet router](https://tailscale.com/docs/features/subnet-routers) to access your virtual private cloud (VPC). You can also set up a subnet router on [Windows](https://tailscale.com/docs/features/subnet-routers?tab=windows#connect-to-tailscale-as-a-subnet-router) or [macOS](https://tailscale.com/docs/features/subnet-routers?tab=macos#connect-to-tailscale-as-a-subnet-router). For more detailed information, see [Connect to an AWS VPC using subnet routes](https://tailscale.com/docs/install/cloud/aws).\r\n\r\n## [Prerequisites](https://tailscale.com/docs/how-to/connect-vpc\\#prerequisites)\r\n\r\n- You need a [Tailscale account](https://tailscale.com/docs/how-to/quickstart).\r\n- You need a Linux VM. The following topics provide details for setting up a Linux VM using common cloud providers:\r\n  - [Create a Linux VM on Azure](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu).\r\n  - [Create a Linux VM on AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html).\r\n  - [Create a Linux VM on GCP](https://cloud.google.com/compute/docs/create-linux-vm-instance).\r\n- You need [Tailscale installed on your Linux VM](https://tailscale.com/docs/install/linux).\r\n- You need [Tailscale installed on your local machine](https://tailscale.com/download).\r\n\r\n## [Create a Tailscale subnet router](https://tailscale.com/docs/how-to/connect-vpc\\#create-a-tailscale-subnet-router)\r\n\r\n1. Start by jotting down the IP address of the private resources you want to access and determine the Classless Inter-Domain Routing (CIDR) notation that represents the subnet boundaries for those resources.\r\nFor example, if you have a VM at `10.0.0.3` and another at `10.0.1.4`, you might consider using CIDR notations `10.0.0.0/24` and `10.0.1.0/24` to represent these subnets\r\n\r\nCloud providers may also provide CIDR address spaces for your VPCs which you can just use out of the box. For example, here is a screenshot for AWS:\r\n![The AWS VPC page listing available VPCs. Highlighting an IPv4 CIDR range.](https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faws-cidr.14b31db0.png&w=1920&q=75)\r\nThis is a screenshot for Azure:\r\n![The Azure virtual network page with the details for a virtual network. Highlighting the IPv4 CIDR range.](https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fazure-cidr.c4c6a47e.png&w=1920&q=75)\r\n2. Start by accessing your VM to start configuring your subnet router.\r\n\r\n\r\n\r\nThis will most likely be the cloud-provided SSH mechanism and may require you to **temporarily** open up port `22` on that VM to your corporate network or the internet.\r\n\r\n3. In a terminal window, run the following command to check if you have `sysctl.d` on your system:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nls /etc | grep sysctl.d\r\n```\r\n\r\n4. If the command returns an output, it means `sysctl.d` is on your system, so you can run the following commands to set up IP forwarding on your router:\r\n\r\nIf your Linux system has a `/etc/sysctl.d` directory, use:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\necho 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf\r\necho 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf\r\nsudo sysctl -p /etc/sysctl.d/99-tailscale.conf\r\n```\r\n\r\n\r\n\r\nOtherwise, use:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\necho 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf\r\necho 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf\r\nsudo sysctl -p /etc/sysctl.conf\r\n```\r\n\r\n5. If you have firewalld installed on your VM instance, you should also allow masquerading for your subnet router to work:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nfirewall-cmd --permanent --add-masquerade\r\n```\r\n\r\n\r\n\r\nIf this command return an error that means you do not have `firewalld` installed and can skip to the next step.\r\n\r\n6. Finally, run the [`tailscale set`](https://tailscale.com/docs/reference/tailscale-cli#set) command to start advertising routes to your subnet (the routes your recorded in step 1):\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nsudo tailscale set --advertise-routes=<subnet range 1>,<subnet range 2>,...\r\n```\r\n\r\n\r\n\r\nRunning this step will cause the VM to authenticate with Tailscale. You will be asked to login with your credentials and add the device to your tailnet. Here's an example of running the command with the subnet ranges we used in step 1:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nsudo tailscale set --advertise-routes=10.0.0.0/24,10.0.1.0/24\r\n```\r\n\r\n7. Open the [Access controls](https://login.tailscale.com/admin/acls) page of the Tailscale admin console and add the following lines to your tailnet policy file to allow connectivity through your subnet:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```json\r\n\"grants\": [\\\r\n     {\\\r\n       \"src\": [\"john.doe@example.com\"],\\\r\n       \"dst\": [\"<subnet-range-1>/24\", \"<subnet-range-2>/24\"],\\\r\n       \"ip\": [\"*\"]\\\r\n     }\\\r\n]\r\n```\r\n\r\n\r\n\r\n\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\n\r\n\r\nThis lets the designated subnets be reachable by you and to the ports that you designate in the rule. Here's an example of a rule based on subnets in step 1 which grants access to all ports in the subnet range to the user `john.doe@example.com`:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```json\r\n\"grants\": [\\\r\n     {\\\r\n       \"src\": [\"john.doe@example.com\"],\\\r\n       \"dst\": [\"10.0.0.0/24\", \"10.0.1.0/24\"],\\\r\n       \"ip\": [\"*\"]\\\r\n     }\\\r\n]\r\n```\r\n\r\n\r\n\r\n\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\n8. If you are using a Linux-based local machine (not your subnet router) to connect, you need to run the [`tailscale set`](https://tailscale.com/docs/reference/tailscale-cli#set) command to accept the advertised routes. If you are not using a Linux-based local machine, you can skip this step.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nsudo tailscale set --accept-routes\r\n```\r\n\r\n\r\n## [Use the subnet router](https://tailscale.com/docs/how-to/connect-vpc\\#use-the-subnet-router)\r\n\r\n1. From step 1 in [Create a Tailscale subnet router](https://tailscale.com/docs/how-to/connect-vpc#create-a-tailscale-subnet-router), find the private IP addresses for the resources or machine that you are trying to reach.\r\n\r\n2. On your local machine, in a terminal window, ping those private IPs.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nping <your private vm ip address>\r\n```\r\n\r\n\r\n\r\nResponses from them indicate that your subnet router is working as expected.\r\n\r\nFor example, using private IPs in step 1:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nping 10.0.0.3 -t 4\r\n```\r\n\r\n\r\n\r\nIf successful, a response from these private IP addresses displays similar to:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nPING 10.0.0.3 (10.0.0.3): 56 data bytes\r\n64 bytes from 10.0.0.3: icmp_seq=0 ttl=64 time=0.112 ms\r\n64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.088 ms\r\n64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.175 ms\r\n64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.145 ms\r\n```\r\n\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 your virtual private cloud (VPC)</h1>\n<p>Last validated: Jan 5, 2026</p>\n<p>This topic is a quick guide for setting up a Linux <a href=\"https://tailscale.com/docs/features/subnet-routers\">subnet router</a> to access your virtual private cloud (VPC). You can also set up a subnet router on <a href=\"https://tailscale.com/docs/features/subnet-routers?tab=windows#connect-to-tailscale-as-a-subnet-router\">Windows</a> or <a href=\"https://tailscale.com/docs/features/subnet-routers?tab=macos#connect-to-tailscale-as-a-subnet-router\">macOS</a>. For more detailed information, see <a href=\"https://tailscale.com/docs/install/cloud/aws\">Connect to an AWS VPC using subnet routes</a>.</p>\n<h2><a href=\"https://tailscale.com/docs/how-to/connect-vpc#prerequisites\">Prerequisites</a></h2>\n<ul>\n<li>You need a <a href=\"https://tailscale.com/docs/how-to/quickstart\">Tailscale account</a>.</li>\n<li>You need a Linux VM. The following topics provide details for setting up a Linux VM using common cloud providers:\n<ul>\n<li><a href=\"https://learn.microsoft.com/en-us/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu\">Create a Linux VM on Azure</a>.</li>\n<li><a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html\">Create a Linux VM on AWS</a>.</li>\n<li><a href=\"https://cloud.google.com/compute/docs/create-linux-vm-instance\">Create a Linux VM on GCP</a>.</li>\n</ul>\n</li>\n<li>You need <a href=\"https://tailscale.com/docs/install/linux\">Tailscale installed on your Linux VM</a>.</li>\n<li>You need <a href=\"https://tailscale.com/download\">Tailscale installed on your local machine</a>.</li>\n</ul>\n<h2><a href=\"https://tailscale.com/docs/how-to/connect-vpc#create-a-tailscale-subnet-router\">Create a Tailscale subnet router</a></h2>\n<ol>\n<li>Start by jotting down the IP address of the private resources you want to access and determine the Classless Inter-Domain Routing (CIDR) notation that represents the subnet boundaries for those resources.\r\nFor example, if you have a VM at <code>10.0.0.3</code> and another at <code>10.0.1.4</code>, you might consider using CIDR notations <code>10.0.0.0/24</code> and <code>10.0.1.0/24</code> to represent these subnets</li>\n</ol>\n<p>Cloud providers may also provide CIDR address spaces for your VPCs which you can just use out of the box. For example, here is a screenshot for AWS:\r\n<img src=\"https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faws-cidr.14b31db0.png&#x26;w=1920&#x26;q=75\" alt=\"The AWS VPC page listing available VPCs. Highlighting an IPv4 CIDR range.\">\r\nThis is a screenshot for Azure:\r\n<img src=\"https://tailscale.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fazure-cidr.c4c6a47e.png&#x26;w=1920&#x26;q=75\" alt=\"The Azure virtual network page with the details for a virtual network. Highlighting the IPv4 CIDR range.\">\r\n2. Start by accessing your VM to start configuring your subnet router.</p>\n<p>This will most likely be the cloud-provided SSH mechanism and may require you to <strong>temporarily</strong> open up port <code>22</code> on that VM to your corporate network or the internet.</p>\n<ol start=\"3\">\n<li>In a terminal window, run the following command to check if you have <code>sysctl.d</code> on your system:</li>\n</ol>\n<pre><code class=\"language-shell\">ls /etc | grep sysctl.d\n</code></pre>\n<ol start=\"4\">\n<li>If the command returns an output, it means <code>sysctl.d</code> is on your system, so you can run the following commands to set up IP forwarding on your router:</li>\n</ol>\n<p>If your Linux system has a <code>/etc/sysctl.d</code> directory, use:</p>\n<pre><code class=\"language-shell\">echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf\r\necho 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf\r\nsudo sysctl -p /etc/sysctl.d/99-tailscale.conf\n</code></pre>\n<p>Otherwise, use:</p>\n<pre><code class=\"language-shell\">echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf\r\necho 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf\r\nsudo sysctl -p /etc/sysctl.conf\n</code></pre>\n<ol start=\"5\">\n<li>If you have firewalld installed on your VM instance, you should also allow masquerading for your subnet router to work:</li>\n</ol>\n<pre><code class=\"language-shell\">firewall-cmd --permanent --add-masquerade\n</code></pre>\n<p>If this command return an error that means you do not have <code>firewalld</code> installed and can skip to the next step.</p>\n<ol start=\"6\">\n<li>Finally, run the <a href=\"https://tailscale.com/docs/reference/tailscale-cli#set\"><code>tailscale set</code></a> command to start advertising routes to your subnet (the routes your recorded in step 1):</li>\n</ol>\n<pre><code class=\"language-shell\">sudo tailscale set --advertise-routes=&#x3C;subnet range 1>,&#x3C;subnet range 2>,...\n</code></pre>\n<p>Running this step will cause the VM to authenticate with Tailscale. You will be asked to login with your credentials and add the device to your tailnet. Here's an example of running the command with the subnet ranges we used in step 1:</p>\n<pre><code class=\"language-shell\">sudo tailscale set --advertise-routes=10.0.0.0/24,10.0.1.0/24\n</code></pre>\n<ol start=\"7\">\n<li>Open the <a href=\"https://login.tailscale.com/admin/acls\">Access controls</a> page of the Tailscale admin console and add the following lines to your tailnet policy file to allow connectivity through your subnet:</li>\n</ol>\n<pre><code class=\"language-json\">\"grants\": [\\\r\n     {\\\r\n       \"src\": [\"john.doe@example.com\"],\\\r\n       \"dst\": [\"&#x3C;subnet-range-1>/24\", \"&#x3C;subnet-range-2>/24\"],\\\r\n       \"ip\": [\"*\"]\\\r\n     }\\\r\n]\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<p>This lets the designated subnets be reachable by you and to the ports that you designate in the rule. Here's an example of a rule based on subnets in step 1 which grants access to all ports in the subnet range to the user <code>john.doe@example.com</code>:</p>\n<pre><code class=\"language-json\">\"grants\": [\\\r\n     {\\\r\n       \"src\": [\"john.doe@example.com\"],\\\r\n       \"dst\": [\"10.0.0.0/24\", \"10.0.1.0/24\"],\\\r\n       \"ip\": [\"*\"]\\\r\n     }\\\r\n]\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<ol start=\"8\">\n<li>If you are using a Linux-based local machine (not your subnet router) to connect, you need to run the <a href=\"https://tailscale.com/docs/reference/tailscale-cli#set\"><code>tailscale set</code></a> command to accept the advertised routes. If you are not using a Linux-based local machine, you can skip this step.</li>\n</ol>\n<pre><code class=\"language-shell\">sudo tailscale set --accept-routes\n</code></pre>\n<h2><a href=\"https://tailscale.com/docs/how-to/connect-vpc#use-the-subnet-router\">Use the subnet router</a></h2>\n<ol>\n<li>\n<p>From step 1 in <a href=\"https://tailscale.com/docs/how-to/connect-vpc#create-a-tailscale-subnet-router\">Create a Tailscale subnet router</a>, find the private IP addresses for the resources or machine that you are trying to reach.</p>\n</li>\n<li>\n<p>On your local machine, in a terminal window, ping those private IPs.</p>\n</li>\n</ol>\n<pre><code class=\"language-shell\">ping &#x3C;your private vm ip address>\n</code></pre>\n<p>Responses from them indicate that your subnet router is working as expected.</p>\n<p>For example, using private IPs in step 1:</p>\n<pre><code class=\"language-shell\">ping 10.0.0.3 -t 4\n</code></pre>\n<p>If successful, a response from these private IP addresses displays similar to:</p>\n<pre><code class=\"language-shell\">PING 10.0.0.3 (10.0.0.3): 56 data bytes\r\n64 bytes from 10.0.0.3: icmp_seq=0 ttl=64 time=0.112 ms\r\n64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.088 ms\r\n64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.175 ms\r\n64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.145 ms\n</code></pre>\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"}