Claude Code z telefonu przez SSH i tmux
Claude Code działa na VPS w sesji tmux, a telefon jest tylko terminalem. Skonfigurowano klucze SSH, mosh, tmux attach oraz klawiaturę mobilną.
Claude Code z telefonu: jak to faktycznie działa
Claude Code z telefonu nie jest aplikacją mobilną. Claude Code działa na VPS (wirtualnym serwerze prywatnym), w otwartej sesji tmux. Telefon otwiera połączenie SSH (secure shell) z tą sesją na czas jej wyświetlania. Po zamknięciu aplikacji agent nadal działa, ponieważ proces nigdy nie działał na telefonie.
Na tym polega cała konstrukcja. Mobilny system operacyjny zawiesza aplikację kilka sekund po przełączeniu się do innej aplikacji. Dlatego każde długotrwałe zadanie uruchomione na telefonie zostaje zatrzymane. Telefon otrzymuje również nowy adres sieciowy za każdym razem, gdy następuje przejście z wifi na transmisję danych. Oba problemy znikają, gdy proces działa na serwerze, a telefon wyświetla tylko ekran.
Na serwerze potrzebne są cztery elementy: tmux do utrzymywania sesji, klucze SSH do logowania, mosh do obsługi zmian sieci oraz sam Claude Code. Po stronie telefonu wystarczy jedna aplikacja terminala z dostępnym wierszem klawiszy.
Co jest potrzebne na VPS
Do obsługi SSH i tmux wystarczy niewielki serwer Ubuntu 24.04. Claude Code wymaga więcej zasobów. Oficjalne wymagania z lipca 2026 to Ubuntu 20.04 lub nowszy system na procesorze x64 albo ARM64 oraz co najmniej 4 GB pamięci RAM. Na planie z 1 GB instalacja kończy się powodzeniem, ale podczas obciążenia proces zostaje zakończony przez kernel. Claude Code wymaga również płatnego konta Claude (Pro, Max, Team lub Enterprise) albo konta Console z dostępem do API, ponieważ bezpłatny plan Claude.ai go nie obejmuje.
Skonfiguruj serwer jako zwykły użytkownik z uprawnieniami sudo, a nie jako root. Jeśli serwer jest nowy, najpierw wykonaj czynności opisane w pierwszych dziesięciu minutach na nowym VPS, ponieważ zmiany SSH opisane w dalszej części tego poradnika łatwiej wprowadzić, gdy użytkownik i zapora sieciowa już istnieją.
sudo apt update && sudo apt install -y tmux mosh
curl -fsSL https://claude.ai/install.sh | bash
claude --versionInstalator umieszcza plik binarny w ~/.local/bin/claude, a polecenie claude --version wyświetla wiersz podobny do 2.1.211 (Claude Code). Jeśli zostanie wyświetlone command not found, oznacza to, że ten katalog nie znajduje się jeszcze w zmiennej PATH: wyloguj się, zaloguj ponownie, a następnie sprawdź konfigurację za pomocą command -v claude. Polecenie claude doctor wyświetla diagnostykę instalacji i ustawień bez uruchamiania sesji.
Zaloguj się teraz raz z laptopa, zanim zaczniesz korzystać z telefonu. Uruchom claude w katalogu projektu i postępuj zgodnie z instrukcjami logowania. Procedura wymaga otwarcia adresu URL w przeglądarce i wprowadzenia kodu z powrotem w terminalu. Przełączanie między dwiema aplikacjami na ekranie telefonu jest w tym celu powolne. Wykonaj tę czynność raz na fizycznej klawiaturze, a dane uwierzytelniające pozostaną na serwerze.
Uruchamianie Claude Code w tmux, aby zerwane połączenie nie mogło go zakończyć
tmux new -s claude
cd ~/projects/api
claudeOdłącz sesję za pomocą Ctrl-b, a następnie d. tmux wyświetli [detached (from session claude)] i zwróci powłokę. Można teraz zamknąć aplikację, utracić sygnał lub schować telefon do kieszeni. Panel będzie nadal działać.
tmux ls
tmux attach -t claudetmux ls wyświetla jeden wiersz dla każdej sesji, na przykład claude: 1 windows (created Thu Jul 30 09:14:02 2026). tmux attach -t claude przywraca dokładnie miejsce, w którym zakończono pracę, włącznie z niedokończoną edycją.
Dzieje się tak, ponieważ tmux uruchamia własny proces serwera, a powłoka i Claude Code są procesami potomnymi tego serwera, a nie sshd. Po zakończeniu połączenia SSH jądro wysyła sygnał rozłączenia, SIGHUP, do procesów dołączonych do tego połączenia. Serwer tmux nie należy do tej grupy. Bez tmux ta sama blokada ekranu, która zrywa połączenie, zatrzyma Claude Code w trakcie wywołania narzędzia. Uruchamianie Claude Code na VPS w tmux zawiera bardziej szczegółowe informacje o układzie sesji.
tmux należy uruchamiać na serwerze, nigdy na telefonie. Wpisanie tmux w już dołączonej sesji wyświetla sessions should be nested with care, unset $TMUX to force. Wymuszenie tej operacji powoduje konflikt dwóch klawiszy prefiksu.
Automatyczne dołączanie przy każdym logowaniu
Wpisywanie polecenia dołączania na klawiaturze dotykowej szybko staje się uciążliwe. Należy umieścić poniższy wpis na końcu ~/.profile na serwerze:
if command -v tmux >/dev/null 2>&1 && [ -z "$TMUX" ] && [ -t 1 ]; then
exec tmux new-session -A -s claude
finew-session -A -s claude dołącza do sesji o nazwie claude, jeśli taka sesja istnieje, a jeśli nie, tworzy ją. Jedno polecenie obsługuje więc oba przypadki. exec zastępuje powłokę logowania programem tmux, dlatego wyjście z tmux zamyka połączenie zamiast pozostawiać użytkownika w zwykłym znaku zachęty. Aby uzyskać zwykłą powłokę, należy pominąć ten plik: ssh you@server -t "bash --noprofile".
Należy umieścić ten wpis w ~/.profile, a nie w ~/.bashrc. ~/.bashrc jest również wykonywany dla sesji nieinteraktywnych, dlatego transfery plików przestają działać: scp i sftp odczytują nieoczekiwany wynik jako dane protokołu i kończą działanie z błędem Received message too long. ~/.profile jest wykonywany tylko dla powłok logowania, czyli takich, jakie wykorzystuje interaktywna sesja SSH.
~/.profile jest również miejscem, w którym Ubuntu dodaje ~/.local/bin do PATH. Jeśli claude działa bezpośrednio po zalogowaniu, ale powłoka uruchomiona wewnątrz tmux zgłasza command not found, przyczyną jest ta kolejność. Należy więc uruchamiać tmux z powłoki logowania, jak opisano powyżej, a nie ze skryptu pomijającego profil.
iOS: Termius lub Blink Shell
Obie aplikacje obsługują SSH i mosh oraz przechowują klucze w aplikacji. Różnica dotyczy interfejsu.
Blink Shell działa za pomocą poleceń. W jego wierszu poleceń można wpisać ssh you@server lub mosh you@server, korzystając z takiej samej składni jak w terminalu na komputerze. Ustawienia otwiera się poleceniem config, a w sekcji Keys można utworzyć parę kluczy.
Termius działa za pomocą formularzy. Należy wprowadzić dane hosta, a następnie w szczegółach hosta zmienić protokół z SSH na Mosh. Termius zawiera własną implementację mosh i obsługuje mosh 1.3.0 oraz nowsze wersje, dlatego na serwerze nadal musi być zainstalowany pakiet mosh.
W obu przypadkach klucz należy wygenerować w aplikacji. Nie należy kopiować istniejącego klucza prywatnego na telefon. Aplikacja wyświetla część publiczną klucza. Jest to pojedynczy wiersz, który należy dodać do pliku ~/.ssh/authorized_keys na serwerze. Sekcja Klucze SSH dla poszczególnych urządzeń i sposób ich unieważniania opisuje nazewnictwo oraz procedurę unieważniania klucza. Ma to większe znaczenie w przypadku telefonu niż laptopa.
Należy włączyć blokadę biometryczną lub kodem dostępu, zapewnianą przez aplikację terminala. Bez tej blokady odblokowany telefon zapewnia dostęp do powłoki na serwerze przez cały czas, gdy ekran pozostaje aktywny.
Android: Termux
pkg upgrade
pkg install openssh mosh
ssh-keygen -t ed25519 -C "pixel"
cat ~/.ssh/id_ed25519.pubTermux udostępnia pakiety OpenSSH i mosh we własnym repozytorium, dlatego ssh, ssh-keygen i mosh działają tak samo jak na komputerze stacjonarnym. Dodaj wyświetlony wiersz klucza publicznego do pliku ~/.ssh/authorized_keys na serwerze, a następnie połącz się za pomocą mosh you@server.
Klawiatura ekranowa systemu Android nie ma klawisza Esc ani Ctrl, a Claude Code wymaga obu. Termux może wyświetlać własny wiersz klawiszy. Dodaj jeden wiersz do ~/.termux/termux.properties:
extra-keys = [['ESC','|','/','HOME','UP','END','PGUP'],['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN']]Następnie uruchom termux-reload-settings. Wiersz pojawi się nad klawiaturą. To samo ponowne wczytanie wykryje również czcionkę TrueType o stałej szerokości znaków umieszczoną w ~/.termux/font.ttf.
System Android może zatrzymać Termux, gdy aplikacja działa w tle. W tym przypadku skutkuje to tylko koniecznością ponownego połączenia. Sesja i agent działają na serwerze.
Dlaczego terminal zawiesza się po opuszczeniu zasięgu Wi-Fi i co naprawia mosh?
Połączenie SSH jest połączeniem TCP (transmission control protocol), a połączenie TCP jest identyfikowane przez oba adresy i oba porty. Po opuszczeniu zasięgu Wi-Fi telefon otrzymuje nowy adres z sieci komórkowej, więc stare połączenie nie pasuje już do żadnego końca. Żadna strona tego nie sygnalizuje. Terminal przestaje odpowiadać do czasu, aż TCP zrezygnuje z połączenia, a następnie ssh wyświetla client_loop: send disconnect: Broken pipe. Aby natychmiast zakończyć zawieszoną sesję, naciśnij Enter, następnie ~, a potem ..
mosh (mobile shell) eliminuje ten tryb awarii. Jednorazowo używa SSH do zalogowania się i uruchomienia procesu mosh-server, odczytuje zwrócony przez serwer port UDP (user datagram protocol), a następnie zamyka połączenie SSH. Od tego momentu obie strony wymieniają datagramy UDP uwierzytelniane wspólnym kluczem sesji, dlatego sesja jest identyfikowana przez ten klucz, a nie przez adres. Nowy adres nie przerywa sesji. mosh wyświetla również wpisywane znaki lokalnie i odświeża ekran, gdy serwer zwróci inny stan. Dzięki temu pozostaje użyteczny przy wolnym połączeniu komórkowym.
mosh używa portu UDP z zakresu od 60000 do 61000, dlatego należy otworzyć ten zakres:
sudo ufw allow 60000:61000/udp
sudo ufw statusOtwieranie portów za pomocą ufw zawiera pozostałe informacje dotyczące zapory sieciowej. Jeśli dostawca udostępnia oddzielną zaporę sieciową w panelu administracyjnym, należy dodać tam ten sam zakres, ponieważ reguła ufw nie może wpływać na filtr znajdujący się przed serwerem.
Często występują dwa problemy z mosh. Logowanie kończy się powodzeniem, a następnie zawiesza się i wyświetla Nothing received from server on UDP port 60001.. Oznacza to, że zakres UDP jest blokowany gdzieś między telefonem a serwerem. Komunikat mosh-server not found oznacza, że pakiet nie jest zainstalowany na serwerze albo nie ma go w ścieżce logowania PATH. Należy go zainstalować albo wskazać go bezpośrednio za pomocą mosh --server=/usr/bin/mosh-server you@server.
mosh odmawia również działania, gdy lokalizacja logowania nie używa UTF-8, i wyświetla komunikat: mosh-server needs a UTF-8 native locale to run. Należy poprawić lokalizację na serwerze, a nie w telefonie.
locale
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8mosh nie obsługuje dwóch funkcji. Zgodnie z plikiem README mosh nie obsługuje przekazywania X ani nieinteraktywnych zastosowań SSH, w tym przekazywania portów. Dlatego do podglądu aplikacji internetowej, którą właśnie uruchomił Claude Code, nadal potrzebne jest zwykłe ssh -L 8080:127.0.0.1:8080 you@server. mosh synchronizuje również tylko widoczny ekran, więc nie ma własnej historii przewijania. To ograniczenie nie ma tutaj znaczenia, ponieważ historię przewijania przechowuje tmux: Ctrl-b, następnie [ włącza tryb kopiowania, przeciągnięcie lub klawisze strzałek przewijają zawartość, a q zamyka ten tryb.
Przygotowanie ekranu telefonu do pracy
Cztery wiersze w ~/.tmux.conf na serwerze wykonują większość pracy:
set -g mouse on
set -g status-position top
set -g default-terminal "tmux-256color"
set -g history-limit 20000mouse on zamienia przeciągnięcie palcem w przewijanie, a stuknięcie w wybór panelu lub okna. Zastępuje to większość klawiszy prefiksu, których wpisywanie na telefonie jest niewygodne. status-position top przenosi wiersz stanu tmux znad dolnej krawędzi, gdzie zasłaniają go klawiatura ekranowa i pasek sugestii. default-terminal jest istotne, ponieważ w przeciwnym razie tmux zgłasza Claude Code terminal screen, przez co kolory i znaki do rysowania ramek wyglądają gorzej, niż powinny. Jeśli tmux odmawia uruchomienia z missing or unsuitable terminal: tmux-256color, brakuje wpisu terminfo: sudo apt install ncurses-term.
Wystarczy poznać cztery klawisze, aby dalsza praca była wygodna.
Escprzerywa odpowiedź Claude i zachowuje wykonaną pracę. Jest to więc klawisz, do którego kciuk powinien mieć najłatwiejszy dostęp.Ctrl+Crównież przerywa uruchomioną operację. Przy bezczynnym znaku zachęty pierwsze naciśnięcie usuwa dane wejściowe, a drugie zamyka Claude Code. Jest to więc bardziej zdecydowane narzędzie.- Dwukrotne naciśnięcie
Escusuwa roboczą treść polecenia, a przy pustym znaku zachęty otwiera menu przewijania wstecz. - Aby wprowadzić polecenie wielowierszowe, wpisz
\, a następnie naciśnij Enter. Ta forma działa w każdym terminalu. Shift+Enter jest natywnie obsługiwane tylko przez niewielką grupę terminali desktopowych, do której klienci mobilni nie należą.
Należy unikać dzielenia ekranu na panele. Telefon ustawiony pionowo ma około 40 kolumn szerokości, więc podział pionowy pozostawia po 20 kolumn na panel, a każdy diff zawija się i staje się nieczytelny. Zamiast tego należy używać okien tmux: Ctrl-b c tworzy nowe okno, a Ctrl-b n przechodzi do następnego. Gdy trzeba dokładnie odczytać diff, należy obrócić telefon poziomo.
Długa sesja na małym ekranie jest przede wszystkim problemem związanym z kontekstem, dlatego przed próbą wykonania całodziennej pracy w pociągu warto przeczytać zarządzanie oknem kontekstu Claude Code.
Zabezpieczenie dostępu: tylko klucze, bez haseł
Telefon przechowuje teraz klucz do maszyny, która edytuje kod i wykonuje polecenia. Należy wyłączyć uwierzytelnianie za pomocą haseł. Plik typu drop-in jest bezpieczniejszy niż bezpośrednia edycja sshd_config, ponieważ plik sshd_config w Ubuntu dołącza /etc/ssh/sshd_config.d/*.conf na początku, a używana jest pierwsza znaleziona wartość danego ustawienia.
sudo tee /etc/ssh/sshd_config.d/99-phone.conf >/dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
EOF
sudo sshd -t && sudo systemctl reload sshsshd -t analizuje konfigurację i niczego nie wyświetla, gdy jest ona poprawna. Pominięcie tego kroku oznacza, że jedna literówka uniemożliwi sshd ponowne wczytanie konfiguracji. Należy pozostawić otwartą działającą sesję i przetestować dostęp z drugiego połączenia przed zamknięciem któregokolwiek z nich, ponieważ nieprawidłowy klucz spowoduje teraz Permission denied (publickey)., a po wyłączeniu haseł nie będzie mechanizmu awaryjnego. W takiej sytuacji można skorzystać z konsoli udostępnianej przez dostawcę.
Każde urządzenie powinno mieć własny klucz. Utrata telefonu będzie wtedy oznaczać usunięcie jednego wiersza z ~/.ssh/authorized_keys, a laptop nadal będzie działać. W przypadku jednego wspólnego klucza trzeba zmienić klucz na każdym posiadanym urządzeniu.
W przypadku przeniesienia SSH na inny port w Ubuntu 24.04 należy pamiętać, że nasłuch należy do ssh.socket, dlatego samodzielny wiersz Port niczego nie zmienia. Należy uruchomić sudo systemctl edit ssh.socket, wyczyścić wartość domyślną za pomocą pustego ListenStream=, a następnie ustawić port w kolejnym wierszu. Wzmacnianie zabezpieczeń SSH na VPS omawia ten temat oraz pozostałe elementy powierzchni ataku.
fail2ban dla SSH zapewnia niewielkie dodatkowe bezpieczeństwo po wyłączeniu haseł, ponieważ odgadnięte hasło w ogóle nie może zostać zaakceptowane. Zapewnia jednak cichsze dzienniki, dzięki czemu rzeczywista próba logowania jest łatwa do wykrycia.
Silniejszym rozwiązaniem jest wyłączenie SSH z publicznego internetu. Należy umieścić serwer za samodzielnie hostowaną siecią VPN WireGuard, uruchamiać tunel w telefonie na żądanie i skonfigurować dla sshd ListenAddress wyłącznie w tunelu. mosh działa przez tunel, ponieważ obie strony korzystają z UDP. Należy pamiętać, że tunel zwiększa narzut pakietów. Jeśli duże transfery zatrzymują się, należy zmniejszyć MTU (maksymalną jednostkę transmisji) w konfiguracji WireGuard telefonu.
Na koniec należy uwzględnić jeszcze jeden aspekt takiej pracy. Z telefonu zatwierdza się monity dotyczące uprawnień na ekranie, na którym jednocześnie widać tylko kilka wierszy różnic. Jest to powód, aby zachować mechanizmy ochronne, a nie je wyłączać. Bezpieczne uruchamianie Claude Code na VPS omawia ograniczenia użytkownika i katalogów, które warto skonfigurować, zanim głównym sposobem dostępu stanie się ekran dotykowy.
Gdy podczas ponownego dołączania występuje problem
tmux attach wyświetlający no server running on /tmp/tmux-1000/default oznacza, że serwer tmux nie działa. Prawie zawsze oznacza to ponowne uruchomienie komputera. Sprawdź to za pomocą uptime. Aktualizacje jądra z automatycznych aktualizacji zabezpieczeń ponownie uruchamiają system. Po ponownym uruchomieniu system nie ma sesji tmux, dlatego każde uruchomienie Claude Code należy traktować jako możliwe do wznowienia.
can't find session: claude oznacza inną sytuację. Serwer tmux działa, ale nie ma sesji o tej nazwie. tmux ls wyświetla istniejące sesje.
Jeśli po dołączeniu wyświetla się zwykły znak zachęty powłoki zamiast uruchomionego Claude Code, proces zakończył się bez zakończenia sesji. Sprawdź dmesg -T | tail i poszukaj wiersza takiego jak Out of memory: Killed process 4821 (claude). Taki komunikat pojawia się, gdy system ma mniej pamięci niż wymagane 4 GB i wykonywana jest duża edycja. Brak takiego wiersza oznacza, że Claude Code zakończył działanie samodzielnie. Przyczyna znajduje się w przewijanej zawartości powłoki powyżej znaku zachęty.
Jeśli okno po ponownym dołączeniu jest bardzo małe i pozostawia niewykorzystane miejsce, oznacza to, że dwóch klientów jest dołączonych z różnymi rozmiarami. tmux dopasowuje rozmiar okna do najmniejszego dołączonego klienta. Laptop nadal utrzymuje sesję o szerokości 200 kolumn, a telefon żąda szerokości 40 kolumn. Podczas dołączania odłącz pozostałych klientów: tmux attach -d -t claude.
FAQ
Czy można uruchomić Claude Code bezpośrednio na telefonie zamiast na VPS?
Nie. Obsługiwane platformy w lipcu 2026 to macOS, Windows, Ubuntu 20.04 lub nowszy, Debian 10 lub nowszy oraz Alpine 3.19 lub nowszy, z co najmniej 4 GB RAM. Android i iOS nie znajdują się na tej liście. Telefon także usypia aplikacje i stale zmienia adres sieciowy, czego długotrwałe uruchomienie agenta nie toleruje. Należy uruchomić program na serwerze i używać telefonu jako ekranu.
Czy sesja zostanie zachowana po zamknięciu aplikacji lub utracie sygnału?
Tak. Odpowiadają za to dwa niezależne mechanizmy. tmux utrzymuje proces działający na serwerze, więc połączenie może zostać zakończone bez przerwania procesu. mosh utrzymuje samo połączenie mimo zmiany adresu, dlatego przełączenie z wifi na transmisję komórkową nie wymaga nawet ponownego łączenia. W przypadku zwykłego SSH bez tmux zerwane połączenie wysyła SIGHUP, a Claude Code zatrzymuje się w trakcie zadania.
Dlaczego mosh łączy się, a następnie nic nie wyświetla?
Pomyślne logowanie, po którym następuje zawieszenie z komunikatem Nothing received from server on UDP port 60001., oznacza, że UDP 60000–61000 nie jest otwarty. Należy dodać ten zakres w ufw, a następnie dodać go także w zaporze sieciowej dostawcy, która w większości paneli jest oddzielnym mechanizmem kontroli. Jeśli mosh zamiast tego zgłasza, że nie znaleziono mosh-server, na serwerze brakuje pakietu: sudo apt install mosh.
Jak przerwać działanie Claude Code z klawiatury bez klawisza Esc?
Należy dodać wiersz klawiszy. Termux konfiguruje go za pomocą extra-keys w ~/.termux/termux.properties, a Termius i Blink mają wbudowany wiersz, który można edytować w ustawieniach. Esc przerywa trwającą odpowiedź i zachowuje wykonaną dotychczas pracę. Ctrl+C również przerywa działanie, ale dwukrotne naciśnięcie tego klawisza przy bezczynnym znaku zachęty kończy Claude Code, dlatego w pierwszej kolejności należy użyć Esc.
Czy otwarcie SSH na internet jest wystarczająco bezpieczne?
Po wyłączeniu uwierzytelniania za pomocą hasła jedynym poświadczeniem, które może zadziałać, jest klucz, który nigdy nie opuszcza urządzeń użytkownika. Jest to akceptowalne ryzyko w przypadku maszyny, którą można odtworzyć. Należy użyć osobnego klucza dla każdego urządzenia, aby utrata telefonu wymagała usunięcia tylko jednego wiersza z authorized_keys. Jeśli nie należy odpowiadać na połączenia przez publiczny port, serwer można umieścić za WireGuard i skonfigurować sshd do nasłuchiwania na adresie tunelu.