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

С ростом популярности мини-ПК типа 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: 0B5033A9CA12BA8299340BC482111998) и распаковать файл образа.
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) Еще раз перезагрузиться и проверить работу.

Заключение


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

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

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

По такой радости, добавил загружаемый образ (см. раздел 6.Б), который можно скачать и склонировать, не выполняя всю инструкцию.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 81

    +4
    1. rdesktop фактически мёртв, почему он, а не xfreerdp?
    2. Как всё это поддерживать и обновлять?
      Мне кажется, лучше было положить на флешку ядро и минимальный initramfs, а корень монтировать по сети.
      +1
      Да, Вы правы. Rdesktop откровенно стар, просто я с ним давно, и знаю его грабли.
      Если надо заменить на другой — в принципе, меняем раздел 2.9 на другой софт:
      apt-get install freerdp-x11

      и содержимое скрипта runrdp будет чуть другое — вызываем не rdesktop а xfreerdp, с другими параметрами.
      Я больше хотел донести до аудитории автоматику переподключения.

      Касательно сетевого развертывания — тоже хороший вопрос. Я когда-то пытался идти именно по такому пути (плюс даже сетевой загрузки ядра), еще лет 10 тому назад (не с rpi, разумеется). Это требует дополнительной инфраструктуры — надо донастроить DHCP-сервер, развернуть сетевой корень, и т.п. Все это периодически сбоит и сношает мозг.
      А еще клиенты-неттопы докупаются по несколько штук в разное время, у них разные видеодрова (особенно досаждали патченные интеловские, которые вытесняли ванильные), и общий корень им заходит плохо.
      Поэтому я пришел к такой схеме, как наиболее экономически целесообразной, и дешевой как для меня, так и для заказчиков.

      А еще представляете, насколько бы выросла статья, если сюда воткнуть нюансы сетевой загрузки? Я чего-то и так переборщил.

      Что касается обновлять и сопровождать (воровато озираюсь), то, я сейчас, конечно, посягаю на догму, но зачем обновлять и что там сопровождать?
      Из порядка 50 станций (опять таки не на RPi, я про прошлые годы), которые ставил лично я, либо склонированные сисадминами у клиентов из моих образов, ни к одной не потребовалось возвращаться. Из них уже 70% выведены из эксплуатации по причине отпадания необходимости, а на некоторых из тех, что выжили, до сих пор Debian etch и lenny.

      Если надо менять логин и узел подключения часто, наверное, разумным компромиссом было бы в скрипте runrdp подставлять эти параметры, выдергивая их dhclient-ом по DHCP.
        +3
        А у нас малина собрана на Yocto, U-Boot и dtb на флешке, остальное грузится по tftp и работает из памяти. Системный образ с freerdp около 16Мб весит. Обновлять просто.
          0
          А сколько клиентов всего используется? Одна организация?
            0
            Одна, сотни тонких клиентов.
              0
              … и, наверное, однотипное железо.
              Идеальный вариант как раз для сетевого развертывания, все значимо упрощает.

              В последние годы время у меня была выборка примерно из десятка организаций по 3-10 разношерстных железяк разных лет, плюс сисадмины штатные — 1 чел на организацию, ребята после вуза, за 20 тыс/мес. Провинция ж…
              Они — птички, им это сложно. Не вложить в них такие знания, которые требует кучи смежных технологий. Поэтому приходится лепить вот так…
                +1
                А я вот тратил время и силы на вкладывание знаний… Всего несколько человек поддались, но зато расширил кол-во грамотных коллег вокруг.
      +3
      Почему малина а не дешевые аналоги(апельсинка и т.д.)?
        0
        К моменту, когда меня пригласили, заказчиком куплены были уже именно такие.
        В принципе, сама автоматика не привязана к архитектуре, статья подойдет и для Orange. Экономически, естественно, лучше ваши варианты.

        На днях хочу себе заказать апельсинку для опытов, но пока в стадии выбора модели.
        Мне (для другой задачи) нужна SATA на PCI-E, а на ту модель Orange, где это есть, люди жалуются.
          +4
          Orange Pi PC или PC2 — выброшенные попусту деньги.
          Не покупайте. Драйверов нет, ОС нет. Ничего нет. Тогда уж посоветую Rock64.
          А по теме тонкого клиента — где-то я такое уже видел, а вот: www.ncomputing.com
          Тонкие клиенты из RPI3.
            +2
            Там у них всё серьезно. Форк freerdp с отрисовкой через правильное место, fbturbo патченый, свои плагины к gstreamer. В итоге, RDP работает практически идеально, ничего не тормозит и MMR FHD контент воспроизводит. Только денюшку надо им занести.
              +2
              Есть их ранние поделки — это мрак… может с этим все поменялось.
                0
                Ранние их поделки вообще на FPGA(причем довольно старых) были, а там вариантов построить себе турбограбли гораздо больше.
                0
                Если денюшку заносить, то можно уже и wtware использовать
                  0
                  Да что вы привязались к этому wtware, он даже видео не умеет редиректить. И в целом на малине куда хуже работает, чем ncomputing. Заказали рекламу чтоли?
                    +1
                    видео редиректить манагерам в офисе надо далеко не всем, а по качеству, удобству и стоимости (а старые версии вообще бесплатны) — вообще альтернатив не вижу.
                      0

                      А что умеет редиректить видео, подскажите, пожалуйста?

                  0
                  Драйверов нет, ОС нет. Ничего нет.

                  opi pc и иже с ними, с памятейкой >=1gb уже давным-давно (года эдак два) юзабельны, а в armbian, штатно и вполне сносно с ними работающей,
                  по крайней мере запись логов в zram работает из коробки.

                    +1
                    Ну насколько юзабельны?
                    Аппаратное декодирование видео есть? Нет.
                    GPU Mali поддерживается? Только через танцы с бубном.
                  +2
                  Разочарую. Не подойдёт. Я пробовал сделать клиент RDesktop на базе апельсинки. Даже видео снял. Увы, тормозит со страшной силой — даже звук нормально не пробрасывается, хрипит. Делал на базе готового образа Lubuntu.
                  Если вспомню, куда заливал видео, дам пруф.
                  +1
                  Малинка истоптана сообществом вдоль и поперек, а вот у остальных есть периодические проблемы с поддержкой. Если делать, чтобы было просто и с минимумом заморочек (автор даже кнопку питания не стал выводить) малинка лучший вариант.
                  +3
                  Почему бы не запускать xfreerdp через systemd явно передавая пользователя?
                  Что-то типа следующих шагов:
                  1. Отдельный пользователь с минимальными правами
                  2. Настройка сети/дисков через systemd-target
                  3. Автологин для tty
                  4. systemd-user-unit для автостарта RDP-клиента.
                  5. systemd-user-unit для сервисов монтирования дисков/звука/etc

                  Возможно сделать отдельный target для старта системы для доступа к tty под другим пользователем.
                    0
                    Хм. Наверное потому, что с момента, как я эту автоматику сделал, в голове так и остался sysvinit. Плюс еще я не сисадмин, по сути, а так, дилетант, знающий много что горизонтально, но не в деталях, и в systemd особенно не вникал.

                    Вообще, Ваш план выглядит заманчиво и технологично, но это целая новая статья.
                      +2

                      Идеально, да!

                      0
                      Если лень, есть wtware.ru winterminal.com — не бесплатно).
                        0
                        Для RPi вроде бесплатно wtware. Это для ПК (сетевых карт) уже нужна лицензия.
                          0
                          Стала платной год или два года назад.
                            +1

                            Последняя версия, работающая без лицензии на RPi — 5.6.24. Там есть, правда, проблемка с NLA, поэтому мы используем 5.6.22. Но в этих версиях, вроде, Pi3 и старше не поддерживаются.

                          +1
                          Закатал на флешку дистрибутив Бубунты с LTSP сервером. С неё (зашифрованной)грузится сервер,16ГБ достаточно. 5 компьютеров дешевых моноблоков с вынутыми винчестерами. Грузятся по PXE. На рабочих столах Remmina. Профит.Минимум танцев с бубном.
                            +2

                            Сделали так же с разницей в том что наши клиенты грузились по PXE по сети, в них не было дисков вообще. Один образ не всех, tmpfs под каталог пользователя на старте. Но написать я хотел не про это. Написать я хотел про то, что делал я колл-центр, в котором компьютеры просто «стояли» если за ними не сидели операторы. То есть стояла такая себе комната в 40 всегда включённых станций и сменные операторы приходили-уходили, иногда их было 10 (ночью) иногда 40. Так вот «вечный» рдп, переподключающийся к логину после тайм-аута без ввода пользователя-пароля (каждую минуту) с сорока компьютеров клал сервер за два дня. у ссаной винды просто вытекала память от бесконечных подключений к логину по сорок раз в минуту. слов приличных нет это охарактеризовать. пришлось сделать бинарник показывающий .bmp на весь экран и выходящий по нажатию любой кнопки, и сунуть его в тот же цикл что и xfreerdp, перед ним. получилось даже корпоративненько, если на .bmp влепить лого организации.

                              0
                              Спасибо за этот момент, внес исправления в статью.
                              0
                              А зачем весь этот геморрой, если есть WTWare?
                                0

                                Например чтобы меньше потратить денег?

                                  0
                                  Разработчик WTWare ничем не ограничивает функционал пробной версии и никого не принуждает к покупке лицензии — у меня уже пятый год в школе целый компьютерный класс крутится с надписью «только для тестирования». А так, были бы средства — купил бы лицензии обязательно, как сказано ниже, прекрасная оперативная техподдержка на форуме и прочие приятности избавляют от описанного в данной статье геморроя :-)
                                  +2
                                  Стоимость лицензии по максималке 1000 рублей за лицензию, если 10 и более, то цена капитально снижается, вменяемая техподдержка и толковый форум. Думаю, это стоит затрат. И да, я делал малинку с WtWare, работает очень даже недурственно.
                                  0
                                  иксы можно выбросить, freerdp умеет напрямую работать с фреймбуфером
                                    0
                                    Не факт, что это ускорит freerdp. Возможно даже замедлит.
                                    Дело в том, что графические изображения бывают двух типов: bitmap и pixmap. К битмапам процессор имеет непосредственный доступ, так как они в системной памяти. В вот пиксмап — это объект графического контроллера. Процессор к нему не имеет прямого быстрого доступа, но зато графический контроллер имеет очень быстрый доступ.
                                    x11 freerdp оперирует тайлами — плитками 64x64. При создании такой плитки в freerdp создается pixmap — объект GPU. Эти пиксмапы закачиваются в память GPU один раз при создании, но потом могут быть многократно переиспользованы при рендеренге десктопа.
                                    То есть таскаешь окно по экрану — а изображение бэкгроунда уже в памяти GPU в виде пиксмапов.
                                    Можете конечно возразить, что у распбери нет такого деления на память CPU и память GPU, но увы — там так же как и в настоящих компютерах есть деление. Причем CPU писать в память GPU очень не быстро и не просто.
                                      0
                                      Два года назад текущая версия не умела, разработчики писали что-то типа если вам надо, то исправляйте — код открыт.
                                      github.com/FreeRDP/FreeRDP/issues/3866#issuecomment-286352842
                                      +3

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


                                      1. Клонировать образ — плохо. Лучше сделать сразу нужный базовый образ. Я уж не говорю, что айдишники машинки при клонировании не меняются, что потом не позволяет эффективно пользоваться ssh с проверкой подлинности хоста.
                                      2. Для локалей там в дистрибутиве все сломано. Проверьте locale -a после своих действий. Если все ок, то поздравляю — по умолчанию при настройке через штатный настройщик распберри там дичь.
                                      3. Пробовали для удаленной настройки vnc? По крайней мере для киосков это сильно удобнее, чем подключаться по ссш
                                      4. Ntp настраивали? Если нет, то очень плохо. И, да, из коробки его вроде нет
                                      5. Скринсейвер не отключали? Как-то пропустил этот момент
                                        +1
                                        Касательно 1, согласен, но, ИМХО, в большинстве случаев можно пренебречь.
                                        2. Все получилось нормально, хотя я в это не верил. Где-то полгода назад у меня тоже были проблемы с локалью, я даже отказывался от руссификации вообще. Сейчас все прошло гладко.
                                        3. Я не очень знаю, как прикрутить VNC таким образом, чтобы позволял администрировать и консоль и видеть иксы, в одном сеансе. Если подскажете, буду признателен.
                                        4, 5. Спасибо за напоминание. Учел в статье.
                                        с NTP все просто
                                        # apt-get install ntpdate
                                        # echo "0 *     * * * root ntpdate pool.ntp.org" > /etc/cron.d/ntp
                                        

                                          0
                                          1. И консоль, и иксы? Я тоже не знаю ) можес обсудить идеи. Vnc устанавливал через raspi-config.
                                            Ntp — а чего не systemd-timesyncd или как он там называется? Только нужно учесть, что дата-время должны быть хотя бы раз установлены верные, иначе оно не стекается из-за большой разницы (это просто гениально(((()
                                            0
                                            Бгг, вчера тестировал, ntpdate спокойно с 01 января 2019 перевел на актуальную.

                                            Про фокус с расхождением я уже даже успел забыть, именно из за него раньше использовал ntpdate, по крайней мере, вместо ntpd.
                                              +3
                                              Утилиты синхронизации времени используют системный вызов adjtime, позволяющий выставить время более точно, но имеющий ограничение на размер delta. Для ntpdate можно выбрать метод корректировки времени при помощи параметров командной строки:
                                              -b
                                              Force the time to be stepped using the settimeofday() system call, rather than slewed (default) using the adjtime() system call. This option should be used when called from a startup file at boot time.
                                            0

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

                                            0
                                            В бытность использовал thinstation с загрузкой по pxe. Смущало неудобство управления… конфиги вручную править под станции. Потом был ponix. Тоже pxe. уже с интерфейсом управления конфигами станций. Потом был wtware с image over http. Да, локальная загрузка это конечно хорошо, но если подключение к rdp не работает без наличия сети, загрузочный образ в 1 мб можно стянуть по той же сети и есть удобство централизованного управления то зачем бубны ради бубна?
                                              +2
                                              Да, это хороший подход, когда оборудование однородное и проверенное, экземпляров много, а сам работаешь в штате. Я тоже такое поднимал. Особенно мне нравится получение параметров через DHCP, когда, фактически, из конфига DHCP сервера можно было в одном месте поменять хосты и пользователей.

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

                                              Я что только не перебрал в поиске хорошего универсального решения, включая thinstation и др. У них реально плохо с универсальностью, а мне еще в вопросах opensource-сборок патологически не везет: они не заводятся, заводятся но глючат, плюются уникальнейшими логами, которые не гуглятся, и вообще хамски себя ведут. А я еще и не профильный сисадмин, к тому же.

                                              Вокруг тех же 2010-х все эти сборки у меня поднимались только с устаревшим железом, на которое были дрова, а в 11-15 годах вообще пошли неттопы с невнятными intel-овскими видеокартами, дрова к которым приходилось скачивать непонятно где, и компилировать вместо штатных (кстати их 64-битных версий не было даже под Windows, а уж какой трешак под линукс издали — пошатнешься)

                                              Либо подходили штатные, но не с последней версии дистрибутива. Чуть ли не каждому устройству приходилось лично кланяться, чтобы заставить работать. Усложнить это все еще загрузкой через сеть, и потратить время на генерацию компактных образов? Привязать разные образы к мак-адресам? Централизованно управлять аж 5-ю станциями?? Пффф, дешевле было купить флешку на 4 Гб, воткнуть толстый линукс с тонким клиентом туда и примотать скотчем.

                                              С однородными и предсказуемыми RPi, конечно, экономический предел сетевого развертывания будет выше, но я, как-то, по инерции не подумал.
                                              +1
                                              Коллеги, спасибо за отзывы и советы, доработал статью с учетом. Также добавил образ готовой настроенной сборки для загрузки (см. раздел 6.Б).
                                                +3
                                                Использовали еще первые версии малинки для данной цели — работают до сих пор. Не слишком парились по поводу выноса часто записываемых разделов. При настройке использовали такой проект rpitc.blogspot.com а также базовый образ.
                                                • UFO just landed and posted this here
                                                    +1
                                                    dd if=/dev/sda of=/dev/sdb bs=32M
                                                    Только не на том сервере, на котором надо было, а на том, на котором подсматривал конфиги, войдя, по привычке, тоже под root-ом. Запутался в SSH-сеансах, RDP-окнах и еще мозг ели по телефону, а хосты назывались одинаково.

                                                    Это из личного опыта. В принципе, страшного ничего не случилось. Почти.

                                                    Да и не научило ничему… Как совали голым, так и будем © анекдот
                                                    • UFO just landed and posted this here
                                                        +1
                                                        Ну, в данном случае предполагается, что я должен был работать под рутом на настраиваемом оборудовании, а под обычным пользователем (не применяя sudo, кроме как вычитать недоступные конфиги) на эталонном. Символы доллара и решетки будут напоминать, откуда и куда пихать, да и деструктивная команда не запустится.
                                                        Это неплохая схема.

                                                        А так, если sudo использовать всегда, то, ИМХО, это все равно, что всегда использовать рут.
                                                        • UFO just landed and posted this here
                                                            +1

                                                            Под рутом сидеть нехорошо, потому что по ошибке можно нагородить дел. С судо тоже можно, но вероятность чуть снижается. Как в перчатках работать: вроде, неудобно, но без них опасность выше. Однако это же рекомендация: если нужно много чего настроить, то можно и sudo -i сказать. Главное, чтобы в привычку не вошло.


                                                            Кроме того, часто подразумевается, что не стоит логиниться под рутом. Руту вообще полезно иметь звёздочку вместо пароля — чтобы исключить вход под ним в систему вообще.

                                                            • UFO just landed and posted this here
                                                                0

                                                                потому что с sudo, например, ты потом не забудешь случайно отключить вход под рутом (например, удаленно). Задач, которые в принципе требовали ВХОД рута — по сути-то и нет. Все можно через эскалацию привилегий сделать.

                                                                • UFO just landed and posted this here
                                                              –1
                                                              Что-то вы сами с собой разговариваете.

                                                              Гм, перечитал, да, так и получилось. Чего-то я устал, похоже, за день. Мысли — скакуны, а бумага двумерна, так сложно выразить все понятно и системно.

                                                              Давайте сформулирую мысль так.
                                                              1. Я тоже не понимаю этот тезис неоэнтерпрайзистов насчет постоянной работы под sudo, и чем оно более безопасно — мне неизвестно. Прежде всего, безопасно от кого/чего?
                                                              2. Но то, что постоянно не надо работать под root-контекстом без прямой необходимости — мне понятно, даже на личном опыте, пример из которого я привел.
                                                              3. Это также можно скрестить с бесспорно полезными указаниями по безопасности не разрешать прямой вход в SSH под рутом. А большинство серверов админятся таки по SSH.
                                                              4. Из чего я для себя сделал вывод, что оптимально так: когда мне нужен root — я должен работать под рутовским шеллом, а когда не нужен, работать под обычным юзером.
                                                              5. Для достижения оного с учетом п. 3, заходить можно под юзером, а sudo bash, когда надо повыситься надолго, вполне себе вариант. Где надо, я повышусь, где нет — останусь под юзером.
                                                              6. Все равно я так не делаю. Жизнь ничему не научила. Работаю везде под рутом. SSH под рутом открываю в реальный интернет. На что я рассчитываю? А, ладно. Вся страна такая.
                                                              • UFO just landed and posted this here
                                                                  0
                                                                  Запрет рута по ssh — такая же лажа.

                                                                  почему? Это только лишь одно из средств защиты. А вся защита — это комплекс мер. Как Вы правильно говорите — впн, белые списки и все прочее. А еще — да, запрет входа па паролю и только по сертификатам (чтоб брутить было сложнее )))))

                                                                  0

                                                                  Ну, например, смотрите. Простой аргумент — когда у вас вход под рутом и пароль знают более двух человек, то как определить какой из них заходил (и, например, накосячил)? sudo В ЯВНОМ виде оставляет следы КТО повышал свои привилегии. Да, вы можете возразить, что в auth.log можно увидеть ключ того, кто вошел под рутом… но такое себе...

                                                          0

                                                          так на тру сайтах только так и пишут: вот вам сто команд, запускать только под sudo, а то сразу от рута небезопасно :(
                                                          это как рекомендации для винды не работать под админом, суть та же. только мы ж не работаем, а настраиваем)

                                                          +4
                                                          Отпишусь про свой велосипед.
                                                          1) xfreerdp, скомпиленный из github, в стандартных репозиториях старая версия без поддержки rfx/gfx и кодеков сжатия.
                                                          2) В скрипте, перед подключением к серверу проверяется связь с сервером, и через dialog выводится сообщение, о том что нет связи или кабеля.
                                                          rdp.sh
                                                          #!/bin/sh
                                                          
                                                          SERVER=ts01
                                                          
                                                          	#magic!
                                                          	#The first expression removes XVESA= and everything before. The second one removes the next space and everything after.
                                                          	res=$(cat /proc/cmdline | sed -e 's/^.*XVESA=//' -e 's/ .*$//')
                                                          	#should be now like 1280x1024x16
                                                          	res=$(xdpyinfo |grep dimension |awk '/dimensions/{print $2}')
                                                          	
                                                          	SCR_X=$(echo $res |awk -F'[x]' '{print $1}')
                                                          	SCR_Y=$(echo $res |awk -F'[x]' '{print $2}')
                                                          
                                                          PROGRAM=xfreerdp
                                                          
                                                          PARAMS="/cert-ignore -sec-nla /smartcard:A /multimedia:sys:alsa /w:$SCR_X /h:$SCR_Y +fonts /d: /u: /bpp:32"
                                                          
                                                          while true; do
                                                              $PROGRAM $PARAMS /v:$SERVER >> /tmp/rdp.log 2>&1
                                                          
                                                          DATA=$(date +%F-%H-%M)
                                                          
                                                          if eval "sudo ping -c 2 $SERVER"
                                                                  then
                                                                      echo "$DATA | TERMSRV OK"
                                                                  else
                                                                  echo "$DATA | TERMSRV no connect, testing linkup"
                                                          
                                                                  ifconfig |grep "UP BROADCAST RUNNING" 
                                                          
                                                                  if [ $? != 1 ]
                                                                  then
                                                                          echo "$DATA | TERMSRV no connected,run dialog">>/tmp/log-testc0nn
                                                                          dialog --title "PING ERROR" --pause "Нет связи с сервером $SERVER"  22 70 10
                                                                  else
                                                                          echo "$DATA | Linkup testing pass, cable not connected">>/tmp/log-testc0nn
                                                                          dialog --title "NO CABLE" --pause "Сетевой кабель не подключен!"  22 70 10
                                                                  fi
                                                                  clear
                                                          fi
                                                          
                                                          done


                                                          3) Далее подглядел у втваре функционал вывода информации при наведении мышки в нижний правый угол.
                                                          mouse.sh
                                                          #!/bin/sh
                                                          
                                                          while true; do
                                                          #	eval $(xdotool getmouselocation --shell)
                                                          #	echo X=$X   Y=$Y
                                                          
                                                          	#magic!
                                                          	#The first expression removes XVESA= and everything before. The second one removes the next space and everything after.
                                                          	res=$(cat /proc/cmdline | sed -e 's/^.*XVESA=//' -e 's/ .*$//')
                                                          	#should be now like 1280x1024x16
                                                          	res=$(xdpyinfo |grep dimension |awk '/dimensions/{print $2}')
                                                          	
                                                          	SCR_X=$(echo $res |awk -F'[x]' '{print $1}')
                                                          	SCR_Y=$(echo $res |awk -F'[x]' '{print $2}')
                                                          	
                                                          	X=$(xdotool getmouselocation| awk -F'[: ]' '{print $2}')
                                                          	Y=$(xdotool getmouselocation| awk -F'[: ]' '{print $4}')
                                                          
                                                          	dx=$(( $SCR_X - $X))
                                                          	dy=$(( $SCR_Y - $Y))
                                                          	echo screen $SCR_X x $SCR_Y mouse: $X $Y diff $dx $dy
                                                          
                                                              if [ $dx -lt 10 ] && [ $dy -lt 10 ]
                                                              then
                                                                  echo rrrr
                                                                  conky -c /opt/conkyrc &
                                                                  P=$!
                                                                  echo $P
                                                                  sleep 10
                                                                  kill $P
                                                              else
                                                                  sleep 1
                                                              fi
                                                          done


                                                          conkyrc
                                                          double_buffer yes
                                                          alignment bottom_right
                                                          background no
                                                          border_width 1
                                                          cpu_avg_samples 2
                                                          default_color white
                                                          default_outline_color white
                                                          default_shade_color white
                                                          draw_borders no
                                                          draw_graph_borders yes
                                                          draw_outline no
                                                          draw_shades no
                                                          use_xft yes
                                                          xftfont DejaVu Sans Mono:size=12
                                                          gap_x 5
                                                          gap_y 5
                                                          minimum_size 5 5
                                                          net_avg_samples 2
                                                          no_buffers yes
                                                          out_to_console no
                                                          out_to_stderr no
                                                          extra_newline no
                                                          own_window yes
                                                          own_window_class Conky
                                                          #own_window_type desktop
                                                          own_window_type normal
                                                          own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
                                                          #own_window_transparent yes
                                                          stippled_borders 0
                                                          update_interval 10.0
                                                          uppercase no
                                                          use_spacer none
                                                          show_graph_scale no
                                                          show_graph_range no

                                                          TEXT
                                                          $nodename
                                                          ${color grey}Uptime: $uptime
                                                          Address:$color ${addr eth0} ${color grey}
                                                          #Wi-Fi:$color ${addr eth0} ${color grey}
                                                          ${exec grep -v "^#" /opt/rdp.sh |grep SERVER=}


                                                          4) ещё на клиентах запускается vnc для техподдержки, тк использовать виндовые оснастки помощи юзеру это боль. В параметрах запуска vnc ещё можно указать запуск xeye, чтобы пользователь видел, что за ним подглядывают.
                                                          .xsession
                                                          x11vnc -forever >/dev/null &
                                                          /opt/mouse.sh > /dev/null 2>&1 &
                                                          aterm -geometry 218x72 -bg black -fg grey -e /opt/rdp.sh

                                                            +1
                                                            x11vnc -forever >/dev/null &

                                                            не надо так запускать. Никогда. Хотите нормально? Либо через настройки графической среды (lightdm), либо через отдельный юнит файл для vnc (по крайней мере сразу сможете мониторить его состояние и не перезапускать целиком все, если он сдохнет — мы же в 2019....)

                                                              0
                                                              Если честно, не до конца понял, чем мне поможет отдельный юнит файл.
                                                              В оригинале, кстати, было так
                                                              x11vnc -forever -afteraccept "xeyes -geometry 100x50+1820+1000 -distance &" -gone "pkill xeyes" >/dev/null &

                                                              Запускается из пользователя, перезапускается вместе с иксами по ctrl+alt+backspace.
                                                              Пароль на внц не стоит осознанно, поэтому не указан конфиг.
                                                              В моей конфигурации вообще не было никакого графического менеджера.
                                                              И вообще была вот такая крамола:
                                                              .bashrc
                                                              if [ $(tty) == "/dev/tty1" ]; then
                                                                  python /home/pi/card_monitor.py &
                                                                  while true; do startx ; echo "Again [$?]..."; done
                                                              fi
                                                               


                                                              card_monitor.py
                                                              #!/usr/bin/env python
                                                              
                                                              from __future__ import print_function
                                                              import os.path
                                                              from time import sleep
                                                              
                                                              from smartcard.CardMonitoring import CardMonitor, CardObserver
                                                              from smartcard.util import toHexString
                                                              
                                                              
                                                              
                                                              # a simple card observer that prints inserted/removed cards
                                                              class PrintObserver(CardObserver):
                                                              	"""A simple card observer that is notified
                                                              	when cards are inserted/removed from the system and
                                                              	prints the list of cards
                                                              	"""
                                                              	def update(self, observable, actions):
                                                              		(addedcards, removedcards) = actions
                                                              		for card in addedcards:
                                                              			print("+Inserted: ", toHexString(card.atr))
                                                              		for card in removedcards:
                                                              			print("-Removed:  ", toHexString(card.atr))
                                                              			if os.path.isfile("/boot/sc_removed.sh"):
                                                              				os.system("/boot/sc_removed.sh")
                                                              
                                                              if __name__ == '__main__':
                                                              	print("Insert or remove a smartcard in the system.")
                                                              	print("")
                                                              	cardmonitor = CardMonitor()
                                                              	cardobserver = PrintObserver()
                                                              	cardmonitor.addObserver(cardobserver)
                                                              	while 1:
                                                              		sleep(60)
                                                              
                                                              	# don't forget to remove observer, or the
                                                              	# monitor will poll forever...
                                                              	cardmonitor.deleteObserver(cardobserver)


                                                              sc_removed.sh
                                                              /boot/sc_removed.sh
                                                              #!/bin/bash
                                                              
                                                              killall xfreerdp

                                                                0

                                                                Как минимум тем, что не нужно делать & (запуск в фоне). Пускай менеджер служб этим заведует.
                                                                Не говорю уже о том, что можно строить цепочки — нет сети — vnc не стартует и не пытается жрать лишние ресурсы. Плюс логирование, мониторинг и пр. пр. пр.
                                                                Я уж не говорю о когнитивной нагрузке — при прочих равных ковыряться в чужих баш-скриптах времен SysV init гораздо более противно, чем в юнит файлах. Да, сложность при этом никуда не девается — она переносится на другой уровень. Но это и позволяет делать более интересные и надежныен штуки.

                                                                  +1
                                                                  Ну это если есть менеджер служб, часть скриптов использовалась на TinyCoreLinux, а там вообще вся система инициализации в одной bash-портянке.
                                                            +1
                                                            Неужели никак не докрутить до монтирования файловой системы в read-only, а всего изменяемого — в tmpfs? Тогда и выключать можно как хочешь и когда хочешь.
                                                              +1
                                                              Почему не докрутить — даже, кажется, штатно в армбиане есть — overlayroot называется.
                                                              Хуже, если надо синхронизировать изменения обратно — у меня, когда экспериментировал с pine64, не вышло перемонтировать r/o раздел в r/w из скрипта (только из консоли). Ну и штатного механизма синхронизации, кажется, так и нет.
                                                              +4

                                                              Читал статью и плакал. Автор — в начале увлекательного пути, и потому спешу поделиться одним важным моментом, который нужно всегда иметь в виду, занимаясь "терминализацией" и тонкими клиентами. Тем более, когда используются открытые решения.


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


                                                              QoS: CBWFQ/LLQ и Shaping — наше все. Без контроля сетевого трафика невозможно добиться нормальной работы удаленного доступа. Ведь при этом еще остается трафик печати, IP-телефонии и обычного файлового гонялы. Неприятно, когда бухгалтер в RDP сессии с "желтой программой" получит тыкву из-за того, что секретарь в такой же RDP сессии отчаянно листает PDF-ы с отсканированными договорами.


                                                              В любом случае, спасибо автору за минуты ностальгии и еще раз – удачи и успехов!

                                                                0

                                                                Вопрос, а Вы как-то при этом мониторите качество RDP-сессий?

                                                                  0

                                                                  Обязательно да: по стонам в раскаленный телефон, пешеходам с криками "все тормозит!" и заявкам в HelpDesk.


                                                                  А если серьезно, то сейчас практически уже нет. По общей нагрузке на канал принимаем оперативное решение по «прижиманию» не-RDP трафика, перенаправлению оного на альтернативный (он же резервный) канал и т.п.


                                                                  По опыту могу сказать, что в 1-Мбитный настроенный канал легко помещаются 20+ RDP-сессий без проблем. Заторы начинаются, когда все пользователи одновременно начинают рассматривать себя на фотографиях с очередного корпоратива. "Справедливая очередь" начинает хором их дропать, но почему-то в такие "кризисные" моменты понимание происходящего у пользователей возрастает на порядок.

                                                                    0

                                                                    У нас главная жалоба — даже не тормоза, а "разрывы" (ДЦ далеко, канал вроде бы стабильный, но...) и происходит это не постоянно, а наплывами.
                                                                    Хочется научиться мерять именно разрывы сессий и хранить их где-то в исторических данных, хотя бы и в виде графика Zabbix и потом искать корреляцию (она не связана или не всегда связана с загрузкой канала)

                                                                      0
                                                                      Штатные логи не помогут?
                                                                      log_name Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
                                                                      event_id 25
                                                                      message Службы удаленных рабочих столов: Успешное переподключение сеанса:
                                                                        0

                                                                        Хорошая попытка, но нет =)


                                                                        По переподключениям точно не стоит мерить, потеряем тех, кто не переподключился.


                                                                        Хотел смотреть по разрывам (event_id 40), но там нет вполне логичной причины "session timeout"

                                                                          0
                                                                          Может через Haproxy завернуть, и смотреть там логи?
                                                                        0

                                                                        Разрывы и наплывами? Перегруз по каналу. 90%

                                                                          0

                                                                          image


                                                                          Всмысле, хотелось бы это видеть на графиках

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

                                                                        Временно переподключайте их по черному списку на 8 битную глубину цвета.
                                                                        Чертежи смотреть хватит, 1с тоже работать будет, а эстетического удовольствия от просмотра фото не получится (злодейский хохот).
                                                                    +1
                                                                    Есть рожденный сумрачным германским гением проект openthinclient.org.
                                                                    Вот он очень похож на эталон систем управления тонкими клиентами.
                                                                    Он даже у меня проработал полгода. Но они потом очень сильно переделали дистрибутив, и так как я не настоящий линуксоид, мне поднять его под Hyper-V не удалось.
                                                                    К тому-же у Мелкософта произошло очередное обострение безопасности, и XfreeRDP перестал коннектиться к фермам RDP.
                                                                    Работало это на HP-шных тонких клиентах. Причем добрые НР-шники тоже раздают софт для управления тонкими клиентами, но выпиливают поддержку старого оборудования. Хотя сами железяки могли бы еще работать и работать.
                                                                    Так что, если у кого-то хватит задора приручить эту штуку и научить других — почет и уважуха.
                                                                      0
                                                                      Если Вы планируете далее продавать свое решение, то Вам необходимо будет «упаковать» все в виде законченного продукта, например вот так https://habr.com/ru/post/476686/
                                                                      Так же в новых версиях raspberry cm3 используется eMMC память вместо SD. С SD картами у пользователей raspberry бывают проблемы.

                                                                      Only users with full accounts can post comments. Log in, please.