Удаленная установка операционной системы без KVM over IP

в 12:40, , рубрики: arduino, java, системное администрирование, удаленное администрирование

Бывало ли у вас так: вас нет на работе, операционная система у сотрудника слетела и средства удаленного администрирования, которые так вас выручали, становятся бесполезными. Или вы пытаетесь объяснить по телефону, какой пункт меню BIOS отвечает за приоритет загрузки, а собеседник совсем не владеет английским, и разговор превращается для обоих в пытку.

Есть много способов решения проблемы: тот же KVM over IP (относительно дорого), разделение разделов с системой и данными с последующим стиранием раздела системы в случае сбоя, загрузочные носители с Live дистрибутивом для временной работы, PXE-сервер и т.д.

Я предлагаю еще один способ — собрать устройство, наподобие KVM over IP (передающее нажатия клавиш и изображение по сети) своими руками.

image

Закупка

Нам понадобится:

  • Плата видеозахвата. В моем случае AVerTV Game Broadcaster HD. Она поддерживает D-SUB, HDMI, DVI (через переходник на HDMI)
  • Arduinu совместимая плата с возможностью эмуляции клавиатуры. Я использую клон Arduino Leonardo, но это не единственная плата с такой возможностью.

Плата видеозахвата оказалась low profile и мне удалось уместить ее в соответствующий корпус Exegate MI-213. Тут я продешевил. После пары месяцев работы в блоке питания сломался вентилятор, который оказался нестандартным (8х8, но узкий), и его заказ из Китая сопоставим с ценой всего корпуса. С другой стороны корпус мне понравился тем, что в него влезла ATX-материнка (с 4-слотами). В общем решайте сами. Для моих целей корпус вполне подошел. И после небольшой работы болгаркой, мне удалось впихнуть стандартный вентилятор 8x8 с небольшими потерями товарного вида корпуса.

image

Программная часть

Всё достаточно просто: подлючаем «агрегат» вместо монитора и контролируем компьютер с помощью Arduino Leonardo, притворяющегося клавиатурой.

Реализация пока сыровата, но вполне работоспособна.
Есть желание написать программу, которая будет взаимодействовать с WDM-драйвером, но пока захват выполняется стандартной утилитой AVerTV. Она может настраивать разрешение захвата, в отличии от VLC и других плееров, которые тоже получают картинку, но на минимальном разрешении.

К сожалению кроссплатформенность упирается в отсутствие драйверов под Linux. Есть какие-то драйвера, но после отправки письма выяснилось, что они продаются только для корпоративных клиентов.

Код для отправки нажатий клавиш написан на Java, использует кросплатформенную библиотеку JSSC и представляет из себя почти прозрачную форму, которая открывается поверх утилиты, получающей видеопоток.

public class MyKVM extends JFrame {
 private static SerialPort serialPort;
 private static int c = 0;

 public static void createGUI() {
  JFrame frame = new JFrame("Test frame");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  JTextArea inputText;
  JTextArea feedbackText;
  inputText = new JTextArea();
  feedbackText = new JTextArea();
  inputText.addKeyListener(new KeyListener()
        {
              @Override
              public void keyPressed(KeyEvent e)
              {
                  feedbackText.append("Key Pressed: " + e.getKeyCode() + "n");
                  try {
                      switch (e.getKeyCode())
                      {
                        case 65: c = 61; break;
...
 << много разных варианотов >>>
...
           	    };
                    serialPort.writeByte((byte)c);
                  }
                  catch (SerialPortException ex) {
                    System.out.println(ex);
                  };
              }

          JScrollPane scrollText = new JScrollPane(feedbackText);
          frame.getContentPane().add(inputText);
          frame.getContentPane().add(feedbackText);
          frame.add(inputText, BorderLayout.NORTH);
          frame.add(scrollText, BorderLayout.CENTER);
          frame.setPreferredSize(new Dimension(250, 230));
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);

          AWTUtilities.setWindowOpacity(frame, 0.2f);
     }

     public static void main(String[] args) {
              String[] portNames = SerialPortList.getPortNames();
               for(int i = 0; i < portNames.length; i++){
                   System.out.println(portNames[i]);
               }
               serialPort = new SerialPort("COM4");
               try {
                   //Открываем порт
                   serialPort.openPort();
                   //Выставляем параметры
                   serialPort.setParams(SerialPort.BAUDRATE_57600,
                                        SerialPort.DATABITS_8,
                                        SerialPort.STOPBITS_1,
                                        SerialPort.PARITY_NONE);
                   serialPort.writeString("1");
               }
               catch (SerialPortException ex) {
                   System.out.println(ex);
               }

              EventQueue.invokeLater(new Runnable() {

               public void run() {
                    JFrame.setDefaultLookAndFeelDecorated(true);
                    createGUI();
               }
          });
     }
}

Файл MyKVM.java целиком.

Код для Arduino пока достаточно прост. Надо что-то придумать насчет обработки клавиши Shift, но пока, нижнего регистра мне хватает, хотя может возникнуть ситуация, когда понадобится ввести пароль и без верхнего регистра не обойтись.

int incomingByte = 0;

void setup(){ 
  Serial1.begin(57600);
  Serial.begin(57600);
  Keyboard.begin();
}

void loop()
{

    while (Serial1.available()) {
      if (Serial1.available() > 0) {
              // read the incoming byte:
              incomingByte = Serial1.read();             
              switch (incomingByte){
                case 37: Keyboard.write(216); break;
                case 39: Keyboard.write(215); break;
                case 38: Keyboard.write(218); break;
                case 40: Keyboard.write(217); break;
                case 27: Keyboard.write(177); break;
                case 18: Keyboard.write(18); break;
                case 112: Keyboard.write(194); break;
                case 113: Keyboard.write(195); break;
                case 114: Keyboard.write(196); break;
                case 115: Keyboard.write(197); break;
                case 116: Keyboard.write(198); break;
                case 117: Keyboard.write(199); break;
                case 118: Keyboard.write(200); break;
                case 119: Keyboard.write(201); break;
                case 120: Keyboard.write(202); break;
                case 121: Keyboard.write(203); break;
                case 122: Keyboard.write(204); break;
                case 123: Keyboard.write(205); break;
                
                default: Keyboard.write(incomingByte);
              }
      }
    }
}

Железячная часть

Я использовал USB ->Serial переходник, т.к. писал код для Arduino на ноутбуке (именно поэтому в коде открыватеся COM4). Ни что не мешает в финальной версии подключиться к порту, распаянному на материнской плате или к пинам на ней же.

Очень интересный эффект наблюдается, если подключить RX и TX контакты без «земли». Видимо наводки на USB превращаются в ложные пакеты и получается что-то в стиле Halt and catch fire (кстати, очень классный сериал). Компьютер обрабатывает лавинообразный поток нажатий клавиатуры, и вывести его из этого состояния можно только перезагрузкой. Само собой эффект не наблюдается, когда USB и последовательный порт (переходник) являются частью одного компьютера, т.к. «земля» у них общая.

Я припаял USB ->Serial переходник прямо к Arduino. Не обращайте внимания на цвет проводов, они нарощены. Мне повезло, китайцы не перепутали цвета, и в моем переходнике «земля» была желтой. TX-красным, RX-коричневым. Не забудьте, что к плате RX и TX соединяются наоборот. В современных материнках последовательный порт распаивают редко, хотя выводы на самой плате обычно есть. Пока экспериментируете лучше использовать переходник.

Выводы

Железка собиралась just for fun. Не судите строго. Скорее всего вам не зачем собирать подобный велосипед, если вы не уверены на 100%, что он вам нужен.

Автор: tlx

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js