SSH - поради, приклади та тунелі

Практичні приклади SSH, які виведуть на новий рівень ваші навички віддаленого системного адміністратора. Команди та поради допоможуть не тільки використовувати SSH, але і грамотніше переміщатися по мережі. Знання кількох трюків ssh корисне будь-якому системному адміністратору, мережному інженеру або фахівцю з безпеки.


Спочатку основи

Розбір командного рядка SSH

У наступному прикладі використовуються звичайні параметри, які часто зустрічаються при підключенні до віддаленого сервера SSH.

1localhost:~$ ssh -v -p 22 -C neo@remoteserver
  • v: відображення налагоджувальної інформації особливо корисний під час аналізу проблем аутентифікації. Можна використовувати кілька разів, щоб вивести додаткову інформацію.

  • p 22: порт для підключення до віддаленого сервера SSH. 22 не обов’язково вказувати, тому що це значення за замовчуванням, але якщо протокол на якомусь іншому порту, то вказуємо за допомогою параметра -p. Порт прослуховування вказується у файлі sshd_config у форматі Port 2222.

  • C: Стиснення для з’єднання. Якщо у вас повільний канал або переглядає багато тексту, це може прискорити зв’язок.

  • neo@: рядок перед символом @ означає ім’я користувача для автентифікації на віддаленому сервері. Якщо не вказати його, то за умовчанням буде використовуватись ім’я користувача облікового запису, до якого ви увійшли в даний момент (~$whoami). Користувача також можна вказати параметром -l.

  • remoteserver: ім’я хоста, до якого підключається ssh, це може бути повне доменне ім’я, IP-адреса або будь-який хост у локальному файлі hosts. Для підключення до хоста, який підтримує IPv4 і IPv6, можна додати в командний рядок параметр -4 або -6 для правильного резолвінгу.

Усі перелічені параметри є необов’язковими, крім remoteserver.

Використання конфігураційного файлу

Хоча багато хто знайомий із файлом sshd_config, є ще файл конфігурації клієнта для команди ssh. Значення за промовчанням ~/.ssh/config, але його можна визначити як параметр опції -F.

1Host *
2     Port 2222
3
4Host remoteserver
5     HostName remoteserver.thematrix.io
6     User neo
7     Port 2112
8     IdentityFile /home/test/.ssh/remoteserver.private_key

У наведеному вище прикладному файлі конфігурації ssh два записи хоста.

  • Перша позначає всі хости, всім застосовується параметр конфігурації Port 2222.
  • Друга каже, що з хоста remoteserver слід використовувати інше ім’я користувача, порт, FQDN і IdentityFile.

Файл конфігурації може заощадити багато часу на введення символів, дозволяючи автоматично застосовувати просунуту конфігурацію під час підключення до конкретних хостів.

Копіювання файлів SSH за допомогою SCP

SSH-клієнт поставляється з двома іншими дуже зручними інструментами для копіювання файлів із зашифрованого ssh-з’єднання. Нижче див. приклад стандартного використання команд scp та sftp. Зверніть увагу, що багато параметрів для ssh застосовуються і в цих командах.

1localhost:~$ scp mypic.png neo@remoteserver:/media/data/mypic_2.png

У цьому прикладі файл mypic.png скопійований на remoteserver в папку /media/data і перейменований mypic_2.png. Не забувайте про різницю у параметрі порту. На цьому трапляються багато хто, хто запускає scp з командного рядка. Тут параметр порту –P, а не –p, як у ssh-клієнті!

Для тих, хто знайомий з консольним ftp, багато команд схожі на sftp. Ви можете зробити push, put та ls.

sftp neo@remoteserver

Практичні приклади

Багато з цих прикладів можна досягти результату різними методами. Як і у всіх наших підручниках та прикладах, перевага надається практичним прикладам, які просто роблять свою справу.

SSH socks-проксі

Функція SSH Proxy під номером 1 з поважних причин. Вона більш потужна, ніж багато хто припускає, і дає вам доступ до будь-якої системи, до якої має доступ віддалений сервер, використовуючи практично будь-яку програму. Клієнт ssh може тунелювати трафік через проксі-сервер SOCKS однією простою командою. Важливо розуміти, що трафік до віддалених систем виходитиме від віддаленого сервера, так буде вказано в логах веб-сервера.

1localhost:~$ ssh -D 8888 user@remoteserver
2
3localhost:~$ netstat -pan | grep 8888
4tcp        0      0 127.0.0.1:8888       0.0.0.0:*               LISTEN      23880/ssh

Тут ми запускаємо socks-проксі на TCP-порт 8888, друга команда перевіряє, що порт активний в режимі прослуховування. 127.0.0.1 вказує, що служба працює лише на localhost. Ми можемо застосувати трохи іншу команду для прослуховування всіх інтерфейсів, включаючи ethernet або wifi, це дозволить іншим програмам (браузерам і т.д.) у нашій мережі підключатися до проксі-сервісу через ssh socks-проксі

1localhost:~$ ssh -D 0.0.0.0:8888 user@remoteserver

Тепер можемо налаштувати браузер для підключення до socks-проксі. У Firefox виберіть Установки | Основні | Настройки мережі. Вкажіть IP-адресу та порт для підключення

socks-проксі порт 8888

Зверніть увагу на опцію в нижній частині форми, щоб DNS-запити браузера також йшли через проксі SOCKS. Якщо ви використовуєте проксі-сервер для шифрування веб-трафіку в локальній мережі, то, напевно, захочете вибрати цю опцію, щоб DNS-запити тунелювалися через SSH-з’єднання.

Активація socks-проксі у Chrome

Запуск Chrome з певними параметрами командного рядка активує socks-проксі та тунелювання DNS-запитів з браузера. Використовуйте tcpdump, щоб перевірити, чи DNS-запитів більше не видно.

1localhost:~$ google-chrome --proxy-server="socks5://192.168.1.10:8888"

Використання інших програм з проксі

Майте на увазі, що багато інших програм також можуть використовувати socks-проксі. Веб-браузер просто найпопулярніший із них. Деякі програми мають параметри конфігурації для активації проксі-сервера. Іншим потрібно трохи допомогти допоміжною програмою. Наприклад, proxychains дозволяє запустити через socks-проксі Microsoft RDP та ін.

1localhost:~$ proxychains rdesktop $RemoteWindowsServer

Параметри конфігурації socks-проксі задаються у файлі конфігурації proxychains.

Підказка: якщо ви використовуєте віддалений робочий стіл з Linux на Windows? Спробуйте клієнт FreeRDP. Це більш сучасна реалізація, ніж rdesktop, з набагато плавнішою взаємодією.

Варіант використання SSH через socks-проксі

Ви сидите в кафе або готелі і змушені використовувати досить ненадійний WiFi. З ноутбука локально запускаємо ssh-проксі та встановлюємо ssh-тунель у домашню мережу на локальний Rasberry Pi. Використовуючи браузер або інші програми, налаштовані для socks-проксі, ми можемо отримати доступ до будь-яких мережевих служб у нашій домашній мережі або вийти в Інтернет через домашнє підключення. Все між вашим ноутбуком та домашнім сервером (через Wi-Fi та інтернет додому) зашифровано у тунелі SSH.

Тунель SSH (переадресація портів)

У простій формі SSH-тунель просто відкриває порт у вашій локальній системі, який підключається до іншого порту на іншому кінці тунелю.

1localhost:~$ ssh  -L 9999:127.0.0.1:80 user@remoteserver

Розберемо параметр -L. Його можна подати як локальну сторону прослуховування. Таким чином, у прикладі вище порт 9999 прослуховується на стороні localhost і переадресовується через порт 80 на remoteserver. Зверніть увагу, що 127.0.0.1 відноситься до localhost на віддаленому сервері!

Піднімемося на сходинку. У цьому прикладі порти прослуховування зв’язуються з іншими вузлами локальної мережі.

1localhost:~$ ssh  -L 0.0.0.0:9999:127.0.0.1:80 user@remoteserver

У цих прикладах ми підключаємося до порту на веб-сервері, але це може бути проксі-сервер або будь-яка інша служба TCP.

SSH-тунель на сторонній хост

Ми можемо використовувати самі параметри для підключення тунелю з віддаленого сервера до іншої служби, запущеної на третій системі.

1localhost:~$ ssh  -L 0.0.0.0:9999:10.10.10.10:80 user@remoteserver

У цьому прикладі ми перенаправляємо тунель від remoteserver до веб-сервера, що працює на 10.10.10.10. Трафік з remoteserver до 10.10.10.10 не в SSH-тунелі. Веб-сервер на 10.10.10.10 вважатиме remoteserver джерелом веб-запитів.

Зворотній SSH-тунель

Тут налаштуємо порт, що прослуховує, на віддаленому сервері, який буде підключатися назад до локального порту на нашому localhost (або іншій системі). ‘‘‘bash localhost:~$ ssh -v -R 0.0.0.0:1999:127.0.0.1:902 192.168.1.100 user@remoteserver

У цій SSH-сесії встановлюється з'єднання з порту 1999 на remoteserver до порту 902 на нашому локальному клієнті.

### Зворотній проксі SSH
У цьому випадку ми встановлюємо socks-проксі на нашому ssh-з'єднанні, проте проксі слухає на віддаленому кінці сервера. 
Підключення до цього дистанційного проксі тепер з'являються з тунелю як трафік з нашого localhost.
```bash
localhost:~$ ssh -v -R 0.0.0.0:1999 192.168.1.100 user@remoteserver

Устранение проблем с удалёнными SSH-туннелями

Якщо у вас виникли проблеми з роботою віддалених опцій SSH, перевірте за допомогою netstat, до яких інтерфейсів підключений порт прослуховування. Хоча ми в прикладах вказали 0.0.0.0, але якщо значення GatewayPorts в sshd_config встановлено на значення no, то листенер буде прив’язаний лише до localhost (127.0.0.1).

Попередження безпеки Зверніть увагу, що при відкритті тунелів та socks-проксі внутрішні мережні ресурси можуть бути доступні ненадійним мережам (наприклад, інтернету!). Це може бути серйозною загрозою безпеці, тому переконайтеся, що ви розумієте, що є слухачем і до чого має доступ.

Встановлення VPN по SSH

Загальний термін серед спеців за методами атаки (пентестери та ін.) - Це «точка опори в мережі». Після встановлення з’єднання в одній системі ця система стає шлюзом для подальшого доступу до мережі. Точка опори, що дозволяє рухатися вшир.

Для такої точки опори ми можемо використовувати SSH-проксі та proxychains, однак є деякі обмеження.

Наприклад, не вийде працювати безпосередньо із сокетами, тому ми не зможемо сканувати порти всередині мережі через Nmap SYN.

Використовуючи цей більш просунутий варіант VPN, з’єднання знижується до рівня 3. Потім ми можемо просто направити трафік через тунель, використовуючи стандартну мережну маршрутизацію. Метод використовує ssh, iptables, tun interfaces та маршрутизацію. Спочатку потрібно встановити ці параметри в sshd_config. Оскільки ми вносимо зміни до інтерфейсів і віддаленої, і клієнтської системи, нам потрібні права root з обох сторін.

1PermitRootLogin yes
2PermitTunnel yes

Потім встановимо ssh-з’єднання, використовуючи параметр, який вимагає ініціалізації tun-пристроїв.

1localhost:~# ssh -v -w any root@remoteserver

Тепер у нас має бути пристрій tun під час показу інтерфейсів (# ip a). Наступний крок додасть IP-адреси до тунельних інтерфейсів.

Сторона клієнта SSH:

1localhost:~# ip addr add 10.10.10.2/32 peer 10.10.10.10 dev tun0
2localhost:~# ip tun0 up

Сторона сервера SSH:

1remoteserver:~# ip addr add 10.10.10.10/32 peer 10.10.10.2 dev tun0
2remoteserver:~# ip tun0 up

Тепер у нас прямий маршрут до іншого хоста (route -n та ping 10.10.10.10). Можна маршрутизувати будь-яку підсітку через хост з іншого боку.

1localhost:~# route add -net 10.10.10.0 netmask 255.255.255.0 dev tun0

На віддаленому боці необхідно включити ip_forward та iptables.

1remoteserver:~# echo 1 > /proc/sys/net/ipv4/ip_forward
2remoteserver:~# iptables -t nat -A POSTROUTING -s 10.10.10.2 -o enp7s0 -j MASQUERADE

VPN через тунель SSH на мережевому рівні 3. Якщо виникають проблеми, використовуйте tcpdump і ping, щоб встановити причину. Оскільки ми граємо на рівні 3, наші пакети icmp підуть через цей тунель.

Копіювання ключа SSH (ssh-copy-id)

Тут є кілька способів, але ця команда заощаджує час, щоб не копіювати файли вручну. Вона просто копіює ~/.ssh/id_rsa.pub (або стандартний) з вашої системи в ~/.ssh/authorized_keys на віддаленому сервері.

1localhost:~$ ssh-copy-id user@remoteserver

Дистанційне виконання команд (не інтерактивно)

Команду ssh можна зв’язати з іншими командами для зручного інтерфейсу. Просто додайте команду, яку хочете запустити на віддаленому хості, як останній параметр у лапках.

1localhost:~$ ssh remoteserver "cat /var/log/nginx/access.log" | grep badstuff.php

У даному прикладі grep виконується на локальній системі після того, як лог завантажувався по ssh-каналу. Якщо файл великий, зручніше запустити grep на віддаленій стороні, просто уклавши обидві команди в подвійні лапки.

Інший приклад виконує ту ж функцію, що і ssh-copy-id з прикладу 7.

1localhost:~$ cat ~/.ssh/id_rsa.pub | ssh remoteserver 'cat >> .ssh/authorized_keys'

Дистанційне перехоплення пакетів та перегляд у Wireshark

Приклад tcpdump. Використовуйте його для віддаленого перехоплення пакетів з видачею результату безпосередньо у GUI локального Wireshark.

1$ ssh root@remoteserver 'tcpdump -c 1000 -nn -w - not port 22' | wireshark -k -i -

Копіювання локальної папки на віддалений сервер SSH

Гарний трюк, який стискає папку за допомогою bzip2 (це параметр -j у команді tar), а потім витягує потік bzip2 з іншого боку, створюючи на віддаленому сервері дублікат папки.

1localhost:~$ tar -cvj /datafolder | ssh remoteserver "tar -xj -C /datafolder"

Дистанційні програми GUI з переадресацією SSH X11

Якщо на клієнті та віддаленому сервері встановлені «ікси», можна віддалено виконати команду GUI, з вікном на вашому локальному робочому столі. Ця функція існує давно, але, як і раніше, дуже корисна.

Запустіть віддалений веб-браузер або консоль VMWawre Workstation, як я роблю в цьому прикладі.

1localhost:~$ ssh -X remoteserver vmware

Потрібний рядок X11Forwarding yes у файлі sshd_config.

Дистанційне копіювання файлів за допомогою rsync та SSH

rsync значно зручніше scp, якщо потрібно періодичне резервне копіювання каталогу, великої кількості файлів або дуже великих файлів. Тут є функція відновлення після збою передачі та копіювання лише змінених файлів, що зберігає трафік та час.

У цьому прикладі використовується стиск gzip (-z) та режим архівування (-a), який включає рекурсивне копіювання.

1$ rsync -az /home/testuser/data remoteserver:backup/

SSH через мержу Tor

Анонімна мережа Tor може тунелювати SSH-трафік за допомогою команди torsocks. Наступна команда прокине ssh-проксі через Tor.

1localhost:~$ torsocks ssh myuntracableuser@remoteserver

Torsocks буде використовувати для проксі порт 9050 на localhost. Як завжди при використанні Tor, необхідно серйозно перевіряти, який трафік тунелюється та інші проблеми операційної безпеки (opsec). Куди йдуть ваші запити DNS?

SSH до інстансу EC2

Для підключення до інстансу EC2 необхідний закритий ключ. Завантажте його (розширення .pem) з панелі керування Amazon EC2 та змініть роздільну здатність (chmod 400 my-ec2-ssh-key.pem). Зберігайте ключ у надійному місці або помістіть його у папку ~/.ssh/.

1localhost:~$ ssh -i ~/.ssh/my-ec2-key.pem ubuntu@my-ec2-public

Параметр -i просто вказує на ssh-клієнту використовувати цей ключ. Файл ~/.ssh/config ідеально підходить для автоматичного налаштування використання ключа під час підключення до хоста ec2.

Host my-ec2-public
   Hostname ec2???.compute-1.amazonaws.com
   User ubuntu
   IdentityFile ~/.ssh/my-ec2-key.pem

Редагування текстових файлів за допомогою VIM через ssh/scp

Для всіх любителів vim ця порада заощадить небагато часу. За допомогою vim файли редагуються через scp однією командою. Цей метод просто створює файл локально /tmp, а потім копіює його назад, як тільки ми його зберегли з vim.

1localhost:~$ vim scp://user@remoteserver//etc/hosts

Примітка: формат трохи відрізняється від звичайного scp. Після хоста у нас подвійний//. Це посилання абсолютний шлях. Один слеш означатиме шлях щодо домашньої папки users.

Якщо ви побачите таку помилку, двічі перевірте формат команди. Зазвичай це означає синтаксичну помилку.

**warning** (netrw) cannot determine method (format: protocol://[user@]hostname[:port]/[path])

Монтування віддаленого SSH як локальної папки з SSHFS

За допомогою sshfs – клієнта файлової системи ssh – ми можемо підключити локальний каталог до віддаленого розташування зі всіма взаємодіями файлів у зашифрованому сеансі ssh.

На Ubuntu та Debian встановимо пакет sshfs, а потім просто примонтуємо віддалене розташування до нашої системи.

1localhost:~$ apt install sshfs
2
3localhost:~$ sshfs user@remoteserver:/media/data ~/data/

Мультиплексування SSH за допомогою ControlPath

За промовчанням за наявності існуючого підключення до віддаленого сервера за допомогою ssh друге підключення за допомогою ssh або scp встановлює новий сеанс із додатковою автентифікацією.

Опція ControlPath дозволяє використовувати існуючий сеанс для всіх наступних з’єднань. Це значно прискорить процес: ефект помітний навіть у локальній мережі, а тим більше під час підключення до віддалених ресурсів.

ControlPath вказує сокет для перевірки новими з’єднаннями щодо наявності активної сесії ssh. Остання опція означає, що навіть після виходу з консолі існуючий сеанс залишиться відкритим 10 хвилин, тому протягом цього часу ви зможете повторно підключитися по існуючому сокету. Для отримання додаткової інформації дивіться довідку ssh_config man.

Host remoteserver
        HostName remoteserver.example.org
        ControlMaster auto
        ControlPath ~/.ssh/control/%r@%h:%p
        ControlPersist 10m

Потокове відео по SSH за допомогою VLC та SFTP

Навіть давні користувачі ssh і vlc (Video Lan Client) не завжди знають про цю зручну опцію, коли потрібно подивитися відео по мережі. У налаштуваннях File | Open Network Stream програми vlc можна ввести місцезнаходження як sftp://. Якщо потрібно пароль, з’явиться запит.

1sftp://remoteserver//media/uploads/myvideo.mkv

Двофакторна аутентифікація

Така ж двофакторна автентифікація, як у вашого банківського рахунку або облікового запису Google, може бути застосована до сервісу SSH. Звичайно, ssh спочатку має функцію двофакторної аутентифікації, під якою маються на увазі пароль і ключ SSH. Перевага апаратного токена або програми Google Authenticator полягає в тому, що це зазвичай інший фізичний пристрій.

Стрибки по хост з ssh і -J

Якщо через сегментацію мережі доводиться переходити через кілька хостів ssh, щоб дістатися кінцевої мережі призначення, вам заощадить час ярлик -J.

1localhost:~$ ssh -J host1,host2,host3 [email protected]

Тут головне розуміти, що це не аналогічно команді ssh host1, потім user@host1: ~ $ ssh host2 і т. д.

Параметр -J хитро використовує переадресацію, щоб localhost встановлював сеанс з наступним хостом у ланцюжку. Таким чином, у наведеному вище прикладі наш localhost автентифікується на host4. Тобто використовуються ключі localhost, а сеанс від localhost до host4 повністю зашифрований.

Для цієї можливості в ssh_config вкажіть опцію конфігурації ProxyJump. Якщо регулярно доводиться переходити через кілька хостів, то автоматизація через конфіг заощадить багато часу.

Блокування спроб брутфорсу SSH за допомогою iptables

Будь-хто, хто керував сервісом SSH та переглядав логи, знає про кількість спроб брутфорсу, які відбуваються щогодини щодня. Швидкий спосіб зменшити шум у логах – перенести SSH на нестандартний порт. Змініть файл sshd_config за допомогою параметра конфігурації Port##.

За допомогою iptables також можна легко блокувати спроби підключення до порту після досягнення певного порога. Простий спосіб зробити це – використовувати OSSEC, оскільки він не лише блокує SSH, але виконує купу інших заходів щодо виявлення вторгнень на базі імені хоста (HIDS).

SSH Escape для зміни переадресації портів

І наш останній приклад ssh призначено для зміни переадресації портів на льоту в рамках існуючого сеансу ssh. Уявіть такий сценарій. Ви глибоко в мережі; можливо, стрибнули через півдюжини хостів і вам потрібен локальний порт на робочій станції, який перенаправлений на Microsoft SMB старої системи Windows 2003 (хтось пам’ятає ms08-67?). Натиснувши клавішу enter, спробуйте ввести в консолі ~C. Це керуюча послідовність у сесії, що дозволяє вносити зміни до існуючого з’єднання.

localhost:~$ ~C
ssh> -h
Commands:
      -L[bind_address:]port:host:hostport    Request local forward
      -R[bind_address:]port:host:hostport    Request remote forward
      -D[bind_address:]port                  Request dynamic forward
      -KL[bind_address:]port                 Cancel local forward
      -KR[bind_address:]port                 Cancel remote forward
      -KD[bind_address:]port                 Cancel dynamic forward
ssh> -L 1445:remote-win2k3:445
Forwarding port.

Тут ви можете побачити, що ми переадресували наш локальний порт 1445 на Windows 2003 хост, який знайшли у внутрішній мережі. Тепер просто запустіть msfconsole, і можна йти далі (припускаючи, що ви плануєте використовувати цей хост).