SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Настройка Tailscale на VPS: tailnet и SSH без порта 22

Ставим Tailscale на чистый Ubuntu VPS из репозитория Tailscale, входим в tailnet, включаем MagicDNS и Tailscale SSH, затем закрываем публичный порт 22 в ufw, не потеряв доступ.

Что получится после настройки Tailscale на VPS

Настройка Tailscale на VPS занимает около десяти минут: вы ставите пакет из репозитория Tailscale, выполняете sudo tailscale up, открываете ссылку в браузере, и сервер появляется в вашей частной сети. После этого ноутбук и телефон видят VPS по имени вида vps.tail1234.ts.net, а публичный порт 22 можно закрыть в ufw. Все команды ниже написаны для чистого Ubuntu 24.04 и запускаются от обычного пользователя с sudo. Каждую из них вы выполняете сами на своём сервере.

Tailscale строит поверх WireGuard так называемый tailnet: частную сеть из ваших устройств, где каждое получает адрес вида 100.x.y.z и имя. Ключи WireGuard создаются на каждом устройстве и никогда его не покидают. Координационный сервер Tailscale только раздаёт публичные ключи и адреса, поэтому сам трафик между VPS и ноутбуком он не видит. Если вы ещё не разобрались, что такое Tailscale и чем он отличается от обычного VPN, начните с того текста, а сюда вернитесь за командами.

Что нужно заранее

  • VPS (виртуальный частный сервер) на Ubuntu 24.04 с доступом по SSH и правами sudo.
  • Аккаунт Tailscale. Он создаётся при первом входе через любого из поддерживаемых провайдеров идентификации (Google, Microsoft, GitHub, Apple или passkey). Один и тот же аккаунт вы используете на VPS, ноутбуке и телефоне.
  • Доступ к консоли провайдера (VNC или noVNC в панели управления). Она понадобится, если вы закроете порт 22 раньше, чем проверите путь через tailnet.

Бесплатного тарифа для одного человека и нескольких серверов достаточно. Точные цифры по пользователям и устройствам смотрите в разборе лимитов бесплатного плана Tailscale, здесь они не понадобятся.

Установка Tailscale на VPS из репозитория Tailscale

В архиве Ubuntu пакета tailscale нет. Команда sudo apt install tailscale на чистом сервере заканчивается ошибкой E: Unable to locate package tailscale, потому что apt ищет пакет только в подключённых источниках, а источник Tailscale вы ещё не добавили. Tailscale распространяет клиент через собственный репозиторий pkgs.tailscale.com, и ставить его нужно именно оттуда: там свежие версии, а обновления потом приходят обычным apt upgrade.

Подключить репозиторий можно двумя способами. Первый: официальный скрипт установки. Он определяет дистрибутив, добавляет ключ и список источников, ставит пакет и включает службу tailscaled.

curl -fsSL https://tailscale.com/install.sh | sh

Второй способ: те же шаги вручную. Он подходит, если вы не хотите запускать скрипт с сайта, не прочитав его, или хотите видеть, что именно попало в /etc/apt. Для Ubuntu 24.04 (кодовое имя noble) команды такие:

sudo apt update && sudo apt install -y curl
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt update && sudo apt install -y tailscale

Первая команда curl кладёт ключ подписи репозитория в /usr/share/keyrings/. Вторая добавляет файл источника, который ссылается на этот ключ через signed-by. Так apt проверяет этим ключом только пакеты Tailscale и не доверяет ему для всего остального. Дальше используется ручной вариант: на сервере, которым вы собираетесь управлять годами, лучше понимать каждый файл, который вы туда положили.

Проверьте результат:

tailscale version
systemctl is-enabled tailscaled
systemctl is-active tailscaled

tailscale version печатает номер версии, а обе команды systemctl отвечают enabled и active. Служба tailscaled включается автоматически при установке пакета, поэтому после перезагрузки сервер сам вернётся в tailnet. Если установка падает на другой ошибке, apt не принимает ключ или tailscaled не стартует, причину здесь искать не нужно: типовые ошибки с их точными сообщениями собраны в отдельной статье про ошибки установки Tailscale на Ubuntu.

Вход в tailnet: sudo tailscale up и ссылка для авторизации

sudo tailscale up

Команда не завершается сразу. Она печатает ссылку и ждёт:

To authenticate, visit:

	https://login.tailscale.com/a/1a2b3c4d5e6f

Откройте ссылку в браузере на ноутбуке. Ссылка одноразовая, а браузер на сервере не нужен: сам VPS обращается только к координационному серверу Tailscale по HTTPS. На странице входа выберите провайдера идентификации. При первом входе Tailscale создаст tailnet, а вы станете его администратором. Когда вход подтверждён, tailscale up в терминале завершается словом Success., и машина появляется на странице Machines в консоли администратора.

Доступность страницы входа и серверов Tailscale из конкретной страны и сети здесь не разбирается. Если ссылка не открывается на ноутбуке или tailscale up на сервере долго не печатает Success., проверьте это отдельно с двух сторон: у VPS и у ноутбука разные сети и разные условия.

Имя машины в tailnet берётся из hostname сервера. Если провайдер выдал имя вроде ubuntu-2gb-01 или vm123456, поменяйте его сразу после входа:

sudo tailscale set --hostname vps

Одна ошибка, которую делают почти все новички. tailscale up запоминает флаги, с которыми её вызвали. Если позже выполнить sudo tailscale up --ssh, а потом снова sudo tailscale up без флага, команда откажется работать и напишет Error: changing settings via 'tailscale up' requires mentioning all non-default flags. Причина в том, что up описывает полное желаемое состояние, и отсутствие флага она читает как просьбу его выключить. Поэтому все изменения после первого входа делайте через tailscale set: она меняет только то, что вы явно назвали.

Проверка: tailscale status, tailscale ip -4 и MagicDNS

tailscale status
tailscale ip -4

tailscale ip -4 печатает адрес VPS внутри tailnet, например 100.101.102.103. Адрес выдаётся из диапазона 100.64.0.0/10. Это диапазон CGNAT (carrier-grade NAT, NAT на стороне оператора связи), он не встречается в интернете и почти никогда в домашних сетях, поэтому не конфликтует с адресами роутера или офиса. Адрес закреплён за машиной, пока она есть в tailnet. tailscale status показывает все устройства сети: адрес, имя, владельца, ОС и состояние соединения. Пока в tailnet один VPS, в списке одна строка с самим сервером.

MagicDNS включён по умолчанию в новых tailnet. Он даёт каждой машине имя вида vps.tail1234.ts.net, где tail1234.ts.net это имя вашего tailnet (его видно на вкладке DNS в консоли). Внутри tailnet работает и короткое имя vps. Проверить настройку можно так:

tailscale dns status

В выводе есть блок про MagicDNS с суффиксом вашего tailnet и полным именем этой машины. Если MagicDNS в консоли выключен, устройства всё равно доступны по адресам 100.x.y.z, просто имена не разрешаются.

Подключаем ноутбук и телефон

Установите Tailscale на ноутбук (есть клиенты для всех настольных систем) и войдите тем же аккаунтом. На Linux это та же процедура, что выше. На macOS и Windows вход происходит через окно приложения. После входа проверьте связь с VPS с ноутбука:

tailscale ping vps
ping -c 3 vps

tailscale ping отвечает строкой вида pong from vps (100.101.102.103) via 203.0.113.10:41641 in 24ms. Слово via и публичный адрес с портом означают прямое соединение. Если вместо адреса стоит DERP(fra) или другой код региона, трафик идёт через ретранслятор Tailscale (DERP, Designated Encrypted Relay for Packets). Работать будет, но медленнее. Почему так случается и как добиться прямого соединения, разобрано в статье про медленный Tailscale и разницу между прямым и ретранслируемым соединением. Для VPS с публичным адресом самое частое решение простое: открыть входящий UDP 41641 в файрволе, это сделано в разделе про ufw ниже.

Телефон подключается так же: приложение Tailscale для Android или iOS, вход тем же аккаунтом, переключатель в положение «включено». После этого VPS виден в списке машин прямо в приложении, а любой SSH-клиент на телефоне (например, Termius или JuiceSSH) подключается к vps или к его адресу 100.x.y.z как к обычному хосту. Проброс портов и белый адрес для этого не нужны. По той же причине tailnet удобнее проброса портов на роутере и для доступа к домашним машинам.

Tailscale SSH: вход по личности, а не по ключу

Обычный ssh user@100.101.102.103 через tailnet уже работает: sshd слушает все интерфейсы, включая tailscale0. Аутентификация при этом остаётся вашей: ключи в ~/.ssh/authorized_keys и правила из sshd_config, всё как раньше.

Tailscale SSH делает шаг дальше. Когда он включён, tailscaled сам принимает соединения на порт 22, но только на адресе tailnet, и проверяет не ключ SSH, а вашу личность в Tailscale. Публичный sshd при этом не меняется и продолжает обслуживать порт 22 на внешнем адресе. Включается одной командой:

sudo tailscale set --ssh

Теперь с ноутбука:

ssh ubuntu@vps

Подставьте своего пользователя: на образах разных провайдеров это ubuntu, root или имя, созданное через cloud-init. Первый вход попросит дополнительное подтверждение: в терминале появится ссылка вида https://login.tailscale.com/a/..., откройте её в браузере и подтвердите. Это режим check из правила SSH по умолчанию: любой участник tailnet может входить на свои машины, но раз в 12 часов должен подтверждать сессию в браузере. Ключи SSH на сервере для этого не нужны, а отозвать доступ можно из консоли, не трогая authorized_keys.

Tailscale SSH не отменяет базовую гигиену sshd. Пока публичный порт 22 открыт, к нему применяются все обычные правила: отключить вход по паролю и вход под root, оставить только ключи. Следующий раздел убирает публичный порт совсем, но конфигурацию sshd стоит привести в порядок в любом случае: порт можно однажды снова открыть, и тогда sshd опять станет единственной защитой.

Закрываем публичный порт 22 в ufw

Это главный выигрыш от Tailscale на VPS: sshd перестаёт быть виден из интернета. Боты перестают перебирать пароли, journalctl -u ssh перестаёт заполняться строками Invalid user admin from ..., а снаружи остаётся один UDP-порт, который отвечает только на пакеты с правильным ключом WireGuard.

Порядок действий важен. Сначала проверьте путь через tailnet, потом закрывайте публичный порт. Держите текущую SSH-сессию по публичному адресу открытой, пока не убедитесь, что вторая сессия через vps работает. И заранее найдите в панели провайдера консоль (VNC): если вы всё же ошибётесь, войти получится только через неё.

Если ufw (uncomplicated firewall, стандартная обёртка над netfilter в Ubuntu) ещё не настроен, начните с основ ufw на VPS. Дальше предполагается, что он включён и в нём есть правило для SSH. Сначала разрешите весь входящий трафик с интерфейса tailscale0 и UDP 41641 для прямых соединений:

sudo ufw allow in on tailscale0
sudo ufw allow 41641/udp
sudo ufw status numbered

Правило allow in on tailscale0 безопасно, потому что на этот интерфейс попадают только пакеты, которые tailscaled уже расшифровал и сопоставил с известным узлом tailnet. Порт 41641/udp это порт WireGuard у tailscaled. Закрытый порт связь не ломает, Tailscale пройдёт через ретранслятор, но открытый даёт прямое соединение. Пакет без валидного ключа на этот порт ответа не получает, так что сканеры не видят его открытым.

Теперь из второго окна терминала подключитесь к серверу через tailnet:

ssh ubuntu@vps

Только когда эта сессия открыта и в ней работает sudo, удаляйте публичное правило. Найдите его номер в выводе ufw status numbered (строка с 22/tcp или OpenSSH) и удалите по номеру. ufw спросит подтверждение.

sudo ufw delete 2
sudo ufw status verbose

Подставьте свой номер. Если правил для SSH два (для IPv4 и для IPv6), удалите оба, начиная с большего номера, потому что после каждого удаления нумерация сдвигается. В ufw status verbose больше не должно быть строк с 22/tcp, а Default: deny (incoming) должен остаться. Текущая публичная сессия не оборвётся сразу, потому что ufw пропускает уже установленные соединения. Новая попытка ssh по публичному адресу должна зависнуть и закончиться Connection timed out, а вход через vps продолжает работать. Если вместо таймаута вы видите Connection refused, порт не закрыт, а sshd не слушает: разница между refused и timed out точно указывает, где искать.

Не забудьте про второй файрвол. У многих провайдеров есть сетевой файрвол в панели, отдельный от ufw. Если порт 22 открыт там, но закрыт в ufw, всё в порядке: ufw уже отбрасывает пакеты. Если хотите закрыть его и на уровне панели, действуйте тем же способом: сначала проверка через tailnet, потом правило.

Консоль администратора: три вещи, с которыми сталкиваются первыми

Консоль администратора по адресу login.tailscale.com/admin это место, где живёт всё, что не является командой на сервере. Для первого tailnet важны три пункта.

Срок действия ключа. По умолчанию ключ узла живёт 180 дней. Когда он истекает, узел выпадает из tailnet, и на сервере нужно выполнить sudo tailscale up --force-reauth и снова пройти вход в браузере. Для сервера, на который вы заходите только через tailnet, это опасно: истёкший ключ означает, что войти через tailnet вы уже не можете, а публичный порт закрыт. Поэтому для VPS срок действия отключают. На странице Machines откройте меню справа от машины и выберите Disable key expiry. Сделайте это сразу после закрытия порта 22. Если срок всё же истёк, --force-reauth запускайте из консоли провайдера, а не из сессии через tailnet: команда пересоздаёт соединение и обрывает сессию, из которой её запустили.

Тег для сервера. Пока машина принадлежит вашему аккаунту, она привязана к нему как к человеку. Тег (например, tag:server) делает узел самостоятельной сущностью, и у только что затегированной машины срок действия ключа отключён по умолчанию. Для первого tailnet это необязательно, но полезно, если серверов больше одного или tailnet не только ваш. Порядок такой: на вкладке Access controls объявите тег в секции tagOwners, одна строка вида "tag:server": ["autogroup:admin"], затем на странице Machines в меню машины выберите Edit tags и добавьте tag:server. То же самое из терминала: sudo tailscale login --advertise-tags=tag:server. После тегирования владелец-пользователь у машины исчезает. И одно следствие, о котором узнают на практике: правило Tailscale SSH по умолчанию разрешает вход только на свои машины (autogroup:self), а затегированная машина уже ничья. Чтобы ssh ubuntu@vps продолжил работать, добавьте в секцию ssh политики правило с "dst": ["tag:server"] и нужными пользователями, либо выключите Tailscale SSH (sudo tailscale set --ssh=false) и пользуйтесь обычным sshd через tailnet с ключами.

Удаление машины. Переустановили VPS или отдали его? Удалите узел в консоли: Machines, меню машины, Remove. Со стороны сервера сначала выполните sudo tailscale logout: команда завершает сессию и делает ключ узла недействительным, после чего пакет можно удалить обычным sudo apt remove tailscale. Удалять нужно обязательно: узел, оставленный в списке с живым ключом, для остальных ваших машин остаётся доверенным участником сети, и правило allow in on tailscale0 на них пропускает его трафик.

Что дальше

  • Второй сервер: соединить два VPS частной сетью это тот же tailscale up на второй машине, между ними сразу работают имена MagicDNS.
  • Доступ к сети за сервером или к домашней сети: subnet router на VPS объявляет чужие подсети в tailnet.
  • Выход в интернет с адреса VPS: exit node на VPS превращает сервер в точку выхода для ноутбука и телефона.
  • Понимание того, что происходит внутри: криптоключевая маршрутизация WireGuard объясняет, почему у каждого узла ровно один ключ и один набор адресов.

FAQ: частые вопросы

Почему sudo apt install tailscale пишет Unable to locate package?

Потому что в архиве Ubuntu пакета tailscale нет. Клиент распространяется через репозиторий pkgs.tailscale.com, который нужно подключить: скриптом curl -fsSL https://tailscale.com/install.sh | sh или вручную, добавив ключ в /usr/share/keyrings/ и файл источника /etc/apt/sources.list.d/tailscale.list. После sudo apt update пакет находится.

Как подключиться к VPS по имени, а не по адресу 100.x.y.z?

Имена даёт MagicDNS, он включён по умолчанию в новых tailnet. Полное имя выглядит как vps.tail1234.ts.net, где вторая часть это имя вашего tailnet с вкладки DNS в консоли. Внутри tailnet работает и короткое vps. Само имя машины берётся из hostname сервера, поменять его можно командой sudo tailscale set --hostname vps. Если имена не разрешаются, проверьте tailscale dns status на клиенте и переключатель MagicDNS в консоли.

Безопасно ли закрывать порт 22, если VPS доступен только через Tailscale?

Да, при двух условиях. Первое: путь через tailnet проверен из второго терминала до удаления правила ufw, а консоль провайдера остаётся запасным входом. Второе: у машины отключён срок действия ключа (Disable key expiry в консоли) или она затегирована. Иначе через 180 дней узел выпадет из tailnet, и вместе с ним пропадёт единственный путь к серверу.

Чем Tailscale SSH отличается от обычного SSH через tailnet?

Обычный SSH через tailnet это тот же sshd, к которому вы подключаетесь по адресу 100.x.y.z, и проверяет он ваши ключи из authorized_keys. Tailscale SSH включается командой sudo tailscale set --ssh: тогда tailscaled сам принимает порт 22 на адресе tailnet и проверяет вашу личность в Tailscale, а не ключ. Публичный sshd при этом не меняется. Доступ отзывается из консоли, а не правкой файлов на сервере.

Что делать, если tailscale up не печатает ссылку или зависает?

Чаще всего tailscaled не запущен или не смог создать сетевой интерфейс. Проверьте systemctl status tailscaled и journalctl -u tailscaled -n 50. На KVM-сервере устройство /dev/net/tun есть всегда, а в контейнерной виртуализации его может не быть, и тогда в журнале будет ошибка про TUN. Такие случаи с точными сообщениями об ошибках собраны в статье про ошибки установки Tailscale на Ubuntu.