Проверить сеть, подключиться к серверу по ключу и закрыть лишнее
Чтобы машина работала в сети, ей нужны три вещи: IP-адрес с маской подсети, шлюз — куда отправлять пакеты в другие сети, и DNS-сервер — кто переводит имена в адреса. Первые две показывает команда ip:
$ ip -br a # brief address — кратко
lo UNKNOWN 127.0.0.1/8 ::1/128
ens18 UP 192.168.116.34/24 fe80::b641:8f47:5a50:a157/64
$ ip r # route — таблица маршрутов
default via 192.168.116.1 dev ens18 proto dhcp src 192.168.116.34 metric 1002
192.168.116.0/24 dev ens18 proto dhcp scope link src 192.168.116.34 metric 1002
| Что видно | Значение |
|---|---|
lo, 127.0.0.1 | Петлевой интерфейс: машина сама с собой. Есть всегда |
ens18 (enp0s3 в VirtualBox) | Сетевая карта. Имя зависит от того, как она подключена |
192.168.116.34/24 | Адрес и маска: первые 24 бита — номер сети, адреса 192.168.116.0–255 — «свои» |
default via 192.168.116.1 | Шлюз: всё, что не в своей сети, отправляется на этот адрес |
proto dhcp | Адрес выдан автоматически по DHCP |
Старые команды ifconfig и route из пакета net-tools в Debian по умолчанию не установлены; в инструкциях они ещё встречаются — в ip есть всё то же. Постоянная настройка сети в Debian без графики — файл /etc/network/interfaces; подробно сети разбираются в курсе «Основы компьютерных сетей».
ping отправляет короткие пакеты и ждёт ответа. Он показывает, доходят ли пакеты и за какое время.
$ ping -c 3 ya.ru
PING ya.ru (5.255.255.242) 56(84) bytes of data.
64 bytes from ya.ru (5.255.255.242): icmp_seq=1 ttl=51 time=43.2 ms
64 bytes from ya.ru (5.255.255.242): icmp_seq=2 ttl=51 time=43.0 ms
64 bytes from ya.ru (5.255.255.242): icmp_seq=3 ttl=51 time=43.0 ms
--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
Без -c ping работает бесконечно — остановка Ctrl+C. Имя ya.ru превратилось в адрес 5.255.255.242 — значит, DNS работает. Какой DNS-сервер используется и какие имена заданы вручную:
$ cat /etc/resolv.conf
nameserver 192.168.116.1
$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 debian
$ getent hosts ya.ru # как имя видит система: hosts, затем DNS
2a02:6b8::2:242 ya.ru
ip -br a — есть ли адрес; 2) ip r — есть ли шлюз; 3) ping адреса шлюза — работает ли локальная сеть; 4) ping 77.88.8.8 (DNS Яндекса) — есть ли выход наружу; 5) ping ya.ru — работает ли DNS. Первый неудачный шаг и есть место поломки. Учтите: некоторые серверы не отвечают на ping намеренно, отсутствие ответа ещё не значит, что сервер выключен.Адрес определяет машину, порт — службу на ней: SSH слушает порт 22, веб-сервер — 80 и 443, PostgreSQL — 5432. Какие порты открыты и какие процессы их слушают:
$ sudo ss -tlnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 200 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=23836,fd=7))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=640,fd=6))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=640,fd=7))
Опции: -t — TCP, -l — только слушающие, -n — номера вместо имён, -p — процесс (нужен sudo). Важен адрес в Local Address:
| Адрес | Кто может подключиться |
|---|---|
127.0.0.1, [::1] | Только программы на этой же машине. PostgreSQL выше снаружи недоступен |
0.0.0.0, [::] | Любой, кто доберётся по сети, — если не закрыто межсетевым экраном |
| конкретный адрес | Только через этот интерфейс |
Активные соединения — ss -tn: видно, кто сейчас подключён к серверу, например ваш SSH-сеанс.
SSH (Secure Shell) — зашифрованный удалённый терминал. Сервер sshd на учебной машине уже стоит, если при установке отмечен «SSH-сервер». Клиент ssh есть в Linux, macOS и Windows 10/11 (PowerShell или «Терминал»); в Windows можно использовать и PuTTY.
Виртуальная машина VirtualBox в режиме NAT не видна из основной системы напрямую — для этого в модуле 01 настроен проброс порта: обращения на порт 2222 основной системы уходят на 22 гостевой.
PS C:\> ssh -p 2222 student@127.0.0.1
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
ED25519 key fingerprint is SHA256:8k3Y4nKpY0Qe6cT+3cV9n2u8bG5QxkJwq0Lr1aVb7hM.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
student@127.0.0.1's password:
student@debian:~$
При первом подключении клиент показывает отпечаток ключа сервера и запоминает его в ~/.ssh/known_hosts. Если в следующий раз отпечаток не совпадёт, клиент откажется подключаться с предупреждением REMOTE HOST IDENTIFICATION HAS CHANGED: либо сервер переустановили, либо кто-то подменяет его по дороге. Не удаляйте запись не разобравшись. Свой отпечаток сервер покажет командой ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub — сверьте его в консоли ВМ.
Пароль можно подобрать, подсмотреть или перехватить на чужом компьютере. Ключ — пара файлов: закрытый остаётся у вас, открытый кладётся на сервер. Сервер проверяет, что у вас есть закрытый ключ, не получая его самого. Ключ создаётся на вашем компьютере, а не на сервере:
$ ssh-keygen -t ed25519 -C "student@laptop"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/student/.ssh/id_ed25519):
Enter passphrase for "/home/student/.ssh/id_ed25519" (empty for no passphrase):
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:bA0QDNOrWYMV4ZTqL1thCR9gjcvi+8f22FHlKOwGCkA student@laptop
Парольная фраза шифрует закрытый ключ на диске: украденный файл без неё бесполезен. Её стоит задать. id_ed25519 — закрытый ключ, никому не передаётся; id_ed25519.pub — открытый, его не жалко показать:
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIlznftSrFSI+xYc6L5PtIno9HJ32ueP8xJiWT3DnCSf student@laptop
Открытый ключ дописывается на сервере в файл ~/.ssh/authorized_keys того пользователя, под которым вы входите:
# из Linux и macOS
$ ssh-copy-id -p 2222 student@127.0.0.1
# из Windows PowerShell (ssh-copy-id там нет)
PS C:\> type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh -p 2222 student@127.0.0.1 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
$ ssh -p 2222 student@127.0.0.1 # пароль больше не спрашивается
~/.ssh — 700, authorized_keys — 600, домашний каталог не должен быть доступен на запись группе и остальным. На клиенте закрытый ключ — 600. Ошибки прав видны в sudo journalctl -u ssh на сервере.Чтобы не набирать порт и адрес каждый раз, на клиенте заводят ~/.ssh/config:
Host lab
HostName 127.0.0.1
Port 2222
User student
IdentityFile ~/.ssh/id_ed25519
Теперь достаточно ssh lab. Имя lab работает и в scp, и в VS Code (расширение Remote - SSH).
Сервер с открытым портом 22 в интернете перебирают ботами круглые сутки. Когда вход по ключу работает, вход по паролю отключают. Настройки sshd — в /etc/ssh/sshd_config; свои изменения удобнее класть отдельным файлом в /etc/ssh/sshd_config.d/, тогда обновление пакета не затрёт их.
$ sudo nano /etc/ssh/sshd_config.d/10-hardening.conf
PasswordAuthentication no
PermitRootLogin no
$ sudo sshd -t && sudo systemctl reload ssh # проверить синтаксис, только потом применить
$ sudo sshd -T | grep -Ei '^(passwordauthentication|permitrootlogin) '
permitrootlogin no
passwordauthentication no
sshd -t проверяет конфигурацию и молчит, если ошибок нет; && выполнит перезагрузку настроек, только если проверка прошла. sshd -T показывает итоговые значения после слияния всех файлов.
reload; если новое не проходит — исправляете в первом. Закрыли единственный сеанс с ошибкой в настройках — на облачный сервер теперь только через консоль провайдера.scp копирует файлы через SSH, синтаксис как у cp, а удалённый путь записывается как пользователь@сервер:путь:
$ scp -P 2222 site.tar.gz student@127.0.0.1:/tmp/ # на сервер; порт — заглавная P
$ scp lab:/var/log/nginx/access.log . # с сервера в текущий каталог, через ~/.ssh/config
$ scp -r lab:/etc/nginx ./nginx-backup # каталог — с -r
Для больших каталогов и повторных копирований удобнее rsync -av: он передаёт только изменившиеся файлы. В Windows файлы можно переносить и графическими программами WinSCP или FileZilla (протокол SFTP — тот же SSH).
Межсетевой экран (firewall) решает, какие входящие подключения пропускать. В ядре Linux фильтрацией занимается nftables; для простых случаев над ним есть удобная обёртка ufw (Uncomplicated Firewall). Принцип: запретить всё входящее и открыть только нужные порты.
$ sudo apt install ufw
$ sudo ufw allow OpenSSH # СНАЧАЛА разрешить SSH
$ sudo ufw allow 80/tcp # веб-сервер
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
$ sudo ufw status verbose
Status: active
Default: deny (incoming), allow (outgoing), disabled (routed)
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
ufw enable без правила для SSH закроет доступ к удалённому серверу. На учебной ВМ это поправимо через консоль VirtualBox — потренируйтесь на ней, прежде чем включать экран на настоящем сервере.Проверить снаружи, что порт закрыт, можно попыткой подключения с другой машины: nc -zv адрес 5432 (пакет netcat-openbsd). Закрытый порт ответит отказом или таймаутом.
ip -br a, шлюз — ip r, DNS — /etc/resolv.conf; связь проверяют снизу вверхsudo ss -tlnp — кто какой порт слушает; 127.0.0.1 — только локально, 0.0.0.0 — для всех~/.ssh/authorized_keys на сервере; права 700/600sshd -t перед reload, второе окно для проверкиscp и rsync копируют через SSH, ~/.ssh/config избавляет от длинных команд