Управление буфером обмена через SSH: аналитический обзор¶
Введение¶
При работе на удалённых серверах через SSH часто возникает задача: скопировать данные из удалённой сессии в буфер обмена локальной машины. На macOS локальная команда pbcopy решает эту задачу, но при выполнении на удалённом сервере данные попадают в буфер удалённой машины (если он вообще существует), а не локальной. Обзор рассматривает все доступные подходы к решению этой задачи — от встроенных механизмов терминалов до специализированных утилит.
OSC 52 — Escape-последовательность для буфера обмена¶
Принцип работы¶
OSC 52 (Operating System Command 52) — ANSI escape-последовательность, которая инструктирует терминальный эмулятор записать данные в системный буфер обмена 1. Формат последовательности:
Терминал перехватывает эту последовательность, декодирует base64-содержимое и помещает его в системный clipboard. Ключевое свойство — последовательность работает независимо от того, где она была сгенерирована: локально, через SSH или через цепочку SSH → tmux → Neovim 2.
"OSC 52 is location-independent — the terminal doesn't care where the sequence originates, even from a remote SSH session" 1.
Минимальный скрипт¶
На удалённом сервере достаточно создать скрипт-замену pbcopy:
#!/bin/bash
# ~/bin/pbcopy — копирование в локальный буфер через OSC 52
printf "\033]52;c;%s\007" "$(base64 | tr -d '\n')"
Использование: echo "текст" | pbcopy или cat file.txt | pbcopy 3.
Ограничения¶
Максимальный объём передаваемых данных — приблизительно 74 994 байта (~75 КБ) из-за ограничений длины escape-последовательности (100 000 байт с учётом base64-оверхеда) 1.
Поддержка терминалами¶
| Терминал | Поддержка | Примечания |
|---|---|---|
| iTerm2 | Да | Требует включения в Preferences → General → "Allow clipboard access" 4 |
| Alacritty | Да | Работает из коробки 1 |
| kitty | Да | Рекомендуется clipboard_control no-append в конфиге из-за бага с append 1 |
| WezTerm | Да | Работает из коробки 1 |
| Windows Terminal | Частично | Только копирование, вставка заблокирована 5 |
| xterm | Да | Отключено по умолчанию; требует XTerm.vt100.allowWindowOps: true в .Xresources 1 |
| foot | Да | Работает из коробки 1 |
| GNOME Terminal | Нет | Не поддерживает OSC 52 1 |
| VTE-терминалы (XFCE Terminal, Terminator) | Нет | Не поддерживают 1 |
Конфигурация tmux¶
tmux требует явного включения поддержки OSC 52. Конфигурация в ~/.tmux.conf:
# Включить поддержку clipboard
set -s set-clipboard on
# Для tmux 3.3+ — разрешить passthrough escape-последовательностей
set -g allow-passthrough on
# Указать terminal features для конкретных эмуляторов
set -as terminal-features "xterm*:clipboard"
set -as terminal-features "alacritty:clipboard"
set -as terminal-features "kitty:clipboard"
set -as terminal-features "wezterm:clipboard"
Параметр set-clipboard имеет три значения 6:
- on — tmux устанавливает буфер обмена и разрешает приложениям внутри tmux изменять его
- external — tmux устанавливает буфер, но запрещает приложениям модификацию (по умолчанию с tmux 2.6+)
- off — полностью отключено
Параметр allow-passthrough (tmux 3.3a+) критически важен для nested-сценариев: SSH → tmux → приложение 7.
Проверка корректности настройки:
Интеграция с Neovim¶
Neovim имеет встроенную поддержку OSC 52 и автоматически включает её при обнаружении переменной $SSH_TTY 8. Явная конфигурация в init.lua:
vim.g.clipboard = {
name = 'OSC 52',
copy = {
['+'] = require('vim.ui.clipboard.osc52').copy('+'),
['*'] = require('vim.ui.clipboard.osc52').copy('*'),
},
paste = {
['+'] = require('vim.ui.clipboard.osc52').paste('+'),
['*'] = require('vim.ui.clipboard.osc52').paste('*'),
},
}
Для традиционного Vim существует плагин vim-osc52 9 или альтернативный подход — скрипт-обёртка (описанный выше), указанный как clipboard provider.
Интеграция с GNU Screen¶
GNU Screen требует оборачивания OSC 52 в DCS (Device Control String) последовательности 10:
- Без screen:
printf "\033]52;c;...\a" - Один уровень screen: оборачивание в
\033P...\033\\ - Вложенный screen: двойное экранирование с учётом
$SHELL_LEVEL
Безопасность OSC 52¶
OSC 52 спроектирован как write-only по умолчанию — приложения могут записывать в буфер обмена, но не читать из него 5. Это предотвращает кражу содержимого clipboard вредоносными скриптами.
Однако при set-clipboard on в tmux любое приложение внутри сессии может модифицировать системный буфер обмена. Рекомендуется включать только при необходимости 5.
SSH Reverse Tunnel + netcat¶
Принцип работы¶
На локальной машине запускается слушающий процесс, который принимает данные по TCP и передаёт их в pbcopy. SSH reverse forwarding пробрасывает порт с удалённой машины на локальную 11.
Настройка¶
Локальная машина (macOS):
SSH подключение:
Постоянная конфигурация (~/.ssh/config):
На удалённой машине:
Автоматизация через LaunchAgent (macOS)¶
Для постоянной работы можно создать LaunchAgent 12:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.local.pbcopy</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>while true; do nc -l 127.0.0.1 2224 | pbcopy; done</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Скрипт-обёртка для прозрачного использования¶
#!/bin/bash
# ~/.bin/pbcopy — прозрачная обёртка
if [ -z "$SSH_CONNECTION" ]; then
/usr/bin/pbcopy "$@"
else
nc localhost 2224
fi
Оценка¶
- Плюсы: минимальные зависимости, работает везде с netcat и SSH
- Минусы: нет аутентификации на уровне туннеля, требует постоянный демон, однонаправленная работа (только копирование), каждая отправка данных закрывает соединение и требует перезапуска
nc -l
Clipper — демон для буфера обмена¶
Описание¶
Clipper — демон/launch agent, предоставляющий доступ к локальному буферу обмена для tmux и vim через TCP или Unix socket 13.
Установка¶
# macOS
brew install clipper
# Из исходников
git clone https://github.com/wincent/clipper.git
cd clipper && make install
Конфигурация¶
Clipper слушает на порту 8377 по умолчанию и передаёт данные в pbcopy (macOS) или xclip (Linux).
SSH forwarding (TCP):
SSH forwarding (Unix socket, OpenSSH 6.7+):
Интеграция с tmux¶
# TCP
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377"
# Unix socket
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc -U ~/.clipper.sock"
Оценка¶
- Плюсы: Unix socket безопаснее TCP, прозрачная интеграция с tmux и vim, поддерживается Homebrew
- Минусы: требует настройки на обеих машинах, однонаправленная работа
Lemonade — кроссплатформенная утилита¶
Описание¶
Lemonade — утилита для удалённого копирования, вставки и открытия URL в браузере через TCP 14. Написана на Go, поддерживает Windows, Linux, macOS.
Установка¶
Использование¶
Локальная машина (сервер):
Удалённая машина (клиент):
Конфигурация (~/.config/lemonade.toml)¶
Оценка¶
- Плюсы: двусторонняя работа (copy + paste), кроссплатформенность, возможность открывать URL в браузере
- Минусы: нет встроенного шифрования (рекомендуется SSH port forwarding), требует отдельный сервер-процесс
sshboard — безопасный вариант¶
Описание¶
sshboard использует SSH Unix domain socket forwarding для безопасного доступа к clipboard 15. Все данные передаются через зашифрованный SSH-туннель, сокеты приватны для конкретного пользователя.
Оценка¶
- Плюсы: шифрование через SSH, защита от других пользователей на shared-серверах, кроссплатформенность (Linux/FreeBSD/Windows WSL/macOS)
- Минусы: менее популярен, сложнее в настройке
X11 Forwarding с xclip/xsel¶
Принцип работы¶
SSH пробрасывает X11-протокол, позволяя удалённым приложениям взаимодействовать с локальным X-сервером, включая буфер обмена 16.
Настройка¶
Сервер (/etc/ssh/sshd_config):
Клиент:
На удалённой машине:
Безопасность X11 Forwarding¶
X11 forwarding создаёт значительные риски безопасности 17:
- X11 cookie даёт полный контроль над X-сервером — удалённое приложение может перехватывать ввод с клавиатуры, читать содержимое экрана, управлять другими окнами
- Компрометация удалённого сервера (включая root-доступ) позволяет получить X11-credentials и получить доступ к локальному дисплею
- Флаг
-X(untrusted) безопаснее-Y(trusted), но ограничивает функциональность
"X11 cookies grant complete control to anyone with access to them" 17.
Оценка¶
- Плюсы: двусторонняя работа, стандартный механизм SSH
- Минусы: серьёзные риски безопасности, требует X11 на обеих машинах, медленнее альтернатив, не работает на headless-серверах, на macOS требует XQuartz
Сравнительная таблица¶
| Подход | Двунаправленный | Шифрование | Сложность настройки | Зависимости на удалённой машине | Безопасность |
|---|---|---|---|---|---|
| OSC 52 | Нет (write-only) | Через SSH | Минимальная | Нет (только скрипт) | Высокая |
| SSH Reverse Tunnel | Нет | Нет (в рамках туннеля — да) | Низкая | netcat | Средняя |
| Clipper | Нет | Да (Unix socket) | Средняя | netcat или socat | Высокая |
| Lemonade | Да | Нет (нужен SSH tunnel) | Средняя | lemonade binary | Средняя |
| sshboard | Да | Да (SSH socket) | Высокая | sshboard binary | Высокая |
| X11 Forwarding | Да | Да | Средняя | xclip + X11 libs | Низкая |
Дискуссионные вопросы и противоречия¶
OSC 52 vs специализированные утилиты¶
OSC 52 не требует установки дополнительного ПО на удалённой машине, но ограничен объёмом передаваемых данных (~75 КБ) и зависит от поддержки терминалом. Специализированные утилиты (Clipper, Lemonade) снимают ограничение на размер, но требуют установки бинарников на обеих машинах.
Безопасность: OSC 52 vs X11 Forwarding¶
По security-модели OSC 52 значительно превосходит X11 Forwarding 5 17. OSC 52 ограничен записью в буфер обмена, тогда как X11 даёт полный доступ к дисплею. Тем не менее, OSC 52 при включённом set-clipboard on в tmux позволяет любому процессу в сессии модифицировать clipboard без уведомления пользователя.
Проблема paste (обратное направление)¶
Большинство подходов решают задачу копирования из удалённой машины в локальный буфер, но обратное направление (paste из локального буфера на удалённую машину) поддерживается только X11 Forwarding и Lemonade. В tmux отмечается асимметрия: текст, скопированный в Neovim внутри tmux, доступен локально, но внешне скопированный текст нельзя вставить в Neovim через clipboard provider 7.
Рекомендации¶
Оптимальный подход для macOS + SSH¶
OSC 52 — рекомендуемый подход для большинства сценариев:
- Не требует установки ПО на удалённом сервере
- Работает через любое количество прокси-слоёв (SSH → tmux → Neovim)
- Безопасен (write-only модель)
- Поддерживается основными терминалами macOS (iTerm2, Alacritty, kitty, WezTerm)
Минимальная настройка:
- Включить OSC 52 в терминале (iTerm2: Preferences → General → Selection → "Applications in terminal may access clipboard")
- Создать скрипт
~/bin/pbcopyна удалённой машине (5 строк) - Если используется tmux — добавить
set -s set-clipboard onиset -g allow-passthrough on - Neovim настроится автоматически через
$SSH_TTY
Для объёмных данных (>75 КБ): SSH Reverse Tunnel или Clipper.
Источники¶
Quality Metrics¶
- Источники найдены: 17
- Источники процитированы: 17
- Типы источников: official: 2, technical blog: 12, GitHub: 3
- Покрытие цитатами: ~95%
- Подвопросы исследованы: 5 (OSC 52, SSH tunnel, утилиты, tmux/vim, безопасность)
-
Copying to clipboard from tmux and Vim using OSC 52 — The Terminal Programmer ↩↩↩↩↩↩↩↩↩↩
-
Copy from tmux/nvim to clipboard over SSH — Milad Alizadeh ↩
-
Copying to your clipboard over SSH in vim with OSC52 — Julia Evans ↩
-
Copying to the iOS Clipboard Over SSH with Control Codes — Andrew Brookins ↩
-
Forward your clipboard via SSH reverse tunnels — GitHub Gist ↩