Как стать автором
Обновить

Сборка тонкого клиента RDP на базе Raspberry Pi

Время на прочтение18 мин
Количество просмотров76K
С ростом популярности мини-ПК типа Raspberry Pi, и подобных ему клонов, возникла масса кейсов по их использованию в ИТ-инфраструктуре предприятия, умном доме / даче / гараже, и в других применениях.

Одним из удобных и желаемых кейсов является использование RPi как тонкого клиента, подключаемого по протоколу RDP к Windows-системам.

Если Вам интересно, как настроить такое место на базе Raspberry Pi, причем так, чтобы «настроить и забыть» — добро пожаловать под кат. Для совсем ленивых есть готовый образ (см. раздел 6.Б).

Картинка для привлечения внимания


Конкретно в моем опыте (специалист по автоматизации учета / управления) мне часто приходилось организовывать рабочие места, единственной целью которых был доступ к какой-либо программе (в основном желтой), офисному пакету, сети интернет, почте. Иногда — работа с флешками. Сервер, при этом, на предприятии уже был.

При этом, от станции требовалась малошумность, компактность и надежность. Ну или, будем честными, дешевизна. Особенно, если вопрос касался розничной торговли, где все должно быть «прибито гвоздями».

При этом, в прошлом, было перебрано множество решений в виде специализированных «железных» тонких клиентов, но по ряду причин они оказывались неудобными. Где-то требовались специфические смежные задачи типа проброса принтеров на сервер, с которыми они не справлялись. Где-то медленно прорисовывались таблицы, что сводило пользователей с ума. Где-то тонкие клиенты просто работали через одно место, и понять почему — было невозможно. Где-то не работала капризная сетевая загрузка, или не передавались параметры по DHCP.

Поэтому, как-то естественным образом, все пришло к выводу, что проще купить бросовый неттоп, и поставить на него минимальный набор софта, чем заниматься угадайкой с непонятным железом, плюс еще за свой счет, потому что где и что не сработает — заранее неизвестно, но точно известно, что все должно было быть хорошо, и столько времени не отнимать.

С актуальностью статья немного запоздала. Если вернуться к той же желтой программе, то в последние годы платформа развилась, у нее появился собственный тонкий клиент, и актуальность ее развертывания в режиме удаленного рабочего стола уменьшилась.

Но есть и ряд других задач, где тихое и надежное рабочее место, подключенное по RDP, будет уместно. А в последние годы, стоимость мини-ПК настолько скакнула вниз, а стандартных компьютеров и неттопов вверх, что стало выгодней (стоимость железа, часа работы специалиста, плюс CAL/TCAL лицензии для Windows Server) строить именно такие решения.

Постановка задачи


Итак, нам требуется на базе Raspberry Pi развернуть тонкий клиент RDP, «прибить гвоздями» к конкретному серверу, плюс обеспечить переподключение при сбое.

Следует исключить всякую интеракцию пользователя с самим устройством. Соответственно, никакого локального рабочего стола и консольных команд. Пароль вводится только на сеанс RDP.

Как бонус, — организовать автомонтирование и проброс съемных USB-дисков.

Дано:

  • чистый Raspberry Pi 3 Model B 1Gb, или 4 Model B 1 Gb
  • адаптер питания 5v 2A,
  • кабель HDMI,
  • адаптер с HDMI на монитор (если в мониторе нет встроенного порта HDMI),
  • кабель Ethernet (либо наличие WiFi-сети),
  • карта памяти MicroSD на 8Гб или больше (объективно хватит и 4 Гб, но карту на 4 Гб, мне кажется, можно купить сейчас только в музее).
  • монитор, клавиатура, мышь для Raspberry.

На время установки — компьютер (ноутбук) с Windows или Linux, адаптер MicroSD-карт к нему.

Предполагается, что у читателя есть базовый навык администрирования Linux-систем, и вопрос «создать и отредактировать файл, скопипастить в него текст из этой статьи» или «подключиться по SSH» не вызовет сложностей. Однако, иногда позволю себе более глубокий экскурс, для тех, кто мог не встречаться конкретно с Raspbian.

Общая логика: настроить базовую систему, поставить клиент RDP, настроить автоматический вход, протестировать, устранить проблемы.

Будет также описано, как склонировать готовую сборку на другой Raspberry.

Программная компоновка сама по себе несложная, родилась в том или ином виде еще около 9 лет назад – как сейчас помню, делал под Debian Etch. С тех пор чуть менялась от версий софта и железа к версиям, и вот сейчас пришло время портировать ее на Raspberry.

Плановые затраты времени — примерно 30 минут.

1. Настройка базовой системы


1.1 Скачать образ системы


В качестве системы выберем Raspbian.

На момент написания статьи это можно сделать тут. Актуальная версия — Buster.

Выбрать Minimal Image Based on Debian Buster.



Скачать ZIP-архив, из которого достать единственный файл .img.



1.2 Записать его на флеш-карту


а) Под Windows

Скачать программу Rufus с официального сайта. Достаточно portable-версии.

Запустить программу, выбрать SD-карту и образ, выдернутый из архива в пункте 1.1.



Нажать кнопку «СТАРТ», подтвердить уничтожение данных на SD-карте, дождаться завершения процесса (примерно 5 минут).

Безопасно извлекаем карту.

б) под Linux

Выполнить команду:

# dd if=2019-09-26-raspbian-buster-lite.img of=/dev/<ваша SD-карта> bs=4M

Дождаться завершения процесса, выдернуть карту.

1.3 Развернуть систему на Rpi


Переставляем карту в целевое устройство. Соединяем мини-ПК с монитором, клавиатурой, мышью и подаем на него питание.

Через некоторое время, не задавая дополнительных вопросов, мини-ПК перезагрузится в свеже-развернутую систему, и пригласит ввести логин и пароль.
По-умолчанию это pi: raspberry.



1.4 Войти в систему и сменить пароль


# passwd pi

или

$ sudo passwd pi

(я намеренно запускаю passwd для пользователя pi под root-ом, чтобы Raspbian не изводил нас требованиями безопасности к паролю, а принял его и смирился)

Непосредственно зайти под root нельзя, если не задать ему явно пароль. В общем-то это и неплохо. Тогда все команды, которые должны быть исполнены под суперпользователем, следует выполнять из под пользователя pi с префикс-командой sudo. Как в Ubuntu.

Например (известная шутка, не запускайте!)

$ sudo rm -rf --no-preserve-root

Впрочем, поскольку я патологически ленив, то, залогинившись в Raspbian, или в тот же Ubuntu набираю:

$ sudo bash

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

Здесь и далее, если приведенные команды предварены #, то они должны быть исполнены под суперпользователем. Если с $, то под пользователем (обычно выше указано, под каким).

2. Установка необходимого ПО «на минималках», тестирование подключения


2.1 Настроить сеть


Для этого, запустить административную утилиту, выполнив команду:

# raspi-config



(Навигация осуществляется стрелками, табуляцией, Enter — выбор, ESC — возврат)
Перейти в Network Options.

Задать имя компьютера (пункт N1 Hostname), например TERM1.

Если компьютер подключен к сети кабелем Ethernet, и получает адрес DHCP, то больше ничего делать не нужно.

Если нужно настроить сеть WiFi, то делаем это (пункт N2 Wi-Fi). Выбираем свою страну. Имя сети придется ввести вручную, обзор не предусмотрен. Указываем пароль.

Затем Finish → Finish.

Перезагрузиться по запросу, или командой:

# reboot

После повторного входа убедиться, что есть доступ в Интернет.

# ping 8.8.8.8

2.2 Обновить систему


Обновим информацию о доступных пакетах.

# apt-get update

Теперь обновим систему (Необязательно, но крайне желательно. Можно сделать позднее.)

# apt-get upgrade

Этот этап может занять длительное время (у меня где-то 15 минут), т. к. обновляется бинарный загрузчик RPi, распаковывающий на SD-карту множество мелких файлов.
Обратите внимание, практически сразу после завершения загрузки и начала распаковки, какой-то мерзкий пакет будет просить нажать «q», остановив при этом процесс. Нужно будет нажать, прежде чем отвлечься на другие дела для ожидания.
По завершению обновления следует перезагрузиться

# reboot

2.3 Установить русскую локаль и раскладку


Снова в административную утилиту:

# raspi-config

Следуем в Localisation Options, там:

  1. Change Locale, снимаем * с en-GB.UTF-8 и устанавливаем напротив ru-RU.UTF-8. Подтверждаем, и в следующем окне выбираем ее же, как основную.
  2. Change Timezone, и выберите страну и город часового пояса.
  3. Change Keyboard Layout, там Generic 105-key (Intl) PCOtherRussianRussianControl+Shift (или Alt+Shift, по желанию, для переключения раскладки) → No temporary switcherRight Alt (AltGr)No compose key.

Подтвердить и выйти — FinishFinish.

Вышли из утилиты администрирования, запускаем команду:

# dpkg-reconfigure console-setup

выбрать UTF-8Guess optimal character setLet the system to select... (нижний пункт) → 8x16.

Шрифты после этого должны стать визуально тоньше, но главное — что они теперь поддерживают кириллицу.

Перезагружаемся, логинимся, тестируем английскую раскладку, переключение и русскую раскладку.

2.4 Определяемся со вспомогательным софтом и редактором


Для работы с файлами, навигации по структуре папок и редактирования файлов мне очень нравится Midnight Commander, поэтому:

# apt-get install mc

Запускаю его под root-правами, и при первом использовании редактора (клавиша F4 на какой-нибудь файл) выбираю mcedit (пункт 2).

Разумеется, Вы можете редактировать файлы средствами, выбранными на свое усмотрение. Например, используя nano, или даже VIM.

2.5 Устанавливаем сервер ssh


# apt-get install ssh

Редактируем /etc/ssh/sshd_config. Раскомментируем строку:

ListenAddress 0.0.0.0

Разблокируем автозагрузку

# systemctl enable ssh.service

Перезапустим службу

# systemctl restart ssh.service

Выясняем IP-адрес командой

# ifconfig

И теперь можем подключиться к устройству удаленно с исходного компьютера по SSH (под Windows мне лично нравится SSH-клиент PuTTY), чтобы выполнять настройку с удобного рабочего места и иметь возможность копипастить тексты с этой статьи в конфиги. Напоминаю, что логин — pi, а не root.



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

2.6 Вынесем волатильные разделы на виртуальные диски


Например, /tmp и /var/log, для того, чтобы:

  1. система не точила попусту sd-карту,
  2. было меньше шансов, что при аварийном отключении питания развалится корневая файловая система,
  3. чтобы в отдаленном будущем логи не забили свободное место на карте.

Для этого в /etc/fstab добавим строки:

tmpfs           /var/log        tmpfs   defaults,noatime,nosuid,mode=0755,size=100m    0 0
tmpfs           /tmp            tmpfs   defaults,noatime,nosuid,size=100m    0 0

Не забудьте поставить в конце файла перевод строки.

Здесь разделам /var/log и /tmp выделено по 100 мб памяти (она будет использоваться только по мере заполнения). Гигабайтному Pi, который используется только для RDP, эти траты совершенно ничем не помешают.

Перезагрузим систему, а затем выполним команду:

# df

и убедимся, что разделы смонтировались на tmpfs (3 и 4 колонки могут отличаться):

tmpfs             102400       8    102392   1% /tmp
tmpfs             102400     224    102176   1% /var/log

2.7 Заведем пользователя, под которым будем, впоследствии, автоматически запускать графическую оболочку


Выполним команду:

# adduser user

Зададим произвольный пароль. Всякие имена и телефоны можно пропустить. Подтвердить.

2.8 Установим X-server в минимальном исполнении


Выполним команду:

# apt-get install xserver-xorg xinit xterm x11-xserver-utils

Это может занять около 5 минут.

Теперь нужно сесть за физический терминал (в смысле, за монитор, клавиатуру и мышь, подключенные непосредственно к Pi), войти под пользователем user и запустить команду:

$ startx

На экране должна появиться примерно следующая картина, которая означает, что x-server успешно установлен, и можно двигаться дальше.



Наведем мышью на курсор (важно, т. к. окновода, формирующего рамки и заголовок окна нет, и окно просто не будет принимать текст без явного фокуса) и наберем

$ exit

чтобы вернуться обратно.

2.9 Установим софт для работы с удаленным рабочим столом


Мне лично нравится rdesktop. Он, конечно, не без нюансов (см. раздел «Извлечение граблей»). Есть и альтернативы типа xfreerdp, remmina и т. п., хотя жалуются и на них тоже.

Я приведу пример именно для первого.

# apt-get install rdesktop

Создадим скрипт, который запускал бы rdesktop на полный экран. В каталоге /home/user создадим файл runrdp (лучше под пользователем user):

#!/bin/bash
rdesktop <имя или IP целевого сервера> -u <имя пользователя для входа> -f -z

Если Вы выбрали другой клиент RDP, то напишите здесь командную строку для него, или воспользуйтесь массой дополнительных параметров, которые есть у rdesktop. Можно даже захардкодить пароль, чтобы вход осуществлялся автоматически.

На этот скрипт надо поставить права на запуск, а если вы его создавали под root, то владельца — user.

# chmod 755 /home/user/runrdp
# chown user:user /home/user/runrdp

Теперь зайдем в физической консоли под user, запустим startx, в открывшемся графическом терминале (см. рисунок выше) наберем:

$ ./runrdp

На экране должно отобразиться окно подключения к удаленному рабочему столу.



Если:

а) в консоли выводится что-то насчет ошибки CredSSP,
б) полноэкранный режим в FullHD оставляет темные закраины (как на рисунке-фото №4 в этой статье, правда там консольный режим, но закраины увидеть можно)
то см. раздел «Извлечение граблей».

А если все ОК, то отменяем вход в систему (Esc, или пункт меню «Отключить»), вываливаемся в x-терминал, набираем exit, возвращаемся в консоль.

3. Автоматизация поднятия сеансов


Если все предыдущие этапы получились, то пришло время все собрать в кучу.

Для этого сделаем так, чтобы при старте системы пользователь автоматически входил бы в терминал, запускал X-сервер и под ним подключался к RDP. Таким образом, пароль будет спрашиваться только для RDP-сессии, что избавит незрелые пользовательские умы от лишних навыков укрощения Linux.

3.1 Бесконечный RDP


Создадим скрипт, который бы, при запуске x-сервера, бесконечно пытался бы открыть RDP-сеанс.
Для этого, в каталоге /home/user создадим файл автозапуска при начале X-сессии .xinitrc, следующего содержания:
setxkbmap -option terminate:ctrl_alt_bksp # Завершение сеанса по Ctrl-Alt-BkSpace
setterm -blank 0 -cursor off # Отключим скринсейвер
xsetroot -solid gray # Установим серый фон подложки экрана
while /bin/true; do
	./runrdp
done

3.2 Бесконечный X-сервер


Исправим скрипт, который определяет автозапуск программ и настройку профиля при консольном входе так, чтобы x-сессия начиналась автоматически, но только при входе пользователя в 1-й терминал.

Спасибо пользователю gecube за напоминание о необходимости отключить скринсейвер. По-умолчанию, он представляет собой черный экран, что, для большинства современных мониторов, скорее вредно.


Отредактируем /home/user/.profile, дописав туда следующие строки:

…
if [ -z "$DISPLAY" ] && [ $(tty) = "/dev/tty1" ]; then
  startx
  clear
  echo "Ожидаем 5 секунд перед повторным соединением"
  sleep 5
  exit
fi

3.3 Промежуточно тестируем связку


Перезагружаем Pi, садимся за терминал, входим под пользователем user. Получаем на экране окно начала сессии, как на рисунке выше.

Пробуем отказаться от ввода пароля (esc, или зависит от версии Windows) – получаем то же окно начала сессии (т.е. наш скрипт из 3.1 постоянно пересоединяется).

Ждем около минуты (зависит от сервера) не трогая клавиатуру и мышь — окно начала сессии должно, вскоре, отключиться (RDP сеанс на стадии ввода пароля без активности истекает по таймауту). Оно, разумеется, из за п. 3.1, подключится вновь.

Теперь нажимаем Ctrl+Alt+BkSp. X-сессия должна прерваться, будет отображена надпись об ожидании 5 секунд, после чего консольная сессия завершится тоже. На экране появится приглашение входа в терминал с логином и паролем.

Если все так — превосходно.

Нам не хватает только автоматического входа в терминал.

3.4 Бесконечно вкусный апельсин повторяющийся автологин в tty1


Для этого из под root создадим файл /etc/systemd/system/getty@tty1.service.d/autologin.conf со следующим содержимым:

[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin user --noclear %I 38400 linux

Затем:

#systemctl enable getty@tty1.service	

Перезагружаемся, убеждаемся, что физическая консоль автоматически залогинилась под пользователем user, запустился X-сервер и открылась сессия RDP, и далее все как в 3.3.
Нажмем Ctrl+Alt+BkSp, дождемся переподключения.

Входим в систему, тестируем переключение, работу раскладок. Если что-то не так, см. раздел 4.

На этом настройка закончена.

Пользователи должны быть проинструктированы, что если что-то идет не так (экран погас, что-то зависло и т.п.), они, прежде всего, нажимают Ctrl+Alt+BkSp, и дожидаются реакции.

См. также раздел 5 про автомонтирование USB.

4. Извлечение граблей


Поскольку это OpenSource, извлечение граблей — отчаянный и непрерывный процесс. Я постараюсь обрисовать основные возможные грабли, но кто там знает, что нас ждет. Мне, вот, лично, никогда не везло, и ни одна инструкция для меня не работала без многочасового дополнительного поиска.

4.1 Проблемы с неполным использованием разрешения экрана


Симптомы: В случаях с некоторым оборудованием (HDMI-DSUB адаптеры, некоторые мониторы) raspbian не использует все доступное разрешение Full-HD монитора. Между значимой информацией и физическим краем экрана остаются темные поля.

Решается следующим образом:

Редактируем /boot/config.txt, находим строку

# disable_overscan = 1 

и раскомментируем ее.

Перезагружаемся.

Теперь темные поля с краев экрана должны убраться как в консольном, так и в графическом режимах.

4.2 Проблемы с курсором мыши при подключении rdesktop к современным серверам RDP


В основном это касается Windows 2012, 2016, Windows 10, где включена тема оформления курсора.

Симптомы: курсор исчезает, плохо прорисовывается, после переключения в нестандартный (песочные часы, символ I, стрелки уширения окон и т. п.) забывает переключиться в обычную стрелку.

Решение: Под пользователем сервера, к которому идет подключение, зайти через панель управления в свойства мыши, сбросить тему на «Нет» и отключить тени под указателем.



Курсоры должны придти к повиновению.

4.3. Проблемы с кодировками при работе rdesktop


Симптомы: в некоторых случаях, через подключение RDP, на удаленной системе неправильно набираются спецсимволы: тильды, слеши, кавычки, точки, вертикальные палки. Особенно начинают бесить точки, т. к. набираются часто.

Решение:

В /usr/share/rdesktop/keymaps создать файл raw и наполнить следующим содержимым:

include common
map 0x419
grave 0x29
asciicircum 0x07 shift
backslash 0x2b
bar 0x2b shift
apostrophe 0x28
greater 0x34 shift
less 0x33 shift

В командную строку запуска rdesktop в скрипте /home/user/runrdp добавить аргумент -k raw. Например:

rdesktop 10.0.0.1 -u user -k raw

Перезапустить сессию на терминале по Ctrl+Alt+BkSp или вообще перезагрузить Pi.

Войти в RDP, протестировать все спецсимволы, в т.ч. с Shift-ом на цифровом ряду клавиатуры и боковые клавиши слева и справа от буквенной секции, с Shift-ом и без (кавычки, двоеточия, знаки препинания, палки и т.п.). Все должно работать.

4.4. При попытке запустить rdesktop сеанс не открывается, в консоль выводится ошибка CredSSP


CredSSP: Initialize failed, do you have correct kerberos tgt initialized ?
Failed to connect, CredSSP required by server.

Целевая система требует современного алгоритма проверки подлинности клиента, чего rdesktop нормально не умеет.

Варианты решения:

  1. Отключить проверку подлинности на сервере, снизив настройки безопасности. В принципе, в тех средах, где Pi пытаются использовать в качестве клиента RDP, это не должно быть слишком большой проблемой безопасности.
  2. Воспользоваться другим клиентом, например freerdp, remmina, заменив содержимое скрипта runrdp на строку запуска этого клиента.
  3. Установить и настроить kerberos client, но, как-то все там сложно. Если желаете попробовать, начните отсюда.

4.5. Включение и выключение устройства


Raspberry Pi штатно не имеет кнопки выключения. Это плохо. Получается, что эффективного способа включать его и выключать — нет. Об этом много написано, попробую изложить кратко:

  1. С одной стороны, мы можем вообще не выключать устройство, выключая только монитор. Строго говоря, где я поставил RPi, все так и сделано. В общем-то устройство почти не греется, не потребляет электроэнергию, не шумит. Монитор, перед уходом, пользователь выключит.
  2. Можно настроить выключение на ночь по Cron-у, но тогда, чтобы утром включить RPi, пользователю придется передергивать провод, или блок питания.
  3. Решить этот вопрос можно, купив питающий USB-кабель с кнопкой размыкания (чтобы включить RPi нужно достаточно будет кратковременно разомкнуть цепь кнопкой). 120 рублей все удовольствие. Но здесь у пользователей сработает автоматика на выключение тем же способом, что для устройство будет аварийно. Учитывая, что мы вынесли волатильные разделы на tmpfs, наверное, маловероятно, что возникнут проблемы, но все таки никто не застрахован, что пользователь не войдет утром в систему из за краха rootfs. Не получилось, так сказать, решения «прибитого гвоздями».
  4. Есть решения с дополнительной кнопкой, включаемой в GPIO-порт, и включающей / выключающей устройство нежно (надлежащим способом). Но колхозить ее на корпус — это тратить часы и увеличивать себестоимость.
  5. Впрочем, для RPi даже есть корпуса со встроенной такой кнопкой (у китайцев вообще есть все). Но я лично еще не пробовал.
  6. Я думаю насчет включения устройства через разрыватель в USB-кабеле, а выключении его по горячей клавише (типа Ctrl+Alt+Shift+P), которая отслеживается системной службой, но руки проработать это решение никак не дойдут.

4.6 Множественные переподключения к серверу RDP


В текущей схеме, клиентское устройство подключится к серверу по протоколу RDP, отобразит окно ввода логина и пароля, и если пользователь не введет ничего, то, через какое-то время сеанс сбросится, и клиент RDP запустится снова, и так до бесконечности.

В комментариях пользователь Mnemonik сообщил, что при множественных постоянных переподключениях у Windows Server кончается память, и привел свой пример решения проблемы.

Я приведу свой. Изменим скрипт .xinitrc таким образом, чтобы после завершения работы очередного процесса rdesktop, на экран выводился модальный диалог, препятствующий повторному запуску до нажатия кнопки OK.

Для этого можно воспользоваться штатным xmessage, входящим в поставку xorg, но окна, создаваемые им, настолько уродливы, что у меня трескается монитор. Кроме того, с русским языком это приложение не дружит, а включить его — та еще задача.

Мне импонирует gxmessage, лишенный этого недостатка, но он тянет GTK и 25 мегабайт других зависимостей, что мне тоже не нравится. Ну ладно, давайте выберем меньшее зло:
apt-get install gxmessage

Изменим скрипт .xinitrc:
setxkbmap -option terminate:ctrl_alt_bksp # Завершение сеанса по Ctrl-Alt-BkSpace
setterm -blank 0 -cursor off # Отключим скринсейвер
xsetroot -solid gray # Установим серый фон подложки экрана
while /bin/true; do
	./runrdp
	gxmessage --center "Нажмите OK для повторного соединение с сервером RDP"
done

Теперь между попытками rdesktop соединиться с сервером, нам на экран будет выводиться соответствующее сообщение, и постоянной «бомбежки» сервера подключениями не будет.

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

4.7 Настройка NTP


Спасибо пользователю gecube за напоминание об этом моменте. Теоретически, время на устройстве может со временем «уплыть», что может вызвать сложности с аутентификацией, а может быть и другие проблемы.
Чтобы устранить эту маленькую проблему, следует установить программу ntpdate и прописать в cron задание на обновление времени каждый час (устройству потребуется доступ в интернет):

# apt-get install ntpdate
# echo "0 *     * * * root ntpdate pool.ntp.org" > /etc/cron.d/ntp

Если у вас в сети местный NTP-сервер, то замените имя узла на свое.

5 Опционально: подключение, отключение и проброс USB-устройств


Собственно, этот раздел включает в себя две ответственные стадии. Во-первых, наладить управление USB-устройствами, чтобы обеспечить их автоматическое монтирование и хоть насколько-то контролируемое пользователем размонтирование. А во-вторых, пробросить подключенные устройства в терминал, чтобы они были доступны по сети.

5.1. Наладка автомонтирования


Подключаемые USB-устройства с файловыми системами будем монтировать в подкаталоги каталога /media. Этот же каталог мы потом пробросим в rdesktop.

Нам потребуется пакет pmount.

# apt-get install pmount.

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

В /etc/udev/rules.d создаем файл 80-usbstick.rules со следующим содержимым:

ACTION=="add", KERNEL=="sd[a-z][0-9]", TAG+="systemd", ENV{SYSTEMD_WANTS}="usbstick-handler@%k"

Теперь создадим сервис для systemd.

В /lib/systemd/system создадим файл usbstick-handler@.service со следующим содержимым:

[Unit]
Description=Mount USB sticks
BindsTo=dev-%i.device
After=dev-%i.device

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/pmount --umask 000 --noatime -w --sync /dev/%i /media/%i
ExecStop=/usr/bin/pumount /dev/%i

В /usr/local/bin создадим файл unmount-devices со следующим содержимым:

#!/bin/bash
for folder in /media/*; do
    pumount $folder
    echo "Unmounted $folder"
done

Присвоим ему права на запуск.

#chmod 755 unmount-devices 

Добавим пользователя user в группу plugdev, чтобы он мог пользоваться этим скриптом (pumount разрешает членам этой группы монтировать и размонтировать устройства)

# adduser user plugdev

Перезагрузимся. Если все сделано правильно, то при вставке флешки в USB порт мини-ПК, через несколько секунд, в каталоге /media должна появляться папка sda1 и т.п, куда и будут смонтирована флешка на чтение-запись.

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

Протестируем этот момент (вставим флешку, выдернем флешку, после чего вставим устройство в ПК с Windows и исправим возможные ошибки).

Теперь вставим устройство в Pi снова, убедимся, что папка /media/sda1 опять появилась.
Запустим unmount-devices из под пользователя user. sda1 из /media должна пропасть, а устройство должно безопасно отмонтироваться, и не выдавать ошибку при вставке в ПК с Windows.

5.2 Пробросим каталог /media по RDP и обеспечим автоотмонтирование устройств


В /home/user/runrdp к командной строке rdesktop добавим дополнительный аргумент:

rdesktop …... -r disk:USB=/media/

Теперь отредактируем /home/user/.profile, добавив вызов unmount-devices.

...
if [ -z "$DISPLAY" ] && [ $(tty) = "/dev/tty1" ]; then
  startx
  clear
  unmount-devices
  echo "Ожидаем 5 секунд перед повторным соединением"
  sleep 5
  exit
fi

Перезагружаемся.

Теперь, если мы работаем в RDP-сеансе, и нам надо подключить к Pi USB-диск, мы просто вставляем его, и идем в Мой компьютер, где наблюдаем примерно следующую картину.



Мы можем свободно пользоваться этими устройствами, они будут появляться как папки (sda1-xx, sdb1-xx и т.п.)

Если нам надо извлечь устройство, достаточно нажать Ctrl+Alt+BkSp. Сеанс будет отключен (тем самым должно прерваться какое-либо копирование на устройство, даже если оно производилось), на консоли отобразится отмонтирование устройств (в этот момент все они безопасно извлекутся) и сообщение об ожидании 5 секунд перед повторным соединением с RDP.
Затем, после пересоединения, Вы сможете ввести пароль и продолжить работу с той же точки, но ранее подключенные устройства будут отмонтированы. В этот момент их можно физически извлечь.

На этом данный этап настройки завершен.

6. Клонируем систему на другой Rpi


6.А Если настроили самостоятельно


Если все грабли извлечены, устройство работает приемлемо, то можно распространить сборку на другие устройства. Если они однотипные, то нет никакой необходимости повторять процесс с нуля.
Вставим SD-карту (мне попалась 16-ти гигабайтная) в карт-адаптер, и поместим в USB-порт Raspberry.

Если вы уже настроили автомонтирование из последнего раздела, то запустим скрипт

# unmount-devices

дабы он отмонтировал только что подключенную SD-карту, которая, конечно же, сразу смонтировалась в /media/sdxx.

Теперь выполним команду lsblk и посмотрим на список устройств:

sda           8:0    1 14.6G  0 disk
└─sda1        8:1    1 14.6G  0 part
mmcblk0     179:0    0  7.4G  0 disk
├─mmcblk0p1 179:1    0  256M  0 part /boot
└─mmcblk0p2 179:2    0  7.2G  0 part /

sda это очевидно наша новая карта, а mmcblk0 – системная.
Выполним:

dd if=/dev/mmcblk0 of=/dev/sda bs=4M

и дождемся результата, который ожидается примерно через полчаса (для 8Гб карты).

После этого вставляем в другой Raspberry, меняем имя узла, имя пользователя в скрипте runrdp, и повторяем по необходимости.

6.Б Скачать готовый образ


Если, разумеется, Вы мне доверяете, можете воспользоваться образом, подготовленным мной, незначительно его перенастроив. Каких-либо закладок, средств телеметрии, и т.п. — я не добавлял, это не Windows 10, а я не Microsoft, и в экономическую перспективу скрытого майнинга биткойнов на RPi я тоже не верю.
Образ был составлен по инструкции, и утрамбован для использования на SD-карте минимальным размером 2 китайских (нечестных) Гб (1977614336 байт). Причем, заполненная часть образа вообще занимает первые 1966080000 байт, что должно влезть даже в самую китайскую SD-карту.

Для этого нужно:
1) Загрузить архив по ссылке (MD5: f7c87ce7b84e2fd7358da95b9baf406c) и распаковать файл образа.
2) Скопировать его на SD-карту, воспользовавшись, по аналогии, указаниями из пункта 1.2.
3) Загрузить систему, дождаться появления графического экрана и нажать Ctrl+Alt+F2 для перехода в консоль.
Войти под пользователем pi, пароль 111. Выполнить:

$ sudo bash

4) Выполнить действия пунктов 1.4, 2.1, убедиться, что интернет работает (командой ping, например).
5) Запустить raspi-config, зайти в Advanced Options, выбрать Expand Filesystem (чтобы расширить образ системы на все доступное на SD-карте место)
6) Отредактировать /home/user/runrdp, заменив имя узла «сервер» на имя или IP-адрес вашего сервера, а имя пользователя «user» на имя пользователя, под которым оператор должен подключаться к серверу.
7) Еще раз перезагрузиться и проверить работу.

Заключение


На этом все, спасибо за внимание. Надеюсь, данная информация будет кому-то полезна.
К сожалению, все охватить в одной статье крайне трудно. Если будет положительный фидбек, напишу, как с этой сборки удобно пробросить принтеры.

UPD 11/12/2019. Спасибо коллегам (gecube, Mnemonik, mkovalevskyi, SannX) за советы и правки. Внес изменения:
  • добавил команду отключения скринсейвера;
  • добавил настройку NTP;
  • касательно расхода памяти на сервере при множественных незаконченных подключениях RDP-клиентов — добавил в скрипт messagebox с паузой.

Кроме того, только что опробовал карту, вынутую из RPi3, вставив ее в свежераспакованный RPi4 Model B 1Gb. Все прекрасно работает без каких-либо исправлений. Соответственно, эта инструкция подходит и для RPi 4, и возможно подойдет и для других модификаций.

По такой радости, добавил загружаемый образ (см. раздел 6.Б), который можно скачать и склонировать, не выполняя всю инструкцию.

UPD 15/03/2020 — Перезалил ссылку на образ через Яндекс.Диск.
Теги:
Хабы:
+54
Комментарии84

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн