Beberapa dari pembaca blog ini pasti sudah tahu jika gueadalahfansberatTailscale. Bukan hanya Wireguard mengubah pendekatan untuk membuat VPN, tapi kombinasi dari solusi yang ditawarkan Tailscale mengubah cara pandang tentang bagaimana memperlakukan jaringan private. Dari yang sebelumnya hanya menggunakan Tailscale untuk keperluan pribadi, pada bulan April kemarin, di kantor gue resmi berlangganan Tailscale sampai hari ini dan seterusnya.

VPN sederhananya adalah tentang menghubungkan jaringan pribadi diatas jaringan publik (internet). Misal, jika ingin menghubungkan jaringan rumah gue (192.168.100.0/24) dengan komputer gue somewhere di GCP, setidaknya ada 2 pilihan:

  1. Hubungkan router gue dengan ke router yang ada di data center GCP lewat kabel
  2. Bikin VPN

Pilihan nomor satu tentu tidak mungkin, menghubungkan router gue dari Cilandak ke somewhere asia-southeast-2 lewat kabel adalah lelucon. Dan of course, tidak akan pernah terjadi sekalipun di kondisi “bisa aja”.

Pilihan nomor dua adalah yang paling masuk akal. Komputer gue terhubung ke komputer yang ada di data center GCP secara virtual, melalui jaringan internet. Kabel penghubung dari VPN dalam konteks ini adalah transport protocol alias apapun yang berada di layer 4. Dengan setup tertentu, komputer gue di GCP yang memiliki alamat IP private 10.184.0.18 dapat berkomunikasi dengan komputer gue di rumah yang memiliki alamat IP 192.168.100.46 yang mana berada di subnet berbeda.

Sepertinya cukup untuk pengenalan VPN secara singkat, dan sepertinya gue tidak perlu membahas tentang mengapa menggunakan Tailscale. Melainkan, kita akan bahas tentang apa yang menjadi judul dari tulisan ini.

Sekilas tentang Pomerium

Singkatnya, Pomerium adalah sebuah reverse proxy. Hal yang sama ketika lo mengakses blog ini, blog ini berjalan di jaringan rumah gue, dan agar bisa diakses oleh pengguna internet, reverse proxy yang berjalan di jaringan Cloudflare meneruskan request ke server rumah gue dari komputer lo, dan sebaliknya.

Seperti reverse proxy lainnya dari Nginx; OpenResty, HAProxy, Traefik, H2O, Caddy, dsb.

Yang berbeda dari Pomerium adalah Pomerium terintegrasi dengan IdP by… design? or default? Di tulisan ini sekilas gue bahas tentang bagaimana serangan DNS rebinding dapat terjadi berikut dengan pencegahannya yang mana dengan menggunakan middleware untuk memasukkan 100.64.0.0/10 ke allowlist secara eksplisit, yang technically ini kesalahan admin, dan masalah terkait VPN pada umumnya adalah semua yang berada di jaringan VPN dianggap terpercaya.

Autentikasi di Tailscale adalah per perangkat. Setiap perangkat harus melakukan autentikasi melalui IdP yang digunakan, misal, Google SSO. Jika koneksi tersambung end-to-end antar perangkat, kita harus mempercayakan Tailscale sebagai control plane nya.

Tailscale juga menawarkan ACL, ini adalah tentang siapa dapat mengakses apa. Misal, ada internal services yang hanya boleh diakses oleh grup finance, dan ada yang hanya boleh diakses melalui grup engineering. Disamping itu, hanya grup devops dan admin yang dapat akses apapun sekalipun ke port 22.

Problem dari Tailscale adalah bagaimana bila seseorang tanpa VPN client ingin mengakses internal services tersebut?

…tanpa mengorbankan sisi keamanan.

Salah satu internal services yang paling banyak diakses oleh developers di tempat gue sekarang adalah ddl-backdoor, ini adalah codename tempat “VSCode in browser” berjalan. Services ini menjalankan container (podman) dalam container (containerd), siapapun—khususnya yang sedang on-call—dapat mengakses lingkungan production yang hanya diperuntukkan untuk keperluan bisnis.

Services ini berjalan di VPC khusus yang sama dengan production. Untuk dapat mengakses services tersebut, setidaknya ada 3 hal yang bisa dipilih:

  1. Membuat VM ephemeral yang berada di VPC tersebut. Ini impossible, karena pada akhirnya tidak ada akses SSH kesana :)
  2. Menjalankan Tailscale sebagai sidecar
  3. Menggunakan reverse proxy sebagai penghubung antara internet dengan internal services tersebut

Nomor 2 tidak kita pilih, karena goals nya adalah untuk bisa mengakses services tersebut tanpa software tambahan, dalam kasus ini berarti VPN client (Tailscale).

Untuk nomor 3, kita harus memastikan bahwa hanya pengguna internet tertentu yang dapat mengaksesnya. Daripada membuat “authentication layer” sendiri yang tidak ISO compliant, kita ingin menggunakan Google SSO, sebagaimana ketika mendaftarkan device di jaringan Tailscale.

Pomerium exactly melakukan hal tersebut.

Ketika siapapun mengakses services internal tersebut, dia akan diarahkan ke SSO provider terlebih dahulu. Pomerium menawarkan ACL serupa meskipun tidak head-to-head sama dengan Tailscale. Hanya orang-orang dengan alamat email yang sudah ditentukan yang dapat mengakses services tersebut, sisanya denied.

Disini gue harus mempercayakan Pomerium sebagai control plane, dan kabar baiknya, Pomerium adalah produk Open Source dan dapat dijalankan self-hosted.

Pomerium & Tailscale

Pada dasarnya ini adalah dua hal berbeda: Pomerium adalah reverse proxy dan Tailscale adalah VPN. Meskipun sama-sama menawarkan akses dan keamanan, ini memiliki 2 pendekatan berbeda.

Misal untuk menghubungkan 2 subnet berbeda (point-to-point). Untuk menghubungkan jaringan 10.0.10.0/24 dengan 10.0.9.0/24, kedua gateway tersebut setidaknya harus terhubung di satu switch/router yang sama. Jika tidak memungkinkan secara fisik, tentu saja alternatifnya dengan menghubungkannya secara virtual. Yang berarti, membuat VPN.

Meskipun Pomerium mendukung TCP proxy (TCP over HTTP), ini membutuhkan software/klien tambahan dan yang paling penting, tidak menyelesaikan masalah sebelumnya.

Yang berarti, jika dihadapkan pertanyaan “Mending menggunakan Tailscale atau Pomerium?” jawabannya adalah “yes”.

Pilih keduanya.

Tailscale Funnel

Pada tanggal 17 November 2022 kemarin, Tailscale mengumumkan fitur baru bernama Tailscale Funnel. Fitur ini masih dalam status alpha dan invite-only, tapi ini invite link nya jika ingin mencoba.

Tailscale Funnel memungkinkan apa yang dilakukan oleh Pomerium. Karena masih dalam status alpha, ada beberapa limitasi: Dan yang harus digaris bawahi adalah yang pertama: DNS hanya bisa di resolve oleh perangkat yang berada dalam 1 tailnet. Tapi untuk demo, kita bisa berbuat curang sedikit untuk mendapatkan gambaran.

Setelah mengaktifkan funnel, layanan gue bisa diakses di colima.tailnet-ead2.ts.net.

Ini adalah “mesin” yang ingin gue gunakan untuk mengakses layanan tersebut: Disitu terlihat bahwa tidak ada interface tailscale0 atau apapun yang bertanggung jawab untuk melakukan routing ke 100.64.0.0/10 (Tailscale). Berdasarkan hasil traceroute diatas, gampangnya:

  1. Request ke 100.64.0.0/10 akan di handle oleh si gateway di docker network (172.19.0.1)
  2. Si gateway tersebut meneruskan request ke gateway lain yang mana ip di mesin gue 192.168.5.2
  3. Seharusnya request selanjutnya diarahkan ke container dengan ip 172.17.0.2, tempat si Tailscale Funnel gue berjalan. Disini gue menggunakan user-space networking karena si Tailscale berjalan di container

Setup diatas agak valid untuk menggambarkan “tidak ada Tailscale yang berjalan di mesin A” ketika si mesin A mencoba akses port 443 ke mesin B via colima.tailnet-ead2.ts.net.

Dan berikut tampilannya:

Tailscale funnel wishlist

Gue belum mencoba apakah menambahkan CNAME ke target.tailnet-xxxx.ts.net dapat berhasil. Di setup kantor gue, gue menggunakan wildcard domain (*.something.io) untuk internal services, yang mana merujuk ke IP si ingress, yang kemudian meneruskan request nya ke si Pomerium.

Jika hal tersebut memungkinkan, ini sangat menarik. Seperti, untuk akses ke backdoor.x.something.io diarahkan ke backdoor.tailnet-xxxx.ts.net , jika diakses melalui device yang terpasang Tailscale dan berada dalam 1 tailnet, ini bisa langsung terhubung tanpa harus login ke SSO lagi.

Jika tidak, gue rasa akan diarahkan melalui ingress-xxx-xx.tailscale.com yang mana per tulisan ini dibuat memiliki IP 208.111.34.11 untuk ingress-sfo-01.tailscale.com, dan semoga login melalui SSO memungkinkan. Yang semoga juga Tailscale menawarkan “bring your own ingress” sebagaimana fitur “bring your own DERP” yang sudah gue lakukan sejak lama.

Jika dua hal diatas memungkinkan, ini bisa menghapus ketergantungan gue ke Pomerium. ACL dapat dilakukan di level Tailscale, misal, seperti:

"acls": [
  {
    "action": "accept",
    "src"   : ["@something.io"],
    "dst"   : ["funnel:443"],
  }
]

Yang maksudnya, setiap request yang datang dari seseorang yang terautentikasi sebagai @something.io, dapat mengakses port 443 di semua hosts yang berada di grup funnel.

Tapi disini ada bias. Strategi pricing Tailscale adalah per user. Paket Team nya memungkinkan untuk 4 users (identitas) terhubung ke Tailnet. Yang berarti, 4 users tersebut adalah:

Setiap users mendapatkan jatah 5 devices, yang berarti, untuk paket Team, setidaknya ada maksimal 20 devices yang bisa didaftarkan. Addons nya adalah $5/user jika sudah masuk ke limit users atau $4.20/10 devices jika limit nya ada di devices.

Jika “Login with SSO” ketika mengakses Tailscale Funnel (jika memang ada) dihitung berdasarkan users, ini kurang fair. Pertama, alasan utama menggunakan Tailscale Funnel adalah agar users yang tidak memasang Tailscale di perangkatnya masih bisa mengakses something. Karena poin pertama tersebut, jika kondisi “daftar tapi tidak perlu memasang tailscale” memungkinkan, ini masih kurang fair, karena total devices selalu dihitung dari total users.

Menurut gue perhitungan yang paling fair adalah dengan menggunakan pool bandwidth, sebagaimana poin 3 dari bagian “Limitations” nya. Misal, bila 1 device memiliki jatah 10 GB bandwidth, setidaknya paket plan memiliki 50 GB bandwidth pool, yang mana cukup fair. Jika melebihi limit, alih-alih harus menambahkan users/devices, alternatifnya bisa membeli addons, misal, $4.20/20 GB. Ini gue rasa win-to-win karena tidak ada redundant users/devices, dan bandwidth tersebut untuk membayar si “ingress”.

Disamping itu ACL pun menjadi barang yang dijual Tailscale. Untuk paket Team, mereka mendapatkan 5 unique users in ACLs. Addons nya adalah $5/users. Dilemanya ada 2:

  1. Ada built-in ACL untuk non-tailscale users yang mengakses Funnel, yang mana digeneralisir misal menjadi funnel@something.io, yang berarti tidak ada unique users in ACLs (setiap users dengan @something.io dapat mengakses funnel apapun)
  2. Tidak ada “built-in ACL untuk non-tailscale users” alias semuanya dianggap as is

Poin pertama ini make sense diterapkan karena, sekali lagi, ACL adalah salah satu barang yang dijual Tailscale. Dilemanya adalah jika setiap users yang mengakses funnel dianggap as is sebagaimana di poin kedua, dan gue belum menemukan win-win solution untuk hal itu.

Penutup

Jika suatu saat nanti Tailscale Funnel sudah tidak di status Alpha/Beta, dan menawarkan:

  • Fitur Login with SSO secara opsional ketika mengakses Funnel
  • Dapat membedakan tailnet users dan non-tailnet users
  • Dapat menjalankan ingress sendiri
  • Harga ditentukan berdasarkan bandwidth, yang tidak bergantung dengan total users/devices

Sudah pasti gue akan menghapus ketergantungan dengan Pomerium. Jika salah satu atau keempat poin diatas tidak memungkinkan, mungkin gue akan menggunakan Tailscale Funnel untuk kebutuhan pribadi aja, seperti, menghapus ketergantungan dengan Cloudflare Access.

Untuk saat ini gue masih menyimpan kepercayaan terhadap Pomerium, dan masih menggunakan Tailscale untuk melakukan apa yang tidak bisa Pomerium lakukan.

Kehadiran Tailscale Funnel membuat “Tailscale bisa melakukan apa yang Pomerium tidak bisa lakukan” yang mana menjadi nilai plus Tailscale, dari yang sebelumnya “Pomerium bisa melakukan apa yang Tailscale tidak bisa lakukan” yakni melakukan HTTP(s) proxy dengan prinsip ZeRO trUsT.

Kompetitor utama Tailscale yang menurut gue paling potensial adalah Twingate, meskipun gue belum pernah mencobanya.

…dan tentu saja Cloudflare.

Pomerium adalah solusi lain untuk masalah lain, tapi gue rasa, Pomerium tidak bisa memberikan solusi yang Tailscale berikan, **kecuali, **mengubah direksi menjadi “solusi ZTNA dengan pendekatan berbeda lainnya”.

Dan dari persaingan VPN dan ZTNA ini, gue hanya ingin melihat Tailscale menang.