Как создать ограниченного пользователя SSH для перенаправления портов?

ændrük предложил обратное соединение для получения легкого соединения SSH с кем-то еще (для удаленной справки). Чтобы это работал, дополнительный пользователь необходим для принятия соединения. Этот пользователь должен смочь передать свой порт через сервер (действия сервера как прокси).

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

Новый пользователь не должен мочь:

  • выполните команды оболочки
  • файлы доступа или файлы загрузки к серверу
  • используйте сервер в качестве прокси (например, webproxy)
  • локальные службы доступа, которые были иначе не публично доступны из-за брандмауэра
  • уничтожьте сервер

Итоговый, как я создаю ограниченного пользователя SSH, который только может соединиться с сервером SSH без полномочий, таким образом, я могу соединиться посредством того соединения с его компьютером?

106
задан 13 April 2017 в 05:24

3 ответа

TL; DR - переходит к нижней части ответа, "Вводя ограничения"

Добавление ограниченного пользователя состоит из двух частей: 1. Создание пользователя 2. Конфигурирование демона SSH (sshd)

Конфигурирование sshd

Лучшее место, которое будет известно возможностям SSH, читая связанные страницы руководства:

Где клиент SSH может выполнить действия?

Прежде чем можно будет ограничить что-то, необходимо знать функции SSH. Плевание через урожаи страниц руководства:

  • Shell управляет выполнением
  • Загрузка файла через sftp
  • Перенаправление портов
    • Клиент вперед (ООН) привык порт для сервера
    • Сервер вперед его порт клиенту
    • Сервер вперед порт другого хоста клиента (выход прокси)
  • Передача X11 (передача дисплея)
  • Передача агента аутентификации
  • Передача туннельного устройства

От раздела Authentication страницы руководства sshd (8):

Если клиент успешно аутентифицирует себя, диалоговое окно для подготовки сессии вводится. В это время клиент может запросить вещи как выделение pseudo-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 - Указывает, позволяется ли бочка (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) - сделанный
  • локальные службы доступа, которые были иначе не публично доступны из-за брандмауэра - частично, клиент, не могут получить доступ к другим портам, чем 62 222, но могут послушать и соединиться с портом 62222 на сервере
  • уничтожьте сервер - сделанный (обратите внимание, что эти проверки ограничены сервером SSH. Если у Вас есть другой уязвимый сервис на машину, это могло бы позволить возможному взломщику командам выполнения, уничтожить сервер, и т.д.),
166
ответ дан 22 November 2019 в 23:00

Я уверен, что существует много решений этого, и более устойчивы, чем то, которое я предлагаю. Однако это может быть достаточно для Ваших потребностей. Чтобы сделать это, я предполагаю, что пользователь имеет, может сделать ssh основанную на ключе аутентификацию (шпаклевка, или любой Unix ssh должен поддерживать это).

  • Добавьте пользователя, как Вы обычно были бы ('adduser' или любой другой инструмент)

  • Создайте пользователей .ssh dir и .ssh/authorized_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, 'читает'" для них, независимо от того, что они пытаются выполнить. 'читайте', будет просто читать до новой строки, и затем выйдет оболочка, таким образом, пользователь просто должен будет совершить нападки, 'входят' для уничтожения соединения.

Существует много других вещей, которые Вы могли сделать в 'команде ='. Посмотрите man authorized_keys и поиск 'команды' для получения дополнительной информации.

Если Вам не нравится то, что удар входит, уничтожает соединение, Вы могли использовать что-то как следующее для 'команды =' запись:

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

Это просто создает временный FIFO в пользовательском корневом каталоге и затем пытается читать из него. Ничто не будет писать в тот файл, таким образом, это зависнет неограниченно долго. Кроме того, если Вы хотите сильно завершить то соединение, Вы могли бы сделать что-то как:

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

Это должно использовать очень небольшие ресурсы, и ничто не должно мочь пойти не так, как надо в том сценарии, который не закончился бы в завершении оболочки.

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

Я не проводил руку, как Вы могли позволить пользователю удаленному вперед (ssh -R) но предел (ssh -L). Возможно, 'permitopen' мог использоваться. Поиск с помощью Google не был очень полезен. Казалось бы, что что-то как 'без перенаправления портов, permitremoteopen=10001' будет полезно позволить ssh -R 6901:localhost:6901.

Это - решение. Это может совершенно определенно быть изменено к лучшему, и любое открытие удаленных портов должно тщательно исследоваться. Если бы моя цель состояла в том, чтобы позволить моей Бабушке соединяться в мою LAN, таким образом, я мог использовать vnc для просмотра ее экрана, и доступ к тем ключам был ограничен ею, я лично чувствовал бы себя довольно в безопасности. Если бы это было для предприятия, то более полное расследование было бы необходимо. Одна вещь знать ssh -N не запрашивает оболочку вообще, таким образом, 'команда =' код не выполняется.

Другой, возможно более безопасные механизмы могут включать создание пользовательской оболочки для пользователя и даже блокировки это вниз с apparmour.

3
ответ дан 22 November 2019 в 23:00

Попробуйте command="exit"

Это заставит пользователей использовать эту команду для переадресации портов

ssh -NfR EXTERNAL_PORT:localhost:INTERNAL_PORT usr@server -i key

0
ответ дан 11 December 2020 в 18:40

Другие вопросы по тегам:

Похожие вопросы: