Перейти к основному содержимому
05ФУНДАМЕНТ · ГЛАВА 05Файлы, пакеты, SSH

Файлы, пакеты, SSH

Прочитано 0%Квизы 0/7Тренажёры 0/5Уровень 1 · Новичок

Зачем это нужно

На чемпионате тебе выдадут чистую машину с Ubuntu — и почти сразу окажется, что «просто написать код» мало. Скрипт, который ты скачал или написал сам, откажется запускаться, пока ты не дашь ему право на выполнение. Нужной программы на машине не будет — её придётся установить, а для этого нужны права администратора, которых у обычного пользователя по умолчанию нет. Файл на сервере придётся поправить прямо в терминале, без графического редактора. А иногда и сама машина, с которой нужно работать, будет вообще не перед тобой: сервер стоит в другой комнате или в другом городе, и подключаться к нему нужно по сети.

Эта глава закрывает все эти ситуации по очереди: что такое права доступа (permission) и как их читать и менять командой chmod, что такое sudo и когда без него не обойтись, чем apt update отличается от apt upgrade и apt install, как поправить файл прямо в терминале редактором nano, и как командой ssh оказаться внутри чужого компьютера, не вставая со стула — сначала по паролю, а потом и вовсе без него, по ключу. В конце — scp, которая копирует файлы между машинами тем же защищённым каналом. Ничего не считаем очевидным: если символ есть в команде, у него есть причина там быть, и мы её найдём.

Права доступа: три буквы rwx

У каждого файла и каталога в Linux есть права доступа (permission) — отметка, кому и что с ним можно делать. Прав ровно три вида: читать (r, read), писать (w, write) и выполнять (x, execute). Для файла «выполнять» значит «запускать как программу»; для каталога — значит «заходить внутрь» (об этом коротко упоминалось в прошлой главе про ls -l, здесь разберём подробно).

Прав не одна тройка, а сразу три — они назначаются отдельно трём разным «кому»: владельцу файла (owner, тот, кто его создал), его группе (group, обычно и есть сам владелец плюс, возможно, коллеги) и всем остальным (other, все прочие пользователи системы). Ровно это и показывает ls -l. Создадим настоящий скрипт и посмотрим на него:

cat > hello.sh <<EOF
#!/bin/bash
echo Hello, chempionat!
EOF
ls -l hello.sh
-rw-r--r-- 1 student student 36 Aug 31 19:06 hello.sh

Строка -rw-r--r-- — это ровно десять символов, и в них зашифрован весь ответ на вопрос «кто и что может». Разберём каждый:

LINUX · ПРАВА ДОСТУПА rwxВладелецrwx6rw-Группаrwx4r--Остальныеrwx4r---rw-r--r--chmod 644 · те же три тройки, что и в калькуляторе прав ниже
Три тройки прав rwx: владелец, группа, остальные. У hello.sh — 644: владелец читает и пишет, группа и остальные только читают.
Нажми на часть выражения

Обрати внимание: нигде нет буквы x. Значит, файл нельзя запустить как программу — только прочитать или изменить. Проверим:

./hello.sh
bash: ./hello.sh: Permission denied

Перевод: «в доступе отказано». Linux не считает файл программой просто потому, что в нём лежит код на bash с правильным первым символом (#!) — он программа только тогда, когда у неё явно стоит бит x. Это осознанная защита: если бы любой скачанный текстовый файл можно было запустить одним движением, вредоносный скрипт под видом текстового документа выполнялся бы сам собой.

Разница между r и x у каталога — отдельная тонкость, которую стоит запомнить сразу: r на каталоге разрешает посмотреть список имён внутри (ls), а x — зайти внутрь и работать с содержимым конкретных файлов (cd, открыть файл по полному пути). Можно иметь r без x — тогда видно, что внутри лежит, но реально прочитать эти файлы по одному не получится; а можно иметь x без r — тогда список файлов ls не покажет, но если знаешь точное имя файла внутри, до него можно достучаться. На практике для своих каталогов почти всегда ставят либо оба бита разом, либо ни одного.

Отвечено вопросов: 0 из 4
Что означает первый символ - в строке прав -rw-r--r--?
Файл имеет права rw-r--r--. Кто из перечисленных может изменить его содержимое?
Почему ./hello.sh отвечает Permission denied, если внутри файла обычный работающий bash-скрипт?
Чем отличаются r и x на каталоге?
Отвечено верно: 0 из 4
Как это было
Права rwx старше интернета. Их придумали в UNIX — системе, которую Кен Томпсон и Деннис Ритчи начали писать в 1969 году в Bell Labs на почти списанном мини-компьютере PDP-7. Оттуда же родом ls, cd, mkdir и сама идея «всё есть файл». Чтобы переписать UNIX с ассемблера на что-то переносимое, Ритчи создал язык C — и обе эти вещи, UNIX и C, до сих пор фундамент почти всего, чем ты пользуешься.

chmod: меняем права

chmod (change mode) — единственная команда, которая меняет права доступа. У неё есть два независимых способа задать новые права: буквенный (символьный) и числовой. Оба означают одно и то же — просто записаны по-разному, и чемпионатные задания используют оба вперемешку, так что нужны оба.

Буквенная запись: кому, что, как

Нажми на часть выражения

Проверим на живом файле — запустим ту же команду, что уже видели во введении к главе, но теперь построчно, с проверкой после каждого шага:

chmod u+x hello.sh
ls -l hello.sh
-rwxr--r-- 1 student student 36 Aug 31 19:06 hello.sh

Смотри внимательно: было rw-r--r--, стало rwxr--r--x появился ровно в одной тройке, у владельца, потому что мы написали букву u. А вот если перед +/-/= не указать вообще никакой буквы u/g/o/a, chmod применит изменение сразу ко всем трём тройкам, как если бы ты написал a+x. Буква u в нашей команде как раз и ограничила добавление только владельцем — без неё, командой просто chmod +x hello.sh, x появился бы у всех троих. Проверим это прямо здесь на том же файле:

chmod 644 hello.sh
chmod +x hello.sh
ls -l hello.sh
-rwxr-xr-x 1 student student 36 Aug 31 19:06 hello.sh

Видишь разницу с предыдущим примером? С u+x группа и остальные права x не получили (rwxr--r--), а с голым +x — получили все трое (rwxr-xr-x). Разница между «с буквой-целью» и «без неё» — та самая деталь, которую легко упустить, читая чужую команду по диагонали.

Буквы можно комбинировать через запятую в одной команде — это задаёт сразу несколько троек за один вызов:

chmod 644 hello.sh
chmod u=rwx,g=rx,o=rx hello.sh
ls -l hello.sh
-rwxr-xr-x 1 student student 36 Aug 31 19:06 hello.sh

Здесь использован = вместо +: он не добавляет права к тому, что уже было, а задаёт их заново, целиком — «у владельца теперь ровно rwx, у группы ровно r-x, у остальных ровно r-x», независимо от того, что стояло раньше. А отнять право у всех сразу можно буквой a:

chmod a-x hello.sh
ls -l hello.sh
-rw-r--r-- 1 student student 36 Aug 31 19:06 hello.sh

Типичная ошибка — опечатка в имени файла или файл ещё не создан:

chmod: cannot access 'nope.sh': No such file or directory

Числовая запись и таблица 755/644

У числовой записи та же логика, просто без букв. Каждому из трёх прав присвоено число: r = 4, w = 2, x = 1. Права одной тройки складываются в одну цифру от 0 до 7 — а поскольку сумма любого набора из 1 без повторов всегда получается уникальной, по одной цифре однозначно восстанавливается, какие именно буквы в неё входили:

ЦифраИз чего сложенаБуквыЗначение
0---ничего нельзя
11--xтолько выполнение
22-w-только запись
32+1-wxзапись и выполнение
44r--только чтение
54+1r-xчтение и выполнение
64+2rw-чтение и запись
74+2+1rwxвсё сразу

Полная команда — три такие цифры подряд, по одной на каждую тройку: владелец, группа, остальные. Разберём ровно ту команду, которая чаще всего звучит на чемпионате, — сделать свежескачанный или свежесозданный скрипт исполняемым и одновременно ограничить права для чужих:

Нажми на часть выражения

Две связки чисел встречаются почти в каждом задании — 755 для программ и скриптов, 644 для обычных файлов вроде конфигов и текста. Вот их полная расшифровка бок о бок:

ПозицияКомуЦифра в 755ПраваЦифра в 644Права
1-явладелец (owner)7rwx6rw-
2-ягруппа (group)5r-x4r--
3-яостальные (other)5r-x4r--

755 = rwxr-xr-x — владелец может всё, включая запуск; группа и все остальные могут только читать и запускать, но не менять. Это стандартные права для исполняемого скрипта или программы. 644 = rw-r--r-- — владелец читает и пишет, все остальные только читают; это стандартные права для обычного файла без исполняемого кода — текста, конфига, разметки. Проверим оба на нашем файле:

chmod 644 hello.sh
ls -l hello.sh
chmod 755 hello.sh
ls -l hello.sh
-rw-r--r-- 1 student student 36 Aug 31 19:06 hello.sh
-rwxr-xr-x 1 student student 36 Aug 31 19:06 hello.sh

Ровно та же строка прав, что мы уже видели после u=rwx,g=rx,o=rx — буквенная и числовая запись всегда приводят к одному и тому же результату, просто это два разных языка для одной идеи.

Владелец6
пользователь, которому принадлежит файл
Группа4
участники группы файла
Остальные4
все прочие пользователи системы
rw-r--r--
Задание: щёлкни любую галочку и введи число (например, 640) — увидишь связь в обе стороны
Углубиться

Почему по умолчанию не 777. Когда ты создаёшь новый файл, у него уже есть какие-то права — их назначает не сама программа, а значение umask, которое вычитается из «максимума» 666 для файлов (rw без x — новые файлы никогда не создаются сразу исполняемыми, из соображений безопасности) и 777 для каталогов. Типичный umask — 022, поэтому свежесозданный файл почти всегда получается именно 644, а каталог — 755: и то, и другое мы видели выше как «стандартные» права не просто так.

chmod -R. У chmod, как у cp и rm, есть флаг -R (recursive, заглавная буква, не строчная, как у cp/rm) — применить изменение сразу ко всему каталогу вместе со всем содержимым: chmod -R 755 project/.

Дальше по теме:

  • man chmod — официальная man-страница: полное описание символьного и числового режимов, включая биты s и t, которых в этой главе не было
  • Академия Selectel — команда chmod в Linux — тот же материал другими словами, с дополнительными примерами вроде chmod 700
Отвечено вопросов: 0 из 4
Что сделает chmod u+x hello.sh с файлом, у которого права были rw-r--r--?
Чем chmod +x file отличается от chmod u+x file?
Как расшифровывается chmod 755?
Какая числовая запись у стандартного текстового файла без права на выполнение — владелец читает/пишет, все остальные только читают?
Отвечено верно: 0 из 4

sudo: временный суперпользователь

Установка программ, правка системных файлов, перезапуск служб — всё это меняет систему целиком, а не только файлы конкретного пользователя. Такие действия разрешены не всем: их может делать только суперпользователь (superuser) — учётная запись root, у которой прав ровно 777 на всё в системе без исключений. Работать под root постоянно опасно: одна опечатка в команде удаления способна снести систему целиком, без единого лишнего вопроса.

sudo (substitute user do — «выполнить от имени другого пользователя») — компромисс: обычный пользователь на секунду становится root только для одной конкретной команды, подтвердив это своим же паролем. Дальше всё возвращается как было. Разберём на живом примере — что будет, если попросить sudo пользователя, которому админ прав не выдавал:

SUDO · ВРЕМЕННОЕ ПОВЫШЕНИЕ ПРАВstudentобычный пользовательsudo + парольrootна одну командукоманда выполненаstudentснова обычныйroot — не отдельный вход, а секунда одолженных прав внутри той же сессии
sudo не открывает постоянный вход под root — он одалживает права ровно на одну команду и сразу забирает их обратно.
sudo whoami
[sudo] password for student: student is not in the sudoers file.

Перевод: «student отсутствует в файле sudoers». /etc/sudoers — список тех, кому вообще разрешено пользоваться sudo; не любой пользователь системы туда попадает автоматически. Добавим пользователя в группу sudo (это отдельная операция самого администратора машины, через usermod -aG sudo student) и повторим:

sudo whoami
[sudo] password for student: root

Пароль спрашивается собственный, пользователя student, а не пароль root — sudo проверяет, что ты действительно тот, за кого себя выдаёшь, а уже потом на секунду одалживает тебе права root. При вводе пароль не отображается на экране вообще, ни звёздочками, ни точками — это нормально, так задумано, чтобы длину пароля не подглядели через плечо. Команда whoami («кто я») после успешного sudo ответила root — доказательство, что права действительно временно повышены.

Если пароль введён неверно:

[sudo] password for student: Sorry, try again.

Перевод: «извините, попробуйте снова». После нескольких неверных попыток подряд sudo временно блокирует дальнейшие попытки — это защита от подбора пароля перебором.

Совет

Практическое правило: sudo ставят перед командой ровно тогда, когда она меняет что-то общесистемное — устанавливает программу, правит файл в /etc, перезапускает службу. Открыть свой собственный файл в nano или посмотреть свой каталог sudo не нужен вовсе.

apt: пакетный менеджер Ubuntu

В Ubuntu программы не скачивают со случайных сайтов по одной. Есть пакетный менеджер (package manager) — программа, которая сама находит нужный софт, скачивает его вместе со всем, что ему требуется для работы, и ставит одной командой. В Ubuntu он называется apt. Единица установки — пакет (package): архив с программой и служебной информацией о ней. Хранятся пакеты в репозитории (repository) — заранее проверенном каталоге софта в интернете, адрес которого уже прописан в системе.

APT · ОТКУДА БЕРУТСЯ ПАКЕТЫлокальный списоктвоя машинарепозиторий (сервер)apt updateтолько сверить списокapt install treeпакет целиком приезжает на диск
apt update сверяет локальный список пакетов с репозиторием, apt install тем же путём привозит на диск сам пакет.

У apt три разных команды, которые новички путают между собой чаще всего, — и путать их дорого: update, upgrade, install. Разберём по одной, на реальных выводах.

apt update — обновить список, не софт

sudo apt update
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:3 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Hit:4 http://archive.ubuntu.com/ubuntu noble-security InRelease
Reading package lists...

update не ставит и не обновляет ни одной программы — самая частая путаница новичков ровно здесь. Он идёт в репозиторий и обновляет только локальный список того, что там вообще есть и в каких версиях — как будто сверяет оглавление магазина перед покупкой, ничего не покупая. Строки Hit:N адрес InRelease значат «список для этого репозитория уже свежий, качать не нужно»; если список устарел, вместо Hit появится Get с реальной загрузкой. Именно поэтому apt update всегда идёт первым шагом — иначе install будет смотреть на устаревший список и может не найти свежую версию пакета или новый пакет вовсе.

Без sudo эта команда вообще не сработает — попробуем:

E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/

Перевод: «невозможно открыть файл блокировки: в доступе отказано (13)» и «невозможно заблокировать каталог». Список пакетов — общесистемный файл, писать в него может только root; apt использует lock-файл, чтобы два запуска apt не сталкивались одновременно, и обычный пользователь до этого файла попросту не дотягивается.

apt upgrade — обновить уже установленное

upgrade смотрит на список, который только что освежил update, сравнивает его с тем, что реально стоит на машине, и предлагает обновить всё устаревшее до новых версий. Сначала можно посмотреть список кандидатов, ничего не меняя:

apt list --upgradable
Listing...
bsdutils/noble-updates,noble-security 1:2.39.3-9ubuntu6.6 arm64 [upgradable from: 1:2.39.3-9ubuntu6.5]
diffutils/noble-updates,noble-security 1:3.10-1ubuntu0.1 arm64 [upgradable from: 1:3.10-1build1]
dpkg/noble-updates,noble-security 1.22.6ubuntu6.6 arm64 [upgradable from: 1.22.6ubuntu6.5]

А сама команда sudo apt upgrade покажет итог одной строкой и список пакетов, которые собирается тронуть:

The following packages will be upgraded:
diffutils dpkg gzip libc-bin libc6 sed tar zlib1g
21 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

update без upgrade — список свежий, а сами программы старые. upgrade без свежего update — команда сравнивает с устаревшим списком и может ничего не найти, хотя обновления давно вышли. На практике их почти всегда пишут парой: sudo apt update && sudo apt upgrade.

apt install — поставить новое

Нажми на часть выражения

Установим маленький и полезный пакет tree, который рисует дерево каталогов, — и увидим сразу важную тонкость поведения apt, которую легко упустить:

sudo apt install tree
The following NEW packages will be installed:
tree
0 upgraded, 1 newly installed, 0 to remove and 21 not upgraded.
Need to get 46.2 kB of archives.
After this operation, 160 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu noble-updates/universe tree 2.1.1-2ubuntu3.24.04.2 [46.2 kB]
Fetched 46.2 kB in 0s (121 kB/s)
Selecting previously unselected package tree.
Preparing to unpack .../tree_2.1.1-2ubuntu3.24.04.2_amd64.deb ...
Unpacking tree (2.1.1-2ubuntu3.24.04.2) ...
Setting up tree (2.1.1-2ubuntu3.24.04.2) ...

Здесь apt не спросил подтверждения — сразу перешёл к скачиванию и установке, хотя ты ничего не отвечал. А вот при удалении того же пакета команда останавливается и ждёт ответа:

sudo apt remove tree
The following packages will be REMOVED:
tree
0 upgraded, 0 newly installed, 1 to remove and 21 not upgraded.
After this operation, 160 kB disk space will be freed.
Do you want to continue? [Y/n]

Вывод: apt не всегда переспрашивает — для простой установки новых пакетов без удаления чего-либо он, как правило, действует сразу; а вот когда операция что-то убирает с диска, он останавливается и явно спрашивает [Y/n], ожидая Enter (по умолчанию Y, заглавная буква — вариант по умолчанию) или n для отмены. Правило простое: раз команда спрашивает подтверждения — значит, она собирается что-то удалить, стоит на секунду прочитать список выше, прежде чем нажимать Enter.

Проверить, что установка удалась, можно флагом --version, который есть почти у любой программы:

tree --version
tree v2.1.1 (c) 1996 - 2023 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro

Повторная установка уже стоящего пакета не ломается, а просто сообщает об этом:

tree is already the newest version (2.1.1-2ubuntu3.24.04.2).
0 upgraded, 0 newly installed, 0 to remove and 21 not upgraded.

А если ошибиться в названии пакета:

sudo apt install nonexistent-pkg-xyz123
E: Unable to locate package nonexistent-pkg-xyz123

Перевод: «не удалось найти пакет». Либо опечатка в имени, либо пакета с таким названием правда не существует в подключённых репозиториях.

Углубиться

apt — не единственный инструмент. Под капотом apt работает поверх более низкоуровневой утилиты dpkg, которая устанавливает и удаляет отдельные .deb-файлы, но сама не умеет искать пакеты в интернете и разрешать зависимости — этим и занимается apt поверх неё. Раньше вместо apt использовали apt-get/apt-cache — они существуют до сих пор и делают то же самое чуть более многословным синтаксисом; apt появился позже как удобная объединённая обёртка для человека, а не для скриптов (это явно написано в предупреждении apt does not have a stable CLI interface, которое иногда мелькает в выводе).

Куда пишется история установок. Всё, что apt/dpkg делали с системой, записывается в журнал /var/log/dpkg.log — можно посмотреть, что и когда ставилось, даже спустя месяцы.

Дальше по теме:

  • Ubuntu Server — Package management — официальная документация: update, upgrade, install, remove и альтернативные инструменты вроде aptitude
Отвечено вопросов: 0 из 4
Что реально меняет команда sudo apt update?
Почему sudo apt update без sudo завершается ошибкой Permission denied?
Пользователь student получил ответ student is not in the sudoers file. Что это значит?
При sudo apt install tree команда сразу начала ставить пакет без вопросов, а при sudo apt remove tree — остановилась и спросила Do you want to continue? [Y/n]. Почему по-разному?
Отвечено верно: 0 из 4

nano: редактор в терминале

Полноценную IDE nano не заменит, но поправить одну строку в конфиге на сервере, где нет вообще никакой графики, — ровно его работа. Открывается командой nano имя_файла; если файла с таким именем не было, nano создаст его при первом сохранении.

Внизу экрана nano всегда держит подсказку по горячим клавишам — вот как она выглядит в открытом файле на самом деле:

^G Help ^O Write Out ^W Where Is ^K Cut ^T Execute ^C Location M-U Undo
^X Exit ^R Read File ^\ Replace ^U Paste ^J Justify ^/ Go To Line M-E Redo

Значок ^ здесь значит Ctrl, а M- — Alt (Meta). Из всей этой панели новичку критично запомнить ровно две клавиши — сохранение и выход, — но обе неочевидны, поэтому разберём с реальным экраном.

КлавишиДействиеЧто произойдёт
Ctrl+OWrite Out — записатьсохранить файл на диск, не закрывая nano; спросит имя файла (можно просто нажать Enter, если менять не нужно)
Ctrl+XExit — выйтизакрыть nano; если были несохранённые изменения — сначала спросит, сохранить их или нет

В nano начиная с версии 4.0 (а значит, и в Ubuntu 22.04, и в 24.04) работает ещё и привычный Ctrl+S — он сохраняет молча, вообще ничего не переспрашивая. В нижней панели его нет, и на старых сборках он может не сработать, поэтому основной клавишей запоминаем всё-таки Ctrl+O.

Наберём текст и сохраним через Ctrl+O:

File Name to Write: notes.txt

nano переспрашивает имя файла для сохранения — по умолчанию то же, что было открыто; менять не нужно, просто нажми Enter. После этого внизу мелькнёт подтверждение:

[ Wrote 1 line ]

Если после этого сразу нажать Ctrl+X, не меняя больше ничего, nano закроется молча — сохранять уже нечего. А если после сохранения дописать ещё текст и снова нажать Ctrl+X, не сохранившись через Ctrl+O, экран покажет предупреждение:

Save modified buffer?
Y Yes
N No ^C Cancel

Три варианта: Y — сохранить и выйти, N — выйти, отбросив несохранённые изменения, Ctrl+C — вообще передумать и вернуться в редактор.

Важно

Здесь легко потерять текст по невнимательности, нажав N вместо Y на автомате, — так что стоит на секунду прочитать вопрос, а не бить N рефлекторно.

Обе связки — «сохранить и выйти» и «выйти, отбросив правки» — проще один раз прожать руками, чем запоминать по таблице:

Сценарий 1 из 2. Сохрани файл и выйди из nano
GNU nano 7.2notes.txtИзменён
port=2222
user=student
^G Help^W Where Is^K Cut^R Read File^\ Replace^U Paste

Кликни в окно nano, затем нажимай настоящие сочетания клавиш (подсвечены в панели). Если браузер перехватил сочетание — нажми его кнопкой прямо в панели.

Отвечено вопросов: 0 из 4
Какая комбинация из нижней панели nano сохраняет файл, не закрывая редактор?
Что сделает Ctrl+X в nano, если после последнего сохранения ты успел дописать ещё текст?
Экран показывает File Name to Write: notes.txt. Что происходит?
Что означает значок ^ в подсказке ^O Write Out внизу экрана nano?
Отвечено верно: 0 из 4

SSH: подключение к чужому компьютеру

Сервер — это компьютер без экрана и клавиатуры, часто вообще в другом здании. Управляют им по сети, через SSH (Secure Shell) — протокол, который открывает терминал удалённой машины прямо в твоём терминале, шифруя всё, что летает между вами. Набираешь команду у себя — выполняется там, а результат прилетает обратно.

Подключение по паролю

Нажми на часть выражения

Если адрес неверный или машина не отвечает на этом порту, ssh откажется сразу, без долгого ожидания:

ssh -p 2222 student@localhost
ssh: connect to host localhost port 2222: Connection refused

Перевод: «в соединении отказано». Порт закрыт или на нём вообще ничего не слушает — либо ошибка в номере порта, либо SSH-сервер там не запущен. А если ошибка в самом адресе — опечатка в имени машины:

ssh nosuchhost.invalid
ssh: Could not resolve hostname nosuchhost.invalid: Name or service not known

Перевод: «не удалось разрешить имя хоста: имя или служба не известны». Это не «сервер не отвечает», а раньше: DNS вообще не нашёл, по какому IP-адресу искать машину с таким именем — обычно означает опечатку в адресе.

Когда всё указано верно и сервер отвечает, при первом подключении к конкретной машине ssh остановится с неожиданным на вид вопросом:

The authenticity of host 'localhost (::1)' can't be established.
ED25519 key fingerprint is SHA256:ABqQ+3oxmaU6fkkoqfJTjOpuQ3A8KiGxeX79BJEMwEg.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Перевод: «подлинность хоста не может быть установлена... ты уверен, что хочешь продолжить подключение?». У каждого SSH-сервера есть собственный ключ (host key), которым он подтверждает: «это точно я, а не кто-то, притворяющийся мной посередине». В первый раз проверить его нечем — твой компьютер ещё не видел эту машину, поэтому и спрашивает напрямую тебя. Печатаешь yes — и ssh запоминает этот ключ у себя навсегда, в файле ~/.ssh/known_hosts:

Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
student@localhost's password:

Дальше — обычный пароль пользователя на удалённой машине. После успешного входа приглашение в терминале сменится на приглашение удалённой машины, и все команды (ls, cat, apt…) с этого момента выполняются уже там, а не у тебя. Вернуться обратно к себе — команда exit.

Если то же самое подключение повторить ещё раз, вопроса про authenticity уже не будет — ключ уже знаком, ssh сверит его молча и сразу перейдёт к паролю. А если пароль ввести неверно:

Permission denied, please try again.

После нескольких неудачных попыток подряд ssh разрывает соединение вовсе:

student@localhost: Permission denied (publickey,password).

Ключи вместо пароля: ssh-keygen

Пароль каждый раз набирать неудобно, а главное — его теоретически можно подобрать перебором. Реальная практика — заменить пароль парой ключей (key pair): закрытым (private key), который никогда никуда не покидает твой компьютер, и открытым (public key), который можно свободно отдавать хоть всем — из публичного ключа восстановить закрытый вычислительно нереально. Сервер, у которого в списке разрешённых лежит твой публичный ключ, пускает без единого вопроса о пароле — доказательством служит то, что у тебя на руках есть парный закрытый ключ, а его не подделать.

SSH · КЛЮЧЕВАЯ ПАРАid_ed25519закрытый (private)600не покидает твой компьютерid_ed25519.pubоткрытый (public)644едет на сервер, в authorized_keysотдавать можно смело
Закрытый ключ шифрует и остаётся дома под правами 600, открытый — расшифровывает и едет на сервер с обычными 644.

Генерирует такую пару команда ssh-keygen:

ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/student/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/student/.ssh/id_ed25519
Your public key has been saved in /home/student/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:SZMt2OlfwKzF1kXp9D7Ylduw1XJfBnlh+UMa1CcorXU student@laptop

-t ed25519 — какой именно математический алгоритм используем для пары (ed25519 — современный и короткий стандарт по умолчанию в свежих версиях OpenSSH). Дальше три вопроса подряд: где сохранить (Enter — оставить путь по умолчанию), и дважды — кодовую фразу (passphrase), дополнительный пароль именно на сам закрытый ключ. Пустая passphrase (просто Enter дважды) означает «входить будем совсем без вопросов»; непустая — «ключ работает, но при каждом использовании спросит ещё и эту фразу», компромисс между удобством и защитой на случай кражи самого файла ключа.

Результат — два файла:

ls -la ~/.ssh
-rw------- 1 student student 411 Aug 31 18:58 id_ed25519
-rw-r--r-- 1 student student 102 Aug 31 18:58 id_ed25519.pub

Обрати внимание на права: у закрытого ключа id_ed25519600 (rw-------, только владелец, вообще никому больше даже читать нельзя), у публичного id_ed25519.pub — обычные 644. Это не случайность, а первое, что проверяет сам ssh, — разберём отдельно чуть ниже, потому что это прямая связка с самым началом этой главы.

Публичный ключ нужно один раз доставить на сервер, в файл ~/.ssh/authorized_keys того пользователя, под которым будешь заходить. Вручную это cat ~/.ssh/id_ed25519.pub и вставка строки на сервере, а есть готовая утилита, которая делает это одной командой:

ssh-copy-id student@localhost
Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'localhost'"
and check to make sure that only the key(s) you wanted were added.

С этого момента вход происходит без единого вопроса о пароле:

ssh localhost whoami
student

Почему право доступа к ключу — не мелочь

Вернёмся к правам 600 на закрытый ключ — это не просто аккуратность, а требование, которое ssh реально проверяет перед каждым подключением. Испортим права специально и посмотрим на настоящий ответ:

chmod 644 ~/.ssh/id_ed25519
ssh -i ~/.ssh/id_ed25519 localhost whoami
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/student/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/student/.ssh/id_ed25519": bad permissions
student@localhost: Permission denied (publickey,password).
Нажми на часть выражения

Полностью сообщение переводится так: «предупреждение: незащищённый файл закрытого ключа! Права 0644 для файла слишком открыты. Требуется, чтобы файлы закрытых ключей были недоступны другим. Этот ключ будет проигнорирован». SSH рассуждает предельно логично: если файл закрытого ключа мог прочитать кто угодно в системе, то и защита, которую он даёт, ничего не стоит — поэтому он просто отказывается им пользоваться, вообще не пробуя. Чинится ровно той же командой, с которой началась эта глава:

chmod 600 ~/.ssh/id_ed25519
ssh -i ~/.ssh/id_ed25519 localhost whoami
student

Права снова 600 — и ключ снова принят без единого возражения.

Сценарий 1 из 5
755 · rwxr-xr-x
Файл deploy.sh — владелец student, группа student
Пользователь student (в группах: student)
Может ли student запустить deploy.sh?
Отвечено вопросов: 0 из 4
Что означает сообщение ssh: connect to host localhost port 2222: Connection refused?
При первом подключении к новой машине ssh спрашивает Are you sure you want to continue connecting? Зачем этот вопрос?
Чем вход по SSH-ключу отличается от входа по паролю?
ssh отвечает Permissions 0644 ... are too open и отказывается использовать ключ. Что нужно сделать?
Отвечено верно: 0 из 4

scp: скопировать файл на другую машину

scp (secure copy) копирует файлы между машинами тем же зашифрованным каналом, что и ssh, — фактически та же команда cp, только один (или оба) из путей находится не локально, а на удалённом хосте.

Нажми на часть выражения
Важно

Флаг регистра — реальный источник путаницы: ssh -p 2222 и scp -P 2222 задают один и тот же порт, но регистр буквы разный. Перепутать легко, а scp на маленькую -p не пожалуется ошибкой — просто молча применит другое поведение (сохранение времени и прав), что для порта совершенно не то, что нужно.

Копирование одного файла:

scp report.txt localhost:/home/student/report_copy.txt
report.txt 100% 23 12.4KB/s 00:00

Если исходного файла не существует:

scp ghost.txt localhost:/home/student/
scp: stat local "ghost.txt": No such file or directory

Перевод: «не удалось получить сведения о локальном файле ghost.txt: нет такого файла или каталога» — опечатка в имени или файл не в том каталоге.

Каталог одним scp, как и cp, без специального флага не скопировать:

scp mydir localhost:/home/student/
scp: local "mydir" is not a regular file
scp: failed to upload file mydir to /home/student/

Перевод: «mydir — не обычный файл» и «не удалось загрузить файл mydir». Нужен тот же по смыслу флаг, что у cp и rm, — рекурсивный:

scp -r mydir localhost:/home/student/mydir_copy
a.txt 100% 0 0.0KB/s 00:00

Направление копирования можно развернуть — переставить местами локальный и удалённый путь: scp localhost:/home/student/report.txt . скачает файл с сервера на локальную машину, в текущий каталог (.). scp не различает «загрузить» и «скачать» как разные команды — направление задаётся исключительно порядком: что откуда, что куда.

Практикум: от прав до подключения

Собери всю главу в одну связку — пройди путь только терминалом, без единого клика мышью.

Шаг 1. Создай скрипт и проверь его права по умолчанию:

cat > deploy.sh <<EOF
#!/bin/bash
echo "Деплой запущен"
EOF
ls -l deploy.sh

Шаг 2. Попробуй запустить — получи Permission denied — и почини правом на выполнение:

./deploy.sh
chmod +x deploy.sh
./deploy.sh

Шаг 3. Обнови список пакетов и поставь tree:

sudo apt update
sudo apt install tree
tree --version

Шаг 4. Заведи конфиг через nano, впиши одну строку, сохрани (Ctrl+O, Enter) и выйди (Ctrl+X):

nano deploy.conf

Шаг 5. Сгенерируй пару SSH-ключей и проверь права на закрытый ключ — они должны быть 600 сразу после генерации:

ssh-keygen -t ed25519
ls -l ~/.ssh/id_ed25519

Шаг 6. Подключись к серверу (первый раз ответь yes на вопрос про authenticity, дальше — своим паролем):

ssh student@192.168.1.10

Шаг 7. Скопируй конфиг на сервер тем же каналом:

scp deploy.conf student@192.168.1.10:/home/student/

Шаг 8. Финальная проверка: зайди на сервер и убедись, что файл на месте:

ssh student@192.168.1.10 'ls -l deploy.conf'

Типичные ошибки

Шесть сообщений, каждое — с воспроизводящим примером, точным текстом (проверено вживую в реальной Ubuntu), переводом, причиной и починкой.

1. Скрипт без права на выполнение

./hello.sh
bash: ./hello.sh: Permission denied

Перевод: «в доступе отказано». Причина: у файла не установлен бит x — Linux не считает его программой, каким бы правильным ни был код внутри. Как починить: chmod +x hello.sh.

2. chmod на несуществующий файл

chmod +x nope.sh
chmod: cannot access 'nope.sh': No such file or directory

Перевод: «невозможно получить доступ к nope.sh: нет такого файла или каталога». Причина: опечатка в имени или файл ещё не создан. Как починить: проверить точное имя через ls, при необходимости — создать файл.

3. apt без sudo

apt update
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/

Перевод: «невозможно открыть файл блокировки: в доступе отказано» и «невозможно заблокировать каталог». Причина: список пакетов — общесистемный файл, писать в него может только root. Как починить: добавить sudosudo apt update.

4. Пользователь не в sudoers

sudo whoami
student is not in the sudoers file.

Перевод: «student отсутствует в файле sudoers». Причина: этому пользователю администратор машины ещё не выдал право пользоваться sudo. Как починить: попросить администратора добавить пользователя в группу sudo — самостоятельно, без уже имеющихся прав, это не сделать (иначе защита не имела бы смысла).

5. SSH: соединение отклонено

ssh -p 2222 student@localhost
ssh: connect to host localhost port 2222: Connection refused

Перевод: «в соединении отказано». Причина: на указанном порту никто не слушает — неверный номер порта или SSH-сервер там не запущен. Как починить: проверить правильный порт у администратора сервера или запустить SSH-сервер на нужной машине.

6. scp: файл-источник не найден

scp ghost.txt localhost:/home/student/
scp: stat local "ghost.txt": No such file or directory

Перевод: «не удалось получить сведения о локальном файле ghost.txt: нет такого файла или каталога». Причина: опечатка в имени или запуск не из того каталога, где лежит файл. Как починить: проверить ls в текущем каталоге и точное имя файла.

Отвечено вопросов: 0 из 4
Permission denied при ./script.sh и Permission denied (publickey,password) при ssh — это одна и та же причина?
apt update выдал E: Could not open lock file ... Permission denied. Что делать?
ssh: connect to host ... port 2222: Connection refused — на каком этапе произошла ошибка?
Какая из шести ошибок этой главы решается ролью пользователя, а не редактированием прав или команды?
Отвечено верно: 0 из 4

Слова главы

permission
1 / 8

Потренируйся печатать

Числовая запись прав — набирается быстрее буквенной, стоит довести до автоматизма:

Цель: скорость ≥ 120 зн/мин, точность ≥ 90%

chmod +x deploy.sh && ./deploy.sh
клавиша ``клавиша 11клавиша 22клавиша 33клавиша 44клавиша 55клавиша 66клавиша 77клавиша 88клавиша 99клавиша 00клавиша --клавиша ==клавиша ⌫клавиша TabTabклавиша QQклавиша WWклавиша EEклавиша RRклавиша TTклавиша YYклавиша UUклавиша IIклавиша OOклавиша PPклавиша [[клавиша ]]клавиша \\клавиша Caps LockCaps Lockклавиша AAклавиша SSклавиша DDклавиша FFклавиша GGклавиша HHклавиша JJклавиша KKклавиша LLклавиша ;;клавиша ''клавиша EnterEnterклавиша ShiftShiftклавиша ZZклавиша XXклавиша CCклавиша VVклавиша BBклавиша NNклавиша MMклавиша ,,клавиша ..клавиша //клавиша ShiftShiftклавиша CtrlCtrlклавиша WinWinклавиша AltAltклавиша ПробелПробелклавиша AltAltклавиша WinWinклавиша MenuMenuклавиша CtrlCtrl
следующая: C — средний левой руки

Подключение по нестандартному порту:

Цель: скорость ≥ 130 зн/мин, точность ≥ 90%

ssh -p 2222 student@192.168.1.10
explainshell
Вставь любую незнакомую команду целиком — сайт разберёт её по частям и покажет выдержку из документации для каждого флага. Проверь на ssh -p 2222 student@192.168.1.10 или chmod 755 script.sh

Команды и флаги главы

Шпаргалка по всему, что встретилось в этой главе.

КомандаФлаг / формаЧто делаетПример
chmodбуквенная (u/g/o/a + +/-/= + rwx)изменить права конкретной тройкеchmod u+x hello.sh
chmodчисловая (0–7 на тройку)изменить права все три тройки сразуchmod 755 script.sh
chmod-Rприменить рекурсивно ко всему каталогуchmod -R 755 project/
sudoвыполнить одну команду от имени root, подтвердив своим паролемsudo apt update
aptupdateобновить локальный список пакетов, не устанавливая ничегоsudo apt update
aptupgradeобновить уже установленные пакеты до новых версийsudo apt upgrade
aptinstallпоставить новый пакетsudo apt install tree
apt-yсразу отвечать «да» на вопросы подтвержденияsudo apt install -y tree
nanoCtrl+OWrite Out — сохранить файл, не закрывая редактор
nanoCtrl+XExit — выйти (спросит про сохранение, если есть изменения)
ssh-pподключиться на нестандартный порт (строчная p)ssh -p 2222 student@host
ssh-iиспользовать конкретный файл закрытого ключаssh -i ~/.ssh/id_ed25519 host
ssh-keygen-tсгенерировать пару ключей заданного типаssh-keygen -t ed25519
ssh-copy-idскопировать публичный ключ в authorized_keys на сервереssh-copy-id student@host
scp-Pнестандартный порт (заглавная P, не путать с ssh -p)scp -P 2222 f.txt host:
scp-rскопировать каталог рекурсивноscp -r mydir host:~/mydir
Углубиться

umask — откуда берутся права по умолчанию. Когда файл только создаётся, ему сразу назначаются какие-то права — их вычисляет значение umask, которое вычитается из «потолка» 666 для файлов и 777 для каталогов. Типичный umask 022 даёт именно те 644 и 755, что мы разбирали как «стандартные» права в этой главе, — это не совпадение, а прямое следствие настройки по умолчанию.

visudo — как правильно редактировать sudoers. Файл /etc/sudoers напрямую редактировать опасно — одна синтаксическая ошибка может заблокировать sudo для всех сразу, включая самого администратора. Для этого есть специальная команда visudo, которая проверяет синтаксис перед сохранением и не даст выйти с битым файлом.

Файл ~/.ssh/config. Чтобы не помнить каждый раз длинную команду с портом, пользователем и адресом, можно один раз прописать алиас в ~/.ssh/config — и дальше просто ssh champserver вместо ssh -p 2222 student@192.168.1.10.

Дальше по теме:

→ Отдельная тема: SSH-ключи глубоко — пара ключей изнутри, ssh-agent, файл ~/.ssh/config и несколько ключей на одной машине.

Куда дальше: проверенные ресурсы

Челлендж ⭐

Ступень 1. На свежей Ubuntu-машине без пакета tree: установи его через apt (не забудь освежить список пакетов первой командой), выведи версию, чтобы доказать, что установка удалась, и запусти tree в своей домашней папке. Затем создай скрипт check.sh с любым содержимым, попробуй его запустить (получишь Permission denied) и почини правами так, чтобы владелец мог всё, а группа и все остальные — только читать и запускать, не редактировать.

Ступень 2 ⭐. Товарищ по команде скинул тебе на флешке файл id_ed25519 — свой закрытый SSH-ключ, чтобы ты подключился к общему тренировочному серверу под его учёткой. Флешка отформатирована так, что все файлы на ней получают права 644. Команда ssh -i id_ed25519 teammate@192.168.1.20 отказывается работать. Разберись, что покажет ssh, и почини — используя ровно то, что разобрано в этой главе.

Решение (сначала попробуй сам)

Ступень 1:

sudo apt update
sudo apt install tree
tree --version
tree ~

cat > check.sh <<EOF
#!/bin/bash
echo "Проверка окружения"
EOF
./check.sh # Permission denied
chmod 755 check.sh # владелец: rwx, группа и остальные: r-x
./check.sh

Ступень 2 ⭐:

ls -l id_ed25519
# -rw-r--r-- 1 student student ... id_ed25519 — права 0644, слишком открытые
chmod 600 id_ed25519
ssh -i id_ed25519 teammate@192.168.1.20

ssh откажется использовать ключ с правами 0644 и явно напишет об этом: Permissions 0644 for 'id_ed25519' are too open. ... This private key will be ignored. Причина — SSH требует, чтобы закрытый ключ был читаем только владельцем, иначе доверять ему нельзя, ведь прочитать его теоретически мог кто угодно на этой машине. chmod 600 id_ed25519 возвращает права ровно к тем, что ssh-keygen устанавливает по умолчанию сам, — и ключ снова принимается без вопросов.

Сводная проверка по всей главе: 8 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.

Что должен уметь

  • Читать строку прав из ls -l (-rwxr-xr-x) и объяснять, что означает каждая из трёх троек — владелец, группа, остальные.
  • Менять права и буквенной записью (chmod u+x, chmod a-x, chmod u=rwx,g=rx,o=rx), и числовой (chmod 755, chmod 644), понимая, чем 755 отличается от 644.
  • Объяснять, что такое sudo, зачем он нужен и что значит сообщение is not in the sudoers file.
  • Различать apt update, apt upgrade и apt install и объяснять, почему update не ставит и не обновляет ни одной программы.
  • Сохранять и выходить из nano клавишами Ctrl+O и Ctrl+X, понимая, что означает вопрос Save modified buffer?.
  • Подключаться по SSH и паролем, и ключом: генерировать пару ssh-keygen, переносить публичный ключ через ssh-copy-id, и объяснять, зачем закрытый ключ должен иметь права 600.
  • Копировать файлы и каталоги между машинами через scp, не путая заглавную -P с ssh-шной строчной -p.
  • Узнавать по точному тексту сообщения шесть типичных ошибок этой главы — от Permission denied до Connection refused — и знать, как каждую починить.

Комментарии

Комментарии появятся после настройки. Нужен аккаунт GitHub — вход прямо в виджете выше.