Перейти к содержанию

Управление буфером обмена через SSH: аналитический обзор

Введение

При работе на удалённых серверах через SSH часто возникает задача: скопировать данные из удалённой сессии в буфер обмена локальной машины. На macOS локальная команда pbcopy решает эту задачу, но при выполнении на удалённом сервере данные попадают в буфер удалённой машины (если он вообще существует), а не локальной. Обзор рассматривает все доступные подходы к решению этой задачи — от встроенных механизмов терминалов до специализированных утилит.

OSC 52 — Escape-последовательность для буфера обмена

Принцип работы

OSC 52 (Operating System Command 52) — ANSI escape-последовательность, которая инструктирует терминальный эмулятор записать данные в системный буфер обмена 1. Формат последовательности:

ESC ] 52 ; c ; <base64-данные> BEL

Терминал перехватывает эту последовательность, декодирует 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.

Проверка корректности настройки:

tmux info | grep Ms:

Интеграция с 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):

# Запустить демон-слушатель
while true; do nc -l 5556 | pbcopy; done

SSH подключение:

ssh -R 5556:localhost:5556 user@remote-server

Постоянная конфигурация (~/.ssh/config):

Host remote-server
    RemoteForward 5556 localhost:5556

На удалённой машине:

cat file.txt | nc -q0 localhost 5556

Автоматизация через 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 -R localhost:8377:localhost:8377 user@host

SSH forwarding (Unix socket, OpenSSH 6.7+):

ssh -R /home/user/.clipper.sock:/Users/user/.clipper.sock host

Интеграция с 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.

Установка

go install github.com/lemonade-command/lemonade@latest

Использование

Локальная машина (сервер):

lemonade server

Удалённая машина (клиент):

cat file.txt | lemonade copy
lemonade paste
lemonade open 'https://example.com'

Конфигурация (~/.config/lemonade.toml)

port = 2489
host = "localhost"
allow = ["192.168.0.0/16"]
line-ending = "lf"

Оценка

  • Плюсы: двусторонняя работа (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):

X11Forwarding yes

Клиент:

ssh -X user@remote-server

На удалённой машине:

echo "текст" | xclip -selection clipboard
xclip -o -selection clipboard  # вставка

Безопасность 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 — рекомендуемый подход для большинства сценариев:

  1. Не требует установки ПО на удалённом сервере
  2. Работает через любое количество прокси-слоёв (SSH → tmux → Neovim)
  3. Безопасен (write-only модель)
  4. Поддерживается основными терминалами macOS (iTerm2, Alacritty, kitty, WezTerm)

Минимальная настройка:

  1. Включить OSC 52 в терминале (iTerm2: Preferences → General → Selection → "Applications in terminal may access clipboard")
  2. Создать скрипт ~/bin/pbcopy на удалённой машине (5 строк)
  3. Если используется tmux — добавить set -s set-clipboard on и set -g allow-passthrough on
  4. 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, безопасность)