Як створити обмеженого користувача SSH для переадресації портів?


106

ændrük запропонував зворотне з'єднання для отримання простого SSH-з'єднання з кимось іншим (для віддаленої допомоги). Щоб це працювало, потрібен додатковий користувач, щоб прийняти з'єднання. Цей користувач повинен мати можливість пересилати свій порт через сервер (сервер виступає як проксі).

Як створити обмеженого користувача, який не може виконати нічого іншого, ніж описано вище?

Новий користувач не повинен:

  • виконання команд оболонки
  • доступ до файлів або завантаження файлів на сервер
  • використовувати сервер як проксі (наприклад, webproxy)
  • отримати доступ до місцевих служб, які в іншому випадку не були загальнодоступними через брандмауер
  • вбити сервер

Підсумовуючи, як я можу створити обмеженого користувача SSH, який може підключитися до SSH-сервера без привілеїв, щоб я міг підключитися через його з'єднання з його комп'ютером?


Відповіді:


166

TL; DR - переходьте до нижньої частини відповіді "Застосування обмежень"

Додавання обмеженого користувача складається з двох частин: 1. Створення користувача 2. Налаштування демона SSH (sshd)

Налаштування sshd

Найкраще місце для ознайомлення з можливостями SSH - це, прочитавши відповідні сторінки посібника:

Де клієнт SSH може виконувати дії?

Перш ніж щось обмежити, потрібно знати особливості SSH. Пролітання по сторінках з інструкціями дає:

  • Оболонка команд виконання
  • Завантаження файлів через sftp
  • Експедиція порту
    • Клієнт пересилає (не) використаний порт на сервер
    • Сервер пересилає свій порт клієнту
    • Сервер пересилає клієнту порт іншого хоста (проксі-ish)
  • Переадресація X11 (переадресація дисплея)
  • Переадресація агента аутентифікації
  • Пересилання тунельного пристрою

З розділу аутентифікації на сторінці керівництва sshd (8) :

Якщо клієнт успішно проходить автентифікацію, вводиться діалогове вікно для підготовки сеансу. У цей час клієнт може запитати такі речі, як розподіл псевдо-tty, пересилання X11-з'єднань, пересилання TCP-з'єднань або пересилання з'єднання агента аутентифікації по захищеному каналу.

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

Параметри обмеження функцій SSH

Файли та їх параметри, що змінюють поведінку, є:

  • ~/.ssh/authorized_keys - містить ключі, дозволені для підключення, яким можна надати параметри:
    • command="command"- Команда, надана користувачем (якщо така є), ігнорується. Зауважте, що клієнт може вказати TCP та / або X11 переадресацію, якщо вони прямо не заборонені . Зауважте, що ця опція стосується виконання оболонки, команд або підсистеми.
    • no-agent-forwarding - Забороняє переадресацію агента аутентифікації, коли цей ключ використовується для аутентифікації.
    • no-port-forwarding - забороняє пересилати TCP, коли цей ключ використовується для автентифікації
    • no-X11-forwarding - "Забороняє пересилання X11, коли цей ключ використовується для автентифікації."
    • permitopen="host:port" - Обмежте переадресацію локального порту 'ssh -L' таким чином, щоб він міг підключатися лише до вказаного хоста та порту.
  • ~/.ssh/environment- Цей файл зачитується в середовище під час входу (якщо він існує). Обробка середовища відключена за замовчуванням і контролюється за допомогою параметра PermitUserEnvironment
  • ~/.ssh/rc - Містить підпрограми ініціалізації, які потрібно запустити до того, як домашній каталог користувача стане доступним.
  • /etc/ssh/sshd_config - загальносистемний файл конфігурації
    • AllowAgentForwarding - Вказує, чи дозволено переадресація ssh-агента (1).
    • AllowTcpForwarding
    • ForceCommand - "Примушує виконання команди, визначеної ForceCommand, ігноруючи будь-яку команду, надану клієнтом, і ~ / .ssh / rc, якщо вона присутня. Команда викликається за допомогою оболонки входу користувача з опцією -c."
    • GatewayPorts - "Вказує, чи дозволяється віддаленим хостам підключатися до портів, пересланих для клієнта. За замовчуванням sshd (8) прив'язує віддалені переадресації портів до адреси петлі. Це запобігає підключенню інших віддалених хостів до переадресованих портів. GatewayPorts можна використовувати для вказівки цей sshd повинен дозволяти віддаленим переадресаціям портів прив'язуватися до адрес, що не відносяться до циклу, тим самим дозволяючи іншим хостам з'єднуватися. "
    • PermitOpen:

      Вказує напрямки, до яких дозволено переадресацію порту TCP. Специфікація переадресації повинна бути однією з таких форм:

      PermitOpen host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port
      

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

    • PermitTunnel- Вказує, чи дозволяється переадресація пристрою tun (4). За замовчуванням - "ні"
    • X11Forwarding- Вказує, чи дозволено переадресація X11. За замовчуванням - "ні"

Застосування обмежень

Змінення загальносистемного файлу конфігурації /etc/ssh/sshd_configдозволяє застосовувати конфігурацію, навіть якщо застосовано автентифікацію на основі пароля або якщо ~/.ssh/authorized_keysвипадкові дії усунуті обмеження . Якщо ви змінили глобальні параметри за замовчуванням, слід скасувати відповідні варіанти.

Match User limited-user
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   #GatewayPorts no
   AllowAgentForwarding no
   PermitOpen localhost:62222
   ForceCommand echo 'This account can only be used for [reason]'

Тепер додайте користувача:

sudo useradd -m limited-user

Опцію ForceCommandможна опустити, якщо оболонку встановлено на не оболонку типу /bin/false(або /bin/true), оскільки /bin/false -c [command]вона нічого не зробить.

Тепер клієнт може підключитися лише до порту 62222 за адресою зворотного зв'язку сервера через SSH (він не буде слухати на загальнодоступній IP-адресі)

Відключення AllowTcpForwardingтакож забороняє використання -R, тим самим перемагаючи використання такого обмеженого облікового запису для пересилання одного порту. PermitOpen localhost:62222припускає, що порт 62222 на сервері ніколи не використовується, оскільки клієнт може радісно підключитися до нього і слухати його також.

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

command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"

Перевірте

Щоб бути впевненим, що він працює, як очікувалося, потрібно запустити деякі тестові випадки. У наведених нижче командах hostслід замінити фактичний логін, якщо він не встановлений ~/.ssh/config. За командою показана команда, яку слід виконати або на клієнті, або на сервері (як зазначено).

# connection closed:
ssh host
# connection closed (/bin/date is not executed):
ssh host /bin/date
# administratively prohibited (2x):
ssh host -N -D 62222 # client: curl -I --socks5 localhost:62222 example.com
ssh host -N -L 8080:example.com:80 # client: curl -I localhost:8080
sftp host
# should be possible because the client should forward his SSH server
ssh host -N -R 8080:example.com:80 # server: curl -I localhost:8080
# This works, it forwards the client SSH to the server
ssh host -N -R 62222:localhost:22
# unfortunately, the client can listen on that port too. Not a big issue
ssh host -N -L 1234:localhost:62222

Висновок

Контрольний список: Користувач SSH не повинен:

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

3
Щоб це працювало, обліковий запис, доданий користувачем, useraddповинен бути розблокований. Це можна зробити, замінивши пароль /etc/shadowна зірочку ( *) або встановивши пароль, використовуючи sudo passwd limited-user.
Лекенштейн

2
SFTP працює, тому що SSH-сервер виконує sftp-serverкоманду. З ForceCommand, ця команда більше не буде виконуватися.
Лекенштейн

2
Також корисний from=варіант в authorized_keys. Це дозволяє обмежити використання ключа джерелами з певною IP-адресою або іменем хоста. Приклад, from="1.1.1.1"або from="10.0.0.?,*.example.com". Дивіться розділ "AUTHORIZED_KEYS ФАЙЛ ФАЙЛУ" на головній сторінці ( linux.die.net/man/8/sshd ) для всіх параметрів дозволених ключів .
Донн Лі

2
"AllowTcpForwarding local" забороняє дистанційне переадресація. (Я не знаю, чи існувала вона, коли була написана відповідь.)
Саймон Сапін

1
Зауважте, що це порушується стійкими з’єднаннями ssh, тому у вас не повинно бути нічого подібного Host * ControlMaster autoу вашому ~/.ssh/configфайлі під час з'єднання ssh -N. Якщо вам це потрібно, використовуйтеssh -N -o ControlMaster=no
nh2

3

Я впевнений, що для цього є багато рішень, і багато більш надійних, ніж той, який я пропоную. Однак цього може бути достатньо для ваших потреб. Для цього я припускаю, що користувач може виконати автентифікацію на основі ключа ssh (putty або будь-яка unix ssh повинна підтримувати це).

  • Додайте користувача, як зазвичай ("adduser" або будь-який інший інструмент)

  • Створіть користувачів .ssh dir та .ssh / Author_keys

your_user $ sudo -Hu ssh_forwarder /bin/bash

ssh_forwarder $ cd ~
ssh_forwarder $ mkdir .ssh
ssh_forwarder $ ( umask 066 && cat > .ssh/authorized_keys ) <<EOF
no-agent-forwarding,no-X11-forwarding,command="read a; exit" ssh-rsa AAAB3NzaC1y....2cD/VN3NtHw== smoser@brickies
EOF
  • Вимкнути доступ до пароля до цього облікового запису.
your_user $ sudo usermod --lock ssh_forwarder

Тепер єдиний спосіб, коли користувач може потрапити у вашу систему, це через доступ до відповідного ключа ssh, і ssh запустить "/ bin / bash -c 'read a" "для них, незалежно від того, що вони намагаються запустити. 'read a' буде просто читати до появи нового рядка, і тоді оболонка вийде, тож користувачеві достатньо натиснути «enter», щоб перервати з'єднання.

Є багато інших речей, які ви можете зробити в команді =. Перегляньте man authorized_keysта знайдіть „команду“ для отримання додаткової інформації.

Якщо вам не подобається, що натискання клавіші вбиває з'єднання, ви можете використати щось на зразок наступного для запису 'command =':

command="f=./.fifo.$$ && mkfifo $f && trap \"rm -f $f\" EXIT && read a <$f && echo $a; exit;"

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

 your_user$ echo GOODBYE | sudo tee ~ssh_forwarder/.fifo.*

Для цього слід використовувати дуже мало ресурсів, і нічого не повинно бути помилковим у тому сценарії, який не закінчився б закінченням оболонки.

sleep 1h; echo You have been here too long. Good bye.

Я не бачив, як ви можете дозволити користувачу віддалено вперед ( ssh -R), але обмежити ( ssh -L). Можливо, може бути використаний «дозвіл на відкриття». Гуглінг не дуже допомагав. Здавалося б, було б корисно дозволити щось на кшталт "без переадресації порту, позволення перегляду = 10001" ssh -R 6901:localhost:6901.

Це рішення. Це, безумовно, можна покращити, і будь-яке відкриття віддалених портів слід ретельно перевірити. Якщо моєю метою було дозволити моїй бабусі підключитися до моєї локальної мережі, щоб я міг використовувати vnc для перегляду її екрана, а доступ до цих клавіш був обмежений нею, я особисто відчував би себе в безпеці. Якби це було для підприємства, було б необхідне більш ретельне розслідування. Одне, що потрібно пам’ятати, - це не вимагати оболонки взагалі, тому код 'command =' не виконується.ssh -N

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


3
Це виглядає дуже хакітно, навіть необов’язково мати оболонку, оскільки жодної команди не потрібно виконувати. Опцію див . На сторінціssh керівництва -N. Має бути більш чистий спосіб досягти цього.
Лекенштейн

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

Я робив деякі дослідження (див. Вище). Оскільки ssh -Nкоманда взагалі не виконує команду, command="something"закриття сеансу не проблема .
Лекенштейн

Я щось пропускаю? Здавалося, chsh ssh_forwarder -s /bin/false це все, що потрібно.
typelogic
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.