При работе с несколькими компьютерами Linux, подключенными к одной сети, нередко требуется установить безопасное соединение с другим компьютером. Для этой цели в Linux предназначен такой инструмент как Secure Shell или SSH. Фактически Secure Shell состоит из трех компонентов: ssh, scp и sftp. ssh собственно используется для установки защищенного удаленного сеанса. scp применяется для копирования файлов на другой компьютер и обратно, на котором запущен процесс SSH. sftp представляет собой безопасный интерфейс FTP-клиента.
Соединение по SSH подразумевает наличие двух элементов: клиента и сервера/хоста. Клиент обращается к хосту и может через ssh взаимодействовать с хостом. Функциональность клиента обычно присутствует в дистрибутивах Linux по умолчанию. В частности, мы можем проверить это, введя команду ssh:
eugene@Eugene:~$ ssh usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] destination [command [argument ...]]
С хостом несколько сложнее. В операционных системах Fedora/Red Hat и SUSE функциональность сервера может присутствовать по умолчанию. В Ubuntu же необходимо установить пакет openssh-server:
sudo apt-get install openssh-server
Если же в Fedora/Red Hat по умолчанию SSH не установлено, то можно установить с помощью следующей команды
sudo yum install openssh-server
После установки проверим статус ssh-сервиса с помощью команды systemctl status ssh
:
eugene@Eugene:~$ systemctl status ssh ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; disabled; preset: enabled) Drop-In: /etc/systemd/system/ssh.service.d └─00-socket.conf Active: active (running) since Mon 2024-03-18 18:26:39 MSK; 15min ago TriggeredBy: ● ssh.socket Docs: man:sshd(8) man:sshd_config(5) Process: 9626 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS) Main PID: 9627 (sshd) Tasks: 1 (limit: 76766) Memory: 1.5M CPU: 98ms
В данном случае мы видим, что сервис активен, то есть хост готов принимать подключения по SSH. Если ssh-сервис установлен, но не запущен, то его можно запустить следующей командой:
sudo systemctl start ssh
Итак, когда на одном компьютере с Linux запущен сервер, мы можем подключиться к нему с другого компьютера, который будет выполнять роль клиента. Для этого введем на компьютере-клиенте команду ssh, которой передадим адрес сервера. Например, в моем случае адрес хоста - 192.168.0.116, соответсьвенно я ввожу:
ssh 192.168.0.116
Адрес компьютера-хоста можно узнать на нем с помощью команды ip
При первом контакте клиент и сервер обмениваются открытыми и закрытыми ключами. При соединении сервер создает ключ на основе своего закрытого ключа (так называемый ключ хоста) и использует его при проверки подключений. При подключении сервер отправляет клиенту свой открытый ключ. Если клиент первый раз подключается к этому хосту, то клиент получает сообщение типа следующего:
eugene@Eugene:~$ ssh 192.168.0.116 The authenticity of host '192.168.0.116 (192.168.0.116)' can't be established. ED25519 key fingerprint is SHA256:jQ5S32RBItZifsdRR+NlvofV+Xeo0nWdKRZcRIXRx6Y. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.0.116' (ED25519) to the list of known hosts. eugene@192.168.0.116's password: Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.14.0-1050-oem x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/pro eugene@eugene-linux:~$
Если клиент уверен, что он хочет подключиться к серверу, то клиент должен ответить "yes" на запрос. В этом случае сервер добавляется в файл .ssh/known_hosts в домашнем каталоге пользователя на клиенте. В следующий раз, когда клиент подключается к серверу, этот файл проверяется, чтобы узнать, известен ли уже сервер. Проверка основана на отпечатке открытого ключа сервера, который представляет собой уникальную контрольную сумму, связанную с открытым ключом сервера. Соединение устанавливается только в том случае, если эта проверка соответствует имени и открытому ключу сервера, к которому подключается клиент. Если эти две части данных не совпадают, в соединении будет отказано.
И после успешного подключения между клиентом и сервером устанавливается защищенный канал. Этот канал устанавливается с помощью ключа сеанса/сессии (session key), который является ключом шифрования, общим для клиента и сервера, и который шифрует все данные, передаваемые между двумя компьютерами. Клиент и сервер согласовывают этот ключ на основе своих открытых ключей. Также клиент и сервер согласуют применяемый протокол шифрования. И после установления защищенного канала у пользователя на клиенте запрашиваются учетные данные - клиент должен ввести пароль.
Команда ssh не запрашивает имя пользователя, поскольку предполагает, что клиент хочет подключиться к другому хосту с тем же логином, то есть логин на клиенте и хосте совпадают. Например, в моем примере выше пользователь на клиенте с логином eugene подключался к хосту на другом компьютере, где учетная запись также имеет логин eugene. Однако также можно явно указать логин, если он отличается. Первый способ - указать имя пользователя и поставить за ним амперсанд при установке соединения с удаленным хостом:
ssh superuser1@192.168.0.116
Второй способ - использовать параметр -l, за которым следует имя учетной записи пользователя для подключения к другому хосту:
ssh -l superuser1 192.168.0.116
В обоих случаях идет подключение к учетной записи пользователя superuser1.
После установления подключения можно увидеть сведения о системе хоста. В моем случае это Ubuntu 22.04:
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.14.0-1050-oem x86_64)
Также выводится некоторая базовая сводка. И в конце можно увидеть, что меняется полное имя текущего пользователя. Например, в моем случае имя клиента "eugene@Eugene" поменялось на "eugene@eugene-linux" (имя на хосте):
eugene@Eugene:~$ ssh 192.168.0.116 The authenticity of host '192.168.0.116 (192.168.0.116)' can't be established. ED25519 key fingerprint is SHA256:jQ5S32RBItZifsdRR+NlvofV+Xeo0nWdKRZcRIXRx6Y. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.0.116' (ED25519) to the list of known hosts. eugene@192.168.0.116's password: Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.14.0-1050-oem x86_64) .............................. eugene@eugene-linux:~$
Таким образом, я теперь нахожусь на машине хоста eugene@eugene-linux и могу вводить стандартные команды и таким образом управлять хостом. Например, посмотреть содержимое текущего каталога на хосте с помощью команды ls -l
:
eugene@eugene-linux:~$ ls -l итого 48 drwxrwxr-x 3 eugene eugene 4096 фев 18 16:47 Android drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Desktop drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Documents drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Downloads drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Music drwxrwxr-x 3 eugene eugene 4096 дек 6 2022 Pictures drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Public drwx------ 8 eugene eugene 4096 фев 19 22:49 snap drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Templates drwxr-xr-x 2 eugene eugene 4096 мар 20 13:33 Videos eugene@eugene-linux:~$
Подобным образом можно выполнять и другие стандартные команды. После завершения работы для отключения от хоста следует выполнить команду exit:
eugene@eugene-linux:~$ exit выход Connection to 192.168.0.116 closed. eugene@Eugene:~$
В итоге консоль выводит сообщение о закрытии подключения, а консоль переходит к компьютеру-клиенту (в моем случае от eugene@eugene-linux к eugene@Eugene).
Если нам больше не нужны данные по подключениям к хостам в .ssh/known_hosts, то мы их можем удалить. Например, в следующей команде очищаем файл, предварительно сделав его бэкап:
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak && echo > ~/.ssh/known_hosts
В SSH один компьютер может быть одновроеменно клиентом и сервером. Но для клиента и сервера существует свой файл конфигурации. Каждый файл конфигурации имеет ряд настроек. При этом
большинство настроек могут принимать одно из двух значений: yes
(настройка включена) и no
(настройка отключена)
Конфигурация клиента размещена в файле /etc/ssh/ssh_config. Но стоит отметить, что это общий файл, который применяется ко всем пользователям в системе, подключающихся по SSH к удаленному хосту. Однако отдельный пользователь может для себя переопределить эти настройки, если создаст файл .ssh_config в домашнем каталоге в подпапке .ssh. Еще один способ переопределить настройки - задать их непосредственно в консоли при вызове команды ssh
Наиболее используемые настройки из /etc/ssh/ssh_config:
Host: эта опция применяется к хосту, к которому подключается пользователь. Она ограничивает последующие объявления определенным хостом (вплоть до следующего слова Host). Имя хоста берется то, которое указывается в командной строке. Обычно эта настройка используется для добавления дополнительной безопасности для определенных хостов. Также можно использовать подстановочные знаки, такие как * и ? для ссылки на более чем одно имя хоста. Например, в файле /etc/ssh/ssh_config по умолчанию можно увидеть следующую строку
Host *
Она говорит о применении последующих настроек ко всем хостам
CheckHostIP: если для этой опции установлено значение "yes" (значение по умолчанию), то SSH проверит IP-адрес хоста в файле known_hosts. Обычно применяется для защиты от подмены DNS или IP-адреса.
Ciphers:. эта настройка принимает несколько аргументов и используется для указания порядка, в котором следует использовать различные алгоритмы шифрования в сеансе SSHv2.
Compression: значения "yes" или "no" для этой настройки определяют, следует ли использовать сжатие в сеансе SSH. По умолчанию не используется.
ForwardX11: определяет, будут ли пересылаться соединения X11. Если установлено значение "yes", графические экраны из сеанса SSH можно пересылать через защищенный туннель. Если не надо включать пересылку X по умолчанию, используйте опцию -X в командной строке при установлении сеанса SSH.
PasswordAuthentication: указывает, надо ли использовать аутентификацию по паролю (по умолчанию используется - значение "yes"). В безопасной среде, в которой для аутентификации применяются ключи, для этой настройки можно установить значение "no", чтобы полностью отключить аутентификацию по паролю.
Конфигурация сервера располагается в файле /etc/ssh/sshd_config, и при необходимости изменить конфигурацию сервера как раз мы можем поместить нужные нам настройки в этот файл. Некоторые настройки сервера повторяют настройки клиента, но есть и специфичные для сервера:
AllowTcpForwarding: указывает, надо ли разрешить клиентам выполнять переадресацию TCP-портов. Если значение "yes" - разрешена (значение по умолчанию),
если no
- не разрешена.
Port: порт, который прослушивает процесс SSH. По умолчанию это порт 22.
PermitRootLogin: указывает, надо ли вы разрешить вход в систему с правами root
PermitEmptyPasswords: указывает, надо ли вы разрешить вход в систему с пустым паролем. По умолчанию значение - no
,
то есть вход с пустым паролем запрещен
X11Forwarding: указывает, надо ли вы разрешить клиентам использовать перенаправление X11.
При работе с SSH доступна такая функциональность как X11Forwarding, которая позволяет управлять приложениями на хосте. Например, мы можем запустить на клиенте графическое приложение, которое будет выполнять при этом всю работу на самом хосте. И для работы X11Forwarding необходимы два условия:
На компьютере-хосте в файле /etc/ssh/sshd_config настройка X11Forwarding должна иметь значение yes
При подключении к компьютеру-хосту надо использовать опцию -X, то есть подключаться с помощью команды ssh -X
Итак, сначала откроем на хосте файл конфигурации /etc/ssh/sshd_config. Найдем в нем строку
# X11Forwarding no
Символ # указывает, что строка закомментирована. А значение "no" указывает, что по умолчанию опция отключена. Изменим эту строку на
X11Forwarding yes
Значение yes
указывает, что настройка включена.
Далее подключимся к этому хосту с другого компьютера с помощью команды ssh -X
. И мы сможем запускать различные приложения, в том числе и графические, которые будут работать непосредственно на хосте. Например:
eugene@Eugene:~$ ssh -X 192.168.0.116 eugene@192.168.0.116's password: Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.14.0-1050-oem x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/pro Last login: Wed Mar 20 13:36:49 2024 from 192.168.0.108 eugene@eugene-linux:~$ code
В данном случае я подключаюсь к хосту с адресом "192.168.0.116". После подключения с помощью code
я запускаю на хосте Visual Studio Code (если он установлен).
Аналогично можно запускать и другие программы. Например:
eugene@eugene-linux:~$ nautilus --browser
Здесь с помощью команды nautilus --browser
запускается программа проводника, который имеется на Ubuntu. И окно проводника отобразит содержимое текущей папки на удаленном хосте.