Принцип работы
SCP использует SSH для защищённого соединения и аутентификации. Передача данных происходит внутри зашифрованного SSH-канала.
Начиная с OpenSSH 9.0, scp по умолчанию использует протокол SFTP для непосредственной передачи файлов. Старый SCP-протокол всё ещё доступен и может быть принудительно включён ключом -O
Перед началом копирования между локальным компьютером и удалённым сервером устанавливается зашифрованное SSH-соединение. Для аутентификации можно использовать пароль или ключ SSH
- Установка SSH-соединения. scp (сам являясь тонкой оберткой) запускает стандартное SSH-подключение к удалённому хосту - тот же handshake, что при обычном
ssh: TCP-соединение, обмен ключами (key exchange), выбор шифра и MAC, аутентификация клиента (по ключу, паролю, agent forwarding и т.д.) - Запрос на удалённой стороне через тот же ssh-канал. Вместо интерактивной shell-сессии SSH-клиент просит сервер запустить то, что будет принимать или отдавать файл. Здесь протоколы расходятся, и это видно в
scp -v: по SFTP клиент пишетdebug1: Sending subsystem: sftp, то есть запрашивает подсистему sftp; с ключом-Oстрока другая -debug1: Sending command: scp -f /root/file, то есть на сервере запускается сам scp в режиме источника (-f), а при загрузке на сервер - в режиме приёмника (-t) - Передача данных идёт через тот же зашифрованный SSH-канал (тот самый TCP-поток), никакого отдельного порта для данных не открывается - в отличие от активного FTP, где данные и управление идут по разным соединениям
- Завершение - по окончании передачи закрывается ssh-сессия
Синтаксис
scp [опции] источник назначение
Удаленный сервер указывается в формате:
IP_или_DOMAIN:/path/to/file
Например:
- Скачать файл с сервера: scp root@192.168.1.29:/root/nginx-redis-chart-0.1.0.tgz /share/
- root@192.168.1.29 - пользователь и IP-адрес удаленного сервера
- /root/nginx-redis-chart-0.1.0.tgz - файл на сервере, который надо скопировать
- /share/ - локальная директория, в которую будет скопирован файл
- Загрузить файл на сервер: scp /home/user/file.txt root@192.168.1.29:/share/
- /home/user/file.txt - локальный файл, который надо скопировать
- root@192.168.1.29 - пользователь и IP-адрес удаленного сервера
- /share/ - директория на сервере, в которую будет скопирован файл
Нюансы
- SCP перезаписывает файл без предупреждения
- Пробел в пути на удалённой стороне ведёт себя по-разному в зависимости от протокола, и с переходом на SFTP правило упростилось. Замер на OpenSSH 10.0:
- по умолчанию (SFTP) хватает одного экранирования - кавычек для локального шелла:
scp "user@host:/path/with space/file.txt" ./копирует файл (обратный слеш внутри кавычек тоже принимается, но уже не обязателен) - с legacy-протоколом (
-O) путь всё ещё уходит удалённому шеллу, поэтому нужны и кавычки, и обратный слеш:scp -O "user@host:/path/with\ space/file.txt" ./. С одними кавычками scp ругается двумя ошибками сразу -/root/withиspace.txt: шелл на сервере разорвал путь по пробелу
- по умолчанию (SFTP) хватает одного экранирования - кавычек для локального шелла:
- Поведение wildcard (*, ? и т.д.) зависит от используемого протокола. В современных версиях OpenSSH scp по умолчанию использует SFTP. При использовании legacy SCP-протокола (-O) раскрытие wildcard выполняется удалённым shell, поэтому кавычки и экранирование имеют особое значение
- В отличие от rsync, при разрыве соединения на середине передачи большого файла scp начинает копирование с нуля. Нет флага для докачки
- Начиная с OpenSSH 9.0, scp по умолчанию использует SFTP-протокол вместо legacy SCP-протокола под капотом. Это меняет поведение в деталях - например, wildcard-раскрытие путей на сервере может работать иначе, и некоторые старые трюки (типа копирования через нестандартные shell-конструкции) перестают работать
- scp user1@host1:/file user2@host2:/path/
- При копировании между двумя удалёнными хостами данные по умолчанию проходят через локальную машину, с которой запущен scp. Не гонять их через себя можно только ключом
-R- тогда scp запускается на стороне источника, и источник сам должен попадать на приёмник без пароля
Ключи
-3
Копирование через промежуточный хост - машину, с которой запущена утилита SCP
Полезно, когда host1 и host2 не имеют прямого сетевого доступа друг к другу, но оба доступны с локальной машины
В современных версиях OpenSSH это поведение используется по умолчанию, так что ключ обычно указывать не нужно - он нужен, только если ты одновременно включаешь legacy-протокол ключом-O. Обратный режим --R
- scp -3 user1@host1:/path/file.txt user2@host2:/path/
-4
Принудительное использование протокола IPv4
Нужно, если DNS резолвит хост и в IPv4, и в IPv6, а IPv6-соединение до сервера не работает или работает нестабильно
- scp -4 file.txt user@domain:/tmp/
-6
Принудительное использование протокола IPv6
Нужно, если DNS резолвит хост и в IPv4, и в IPv6, а IPv4-соединение до сервера не работает или работает нестабильно
- scp -6 file.txt user@domain:/tmp/
-A
Разрешает проброс ssh-agent на удалённую систему. По умолчанию агент не пробрасывается
Нужен, когда с удалённого хоста надо аутентифицироваться дальше - например при копировании между двумя удалёнными хостами ключом-R. У удобства есть цена: проброшенный агент позволяет удалённой машине пользоваться твоими ключами, поэтому на недоверенных хостах его включать не стоит
- scp -A -R user1@host1:/file user2@host2:/path/
-B
Batch mode - отключает запрос пароля/passphrase, работает в неинтерактивном режиме. Если аутентификация не пройдёт автоматически (по ключу), scp просто завершится с ошибкой, а не будет ждать ввода
Используется в скриптах и cron-задачах, где никто не сидит рядом с терминалом, чтобы ввести пароль
- scp -B -i ~/.ssh/id_rsa file.txt user@host:/tmp/
-C
Включить сжатие данных (передаёт
-Cв ssh, тот же алгоритм compression, что и в обычном ssh)
Ускоряет передачу на медленных каналах для сжимаемых данных (текст, логи). Для уже сжатых файлов (архивы, видео, изображения) эффекта почти нет, а CPU тратится зря
- scp -C bigfile.tar user@host:/backup/
-c [шифр]
Выбор шифра для соединения (передаётся в ssh как
-c)
Список доступных шифров можно посмотреть черезssh -Q cipher. Раньше это имело смысл для баланса скорость/безопасность на слабом железе, сейчас редко нужно - современные шифры типаchacha20-poly1305илиaes128-gcmбыстрые сами по себе
- scp -c aes128-gcm@openssh.com file.txt user@host:/tmp/
-F [конфиг-файл SSH]
Указывает альтернативный конфиг-файл ssh вместо
~/.ssh/config
Удобно, когда нужны разные наборы настроек (разные Jump-хосты, ключи, порты) для разных контекстов - например, рабочий и личный
- scp -F ~/.ssh/config_work file.txt user@host:/tmp/
-i [приватный SSH-ключ]
Путь к приватному ключу для аутентификации
Если не указать, ssh использует ключи по умолчанию (id_rsa, id_ed25519 и т.д.) из~/.ssh/. Нужен, когда ключ лежит в нестандартном месте или используется отдельный ключ под конкретный сервер
- scp -i ~/.ssh/id_ed25519 file.txt user@host:/tmp/
-J [адрес прокси-сервера]
Jump host - прокси-сервер, через который устанавливается ssh-туннель до конечного хоста (аналог
ProxyJump)
Классический сценарий: внутренний сервер недоступен из интернета напрямую, но доступен через bastion/jump-хост. В отличие от-3, здесь данные всё равно идут "сквозь" jump-хост как через туннель, а не копируются им как промежуточным участником
- scp -J jumpuser@bastion.example.com file.txt user@internal-host:/tmp/
-l [скорость в килобитах]
Ограничение скорости передачи в Kbit/s
Здесь 800 Kbit/s ≈ 100 KB/s. Полезно, чтобы не забить весь канал при копировании большого файла на продакшн-сервере, который сейчас обслуживает живой трафик
- scp -l 800 bigfile.iso user@host:/tmp/
-O
Принудительно использовать legacy SCP-протокол вместо SFTP
Нужен для серверов, где нет SFTP-подсистемы, а также ради совместимости с раскрытием wildcard и путей с~на старых серверах. Заодно это удобный маркер версии: в man-странице OpenSSH 8.9 у-Oнаписано «This mode is the default», а в 10.0 - уже «legacy SCP protocol». Обратный ключ-s(принудительный SFTP) в man 10.0 уже не описан: он просто не нужен, хотя всё ещё принимается
- scp -O user@host:'/var/log/*.log' ./
-o [SSH-параметр]
Передать произвольную опцию ssh в формате
key=value(как в ssh_config)
- scp -o StrictHostKeyChecking=no -o ConnectTimeout=5 file.txt user@host:/tmp/
-P [порт]
Порт SSH-сервера на удалённой машине (по умолчанию 22)
- scp -P 2222 file.txt user@host:/tmp/
-p
Сохраняет modification time, access time и права доступа (permissions) файла при копировании
Без-pфайл получит текущее время, а права возьмутся от источника, но будут урезаны umask получателя - это не то же самое, что «права по umask». Замер на OpenSSH 10.0: файл с правами741приезжает как741приumask 022и как700приumask 077; с-pв обоих случаях остаётся741, и сохраняется исходное время. Legacy-протокол (-O) ведёт себя так же
С-pсохранятся оригинальные метаданные - важно для бэкапов, деплоя скриптов, где права/время имеют значение
- scp -p script.sh user@host:/usr/local/bin/
-q
Quiet mode - отключает индикатор прогресса и большинство сообщений (кроме ошибок)
Удобно в скриптах, где прогресс-бар только мусорит вывод/логи
- scp -q file.txt user@host:/tmp/
-R
Копирование между двумя удалёнными хостами силами самого источника: scp запускается на host1, и host1 сам подключается к host2
В отличие от-3, данные не идут через локальную машину. Условие: scp на host1 должен попадать на host2 без пароля - ключом на месте или через проброшенный агент (-A)
- scp -R user1@host1:/file user2@host2:/path/
-r
Рекурсивное копирование директорий
Без-rscp откажется копировать директорию и выдаст ошибку. Копирует всё содержимое рекурсивно, включая поддиректории
- scp -r ./project user@host:/var/www/
-S [программа]
Программа для установки шифрованного соединения вместо стандартного
ssh(должна понимать те же флаги, что и ssh)
Редко используется на практике - разве что для отладки через обёртку-скрипт, которая логирует вызовы, или для использования альтернативной ssh-реализации
- scp -S /usr/bin/ssh file.txt user@host:/tmp/
-T
Отключает проверку совпадения имён файлов между тем, что запросил клиент, и тем, что вернул сервер (strict filename checking)
Нужен в редких случаях - например, когда путь на сервере содержит спецсимволы или wildcard-раскрытие на удалённой стороне даёт результат, который стандартная проверка ошибочно блокирует. Ослабляет защиту
- scp -T user@host:/some/weird/*.log ./
-v
Verbose - подробный вывод отладочной информации о процессе соединения и передачи (согласование ssh, аутентификация, шифр и т.д.)
Покажет, где именно происходит зависание или отказ (DNS, TCP, аутентификация, permission denied на удалённой стороне и т.п.)
- scp -v file.txt user@host:/tmp/
-X [SFTP-параметр]
Настройка поведения SFTP, появилась вместе с переходом на этот протокол. Параметров два:
nrequests- сколько запросов чтения/записи держать в полёте одновременно (по умолчанию 64), иbuffer- размер буфера одной операции (по умолчанию 32 КБ)
Это ручка для каналов с большой задержкой: на «длинной толстой трубе» передача упирается не в полосу, а в число запросов в полёте, и подниматьnrequestsсbufferимеет смысл там, где сжатие и выбор шифра уже ничего не дают
- scp -X nrequests=128 -X buffer=262144 bigfile.iso user@host:/tmp/
Тренажёр: собери команду
Ключи запоминаются не чтением, а набором. Ниже - задания прямо на этой
странице: условие словами, а ты пишешь команду. Проверяется не текст, а разбор -
ключи можно ставить в любом порядке, писать слитно (-rp) и цеплять значение к
ключу (-P2222). Задания каждый раз собираются заново с другими путями и
хостами, так что запомнить строку не выйдет.
Комментарии
Пока нет комментариев. Будь первым!
Оставить комментарий