Tailscale
Allikas: Imre kasutab arvutit
Mine navigeerimisribaleMine otsikasti
Sissejuhatus
Tailscale https://tailscale.com/ tarkvara võimaldab muu hulgas nö ad-hoc vpn lahenduse moodustamist
- kasutada on lihtne (erinevalt vanilla wireguard kasutamisest ei pea võtmete-seadistamiste-jms tegelema)
- massiivselt erinevate platvormide kliente (nutitelefonid, nö tavalised operatsioonisüsteemid jms)
- eeldab tailscale.com isandate usaldamist
- töötab nö udp-hole-punching p2p põhimõttel
- võimalik sättida omavahel suhtlema tulemüüride taga asuvaid privaatseid ip aadresse kasutavaid seadmeid, iseeneest nad otse üksteise poole pöörduda ei saaks
Mõisted
- tailscale
- tailnet
- taildrop
Tööpõhimõte
Väited
- lihtne käivitada lõppkasutaja seisukohast (ei ole vaja tegeleda võtmetega otseselt, st see tehakse taustal automaatselt ära)
- kasutamine eeldab omajagu tailscale.com isandate usaldamist
- põhineb wireguard tarkvaral
Võrgujoonis
tailscale isand internetis
_______
| |
| |
|_______| eth0 - pub ip aadress
|
|
internet
pub ip aadress pub ip aadress
local tulemüür - 01 local tulemüür - 02
no dnat, only snat no dnat, only snat
no spat no spat
| |
___|___ eth0 - priv ip aadress ___|___ eth0 - priv ip aadress
| | | |
| | | |
|_______| tailscale0 - 100.121.207.99/32 |_______| tailscale0 - 100.66.245.64/32
pwrk-02 ts-01
kus
- local tulemüür 01 ja 02 on eraldi seade avaliku ja sisemise ip aadressiga, seest internetti suunal toimub nat, väljast sisse mitte; kusjuures seest välja pakettidel ei toimub source port muutust
- pwrk-02 ja ts-01 ei saa otse üksteise poole pöörduda, seda tehakse vahendaja (isanda) abil - kasutades 'udp hole punching' tehnikat
tulemusena töötab kontakt tailscale liideste vahel
root@pwrk-02:~# ping -c 2 100.66.245.64 PING 100.66.245.64 (100.66.245.64) 56(84) bytes of data. 64 bytes from 100.66.245.64: icmp_seq=1 ttl=64 time=28.9 ms 64 bytes from 100.66.245.64: icmp_seq=2 ttl=64 time=14.4 ms --- 100.66.245.64 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 14.369/21.623/28.878/7.254 ms
UDP hole punching
UDP hole punching seisneb selles, et
- pwrk-02 pöördub isanda poole ja sealt on näha välja mineva paketi src port
- ts-01 pöördub isanda poole ja sealt on näha välja mineva paketi src port
- isand vastab mõlemale teise kaaslase src ip pordiga
- pwrk-02 ja ts-01 pöörduvad üksteise poole nö pimedalt ja vastavad üksteisele pimedalt
- kuna kummagi arvuti eest töötav tulemüür ei muuda src porti väärtust ja stateful tulemüür avab tagasipöörduvale udp paketile läbipääsu, siis saab nö omaalgatuslikult sisse saadetud vastuspakett tulemüürist läbi
- jätkub suures osas peer-to-peer suhtlemine
Misc
Teenusepakkuja juures seadmete registreerimine
kus
- pwrk-02 - seade ühes interneti otsas
- ts-01 - seade teises interneti otsas
Registreerimine toimub sellisel põhimõttel
- kasutajal on kasutada google.com konto
- kasutaja logib sisse tailscale veebikohta google kontoga (oidc vms lähenemise abil) ja näeb seal registreeritud arvutite nimekirja vms
- kasutaja ütleb lisatavas arvutis tailscale up ja vastuseks saab lingi
...
- kasutaja pasteb lingi brauserisse millega on google kontoga kontakt ning seda linki aktsepteeritakse
- teise arvutiga sama tegevus
- tulemusena on tailscale isandat veendud, et mõlemad arvutid on sama google konto kasutaja kontrolli all
Tarkvara paigaldamine
# curl ...
Failisüsteemi lisatakse muu hulgas
root@pwrk-02:~# dpkg -L tailscale /etc /etc/default /etc/default/tailscaled /lib diverted by base-files to: /lib.usr-is-merged /lib/systemd /lib/systemd/system /lib/systemd/system/tailscaled.service /usr /usr/bin /usr/bin/tailscale /usr/sbin /usr/sbin/tailscaled
kusjuures tailscale ja tailscaled on staatilised failid
root@pwrk-02:~# ldd /usr/bin/tailscale not a dynamic executable root@pwrk-02:~# ldd /usr/sbin/tailscaled not a dynamic executable root@pwrk-02:~# file /usr/bin/tailscale /usr/bin/tailscale: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=Frc8czhMPI4TkzPHZLGo/SoqAvNVuRoh1d3027b4h/PwayEUv1R2URpzOWznLI/Hbm-pdUsoQkTLL0ztPat, BuildID[sha1]=afade7a0fdda938c236dbaf9f56bccc905891ba9, with debug_info, not stripped root@pwrk-02:~# file /usr/sbin/tailscaled /usr/sbin/tailscaled: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=_7aHzSbINt8U-7aal4KV/jio6APNmVYxIeIZkrKRE/lUrKhZFyG0goF2KRA5Ol/yXJqaT22If5OOJtesmxs, BuildID[sha1]=5d88bea66e8933134c77d311b2481e0a206dc523, with debug_info, not stripped
asjasse puutuvad failid sh krüptomateral
root@pwrk-02:~# find /var/lib/tailscale/ -ls 787147 4 drwx------ 3 root root 4096 Apr 25 15:29 /var/lib/tailscale/ 787040 4 -rw------- 1 root root 2698 Apr 25 15:29 /var/lib/tailscale/tailscaled.state 786536 16 -rw------- 1 root root 15055 Apr 25 13:45 /var/lib/tailscale/derpmap.cached.json 787183 4 -rw------- 1 root root 209 Apr 25 13:42 /var/lib/tailscale/tailscaled.log.conf 786579 4 drwx------ 3 root root 4096 Apr 25 13:45 /var/lib/tailscale/files 787007 4 drwx------ 2 root root 4096 Apr 25 13:45 /var/lib/tailscale/files/imre.oolberg-gmail.com-uid-4916328083301376 787250 0 -rw------- 1 root root 0 Apr 25 16:52 /var/lib/tailscale/tailscaled.log1.txt 787282 0 -rw------- 1 root root 0 Apr 25 17:00 /var/lib/tailscale/tailscaled.log2.txt
kus
root@pwrk-02:~# cat /var/lib/tailscale/tailscaled.state
{
"_current-profile": "cHJvZmlsZS1iMTA3",
"_machinekey": "cHJpdmtleTpmOGNjYzA2YTgyMDllMTExZDgwZTgxZDMwM ...",
"_profiles": "eyJiMTA3Ijp7IklEIjo ... ",
"profile-b107": "ewoJIk ... "
kus
# echo "ewoJIk ... " | base64 -d
{
"ControlURL": "https://controlplane.tailscale.com",
"RouteAll": false,
"ExitNodeID": "",
"ExitNodeIP": "",
"InternalExitNodePrior": "",
"ExitNodeAllowLANAccess": false,
"CorpDNS": true,
"RunSSH": false,
"RunWebClient": false,
"WantRunning": true,
"LoggedOut": false,
"ShieldsUp": false,
"AdvertiseTags": null,
"Hostname": "",
"NotepadURLs": false,
"AdvertiseRoutes": null,
"AdvertiseServices": null,
"Sync": null,
"NoSNAT": false,
"NoStatefulFiltering": true,
"NetfilterMode": 2,
"AutoUpdate": {
"Check": true,
"Apply": true
},
"AppConnector": {
"Advertise": false
},
"PostureChecking": false,
"NetfilterKind": "",
"DriveShares": null,
"AllowSingleHosts": true,
"Config": {
"PrivateNodeKey": "privkey:98adf1348de16 ...",
"OldPrivateNodeKey": "privkey:0000000000000000000000000000000000000000000000000000000000000000",
"UserProfile": {
"ID": 49163 ...,
"LoginName": "imre.oolberg@gmail.com",
"DisplayName": "Imre Oolberg",
"ProfilePicURL": "https://lh3.googleusercontent.com/a/ACg8ocJoZc0K7dx ..."
},
"NetworkLockKey": "nlpriv:f7efba98cda43 ...",
"NodeID": "nE1uKyy .."
}
}root@pwrk-02:~#
systemd unit
root@pwrk-02:~# systemctl status tailscaled
● tailscaled.service - Tailscale node agent
Loaded: loaded (/usr/lib/systemd/system/tailscaled.service; enabled; preset: enabled)
Active: active (running) since Sat 2026-04-25 15:28:10 UTC; 2h 29min ago
Docs: https://tailscale.com/docs/
Main PID: 2400 (tailscaled)
Status: "Connected; imre.oolberg@gmail.com; 100.121.207.99 fd7a:115c:a1e0::1537:cf63"
Tasks: 11 (limit: 9405)
Memory: 15.3M (peak: 17.6M)
CPU: 2.922s
CGroup: /system.slice/tailscaled.service
└─2400 /usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=41641
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: health(warnable=wantrunning-false): ok
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: health(warnable=warming-up): ok
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: health(warnable=no-derp-connection): ok
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: magicsock: derp-28 connected; connGen=1
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: health(warnable=no-derp-connection): ok
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: [RATELIMIT] format("health(warnable=%s): ok")
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: control: RegisterReq: got response; nodeKeyExpired=false, machineAuthorized=true; authURL=false
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: control: netmap: got new dial plan from control
Apr 25 15:29:09 pwrk-02 tailscaled[2400]: netmap: suggested exit node: ()
Apr 25 16:51:29 pwrk-02 tailscaled[2400]: wgengine: Reconfig: configuring userspace WireGuard config (with 1/1 peers)
kus
- paistab wireguard viiteid
Võrguliides noarp point-to-point, nb! mtu on 1280 baiti
root@pwrk-02:~# ifconfig tailscale0
tailscale0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1280
inet 100.121.207.99 netmask 255.255.255.255 destination 100.121.207.99
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 3 bytes 254 (254.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2 bytes 168 (168.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Ruutinguks kasutatakse abistavat nn tabelit nr 52
root@pwrk-02:~# ip route show default via 192.168.111.189 dev enp6s18 proto static 192.168.111.0/24 dev enp6s18 proto kernel scope link src 192.168.111.198 root@pwrk-02:~# ip route show table 52 100.66.245.64 dev tailscale0 100.100.100.100 dev tailscale0
käimasoleva kohta info küsimine
root@pwrk-02:~# tailscale netcheck 2026/04/25 17:10:02 portmap: monitor: gateway and self IP changed: gw=192.168.111.189 self=192.168.111.198 Report: * Time: 2026-04-25T17:10:02.654619377Z * UDP: true * IPv4: yes, 80.235.106.155:57953 * IPv6: no, unavailable in OS * MappingVariesByDestIP: false * PortMapping: * Nearest DERP: Helsinki * DERP latency: - hel: 12.5ms (Helsinki) - waw: 33.5ms (Warsaw) - ams: 41.7ms (Amsterdam) - fra: 42.1ms (Frankfurt) - par: 49.7ms (Paris) - lhr: 49.8ms (London) - nue: 50.8ms (Nuremberg) - mad: 74.3ms (Madrid) - tor: 115.6ms (Toronto) - nyc: 118.7ms (New York City) - ord: 127.3ms (Chicago) - dbi: 134.5ms (Dubai) - iad: 135.4ms (Ashburn) - den: 147.3ms (Denver) - mia: 156.1ms (Miami) - dfw: 167.5ms (Dallas) - blr: 177.3ms (Bengaluru) - sea: 184.2ms (Seattle) - nai: 186.8ms (Nairobi) - sfo: 187.8ms (San Francisco) - lax: 189ms (Los Angeles) - jnb: 210.3ms (Johannesburg) - hnl: 235ms (Honolulu) - sin: (Singapore) - syd: (Sydney) - tok: (Tokyo) - sao: (São Paulo) - hkg: (Hong Kong)
- UDP: true - udp port punching on kasutusel
protsess töötab global namespace'ides
root@pwrk-02:~# ps aux | grep scale | grep -v grep
root 2400 0.0 0.4 1354240 40380 ? Ssl 15:28 0:02 /usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=41641
root@pwrk-02:~# lsns -p 2400
NS TYPE NPROCS PID USER COMMAND
4026531834 time 156 1 root /sbin/init
4026531835 cgroup 156 1 root /sbin/init
4026531836 pid 156 1 root /sbin/init
4026531837 user 156 1 root /sbin/init
4026531838 uts 151 1 root /sbin/init
4026531839 ipc 156 1 root /sbin/init
4026531840 net 156 1 root /sbin/init
4026531841 mnt 148 1 root /sbin/init
töötamise ajal paketifilter
root@pwrk-02:~# iptables-save # Generated by iptables-save v1.8.10 (nf_tables) on Sat Apr 25 18:32:43 2026 *mangle :PREROUTING ACCEPT [41408:3647218] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [41249:3854567] :POSTROUTING ACCEPT [0:0] -A PREROUTING -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xff0000 --ctmask 0xff0000 -A OUTPUT -m conntrack --ctstate NEW -m mark ! --mark 0x0/0xff0000 -j CONNMARK --save-mark --nfmask 0xff0000 --ctmask 0xff0000 COMMIT # Completed on Sat Apr 25 18:32:43 2026 # Generated by iptables-save v1.8.10 (nf_tables) on Sat Apr 25 18:32:43 2026 *filter :INPUT ACCEPT [41137:3630063] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :ts-forward - [0:0] :ts-input - [0:0] -A INPUT -j ts-input -A FORWARD -j ts-forward -A ts-forward -i tailscale0 -j MARK --set-xmark 0x40000/0xff0000 -A ts-forward -m mark --mark 0x40000/0xff0000 -j ACCEPT -A ts-forward -s 100.64.0.0/10 -o tailscale0 -j DROP -A ts-forward -o tailscale0 -j ACCEPT -A ts-input -s 100.121.207.99/32 -i lo -j ACCEPT -A ts-input -s 100.115.92.0/23 ! -i tailscale0 -j RETURN -A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP -A ts-input -i tailscale0 -j ACCEPT -A ts-input -p udp -m udp --dport 41641 -j ACCEPT COMMIT # Completed on Sat Apr 25 18:32:43 2026 # Generated by iptables-save v1.8.10 (nf_tables) on Sat Apr 25 18:32:43 2026 *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [368:32320] :ts-postrouting - [0:0] -A POSTROUTING -j ts-postrouting -A ts-postrouting -m mark --mark 0x40000/0xff0000 -j MASQUERADE COMMIT # Completed on Sat Apr 25 18:32:43 2026
töötamise ajal bpf/btf
root@pwrk-02:~# bpftool prog show id 2 2: tracing name hid_tail_call tag 7cc47bbf07148bfe gpl loaded_at 2026-04-25T13:40:51+0000 uid 0 xlated 56B jited 136B memlock 4096B map_ids 2 btf_id 5 root@pwrk-02:~# bpftool prog dump xlated id 2 int hid_tail_call(unsigned long long * ctx): ; int BPF_PROG(hid_tail_call, struct hid_bpf_ctx *hctx) 0: (79) r2 = *(u64 *)(r1 +0) ; bpf_tail_call(ctx, &hid_jmp_table, hctx->index); 1: (61) r3 = *(u32 *)(r2 +0) 2: (18) r2 = map[id:2] 4: (85) call bpf_tail_call#12 ; int BPF_PROG(hid_tail_call, struct hid_bpf_ctx *hctx) 5: (b7) r0 = 0 6: (95) exit root@pwrk-02:~#