настраивал я всё это на ubuntu mate. Соответвенно качаем убунту мате и устанавливаем и обновляем
sudo apt update
sudo apt upgrade
sudo apt install rdesktop # Ubuntu / Debian
# sudo yum install rdesktop # Fedora / CentOS
sudo apt install xorg
потом сразу добавляем репозиторий в ubuntu
sudo -i (входим как root)
add-apt-repository ppa:ltsp
apt update
устанавливаем LTSP.
apt install --install-recommends ltsp ltsp-binaries dnsmasq nfs-kernel-server openssh-server squashfs-tools ethtool net-tools epoptes
gpasswd -a administrator epoptes
Конфигурация сети
ltsp dnsmasq
Создаем образ клиента в корне фс
ltsp image /
После того, как вы создадите образ создаем меню
ltsp ipxe
Чтобы настроить сервер LTSP для обслуживания образов или schroots через NFS, запустите:
ltsp nfs
Генерировать ltsp.img
ltsp initrd
Перезагружаем компьютер и у нас должна полноценно заработать сетевая загрузка.
для справки, если мы ставим дополнительный софт то чтобы он появился в нашем образе который грузим по сети требуется заново вводить эти пару команд по очереди ltsp image / и следом ltsp initrd и так каждый раз после дополнения софта.
Или Вот автоматическая установка делал на LUBUNTU, нужно создать файл install.sh сделать его исполняемым и запустить с полными правами. В данном случае установится атоматически rdesktop и примитивная графическая оболочка к нему, а также кучка некоторых утилиток. если требуется использовать свои адреса RDP, отредактируйте файл перед установкой. Данная установка создаст действующий образ системы со свсеми программами который у вас установлены, чтобы не переделывать образ повторно установите сразу требуемый софт.
#!/bin/bash
# Проверяем права суперпользователя
if [[ $(id -u) != 0 ]]; then
echo "Ошибка: Необходимо запустить скрипт с правами суперпользователя."
exit 1
fi
# Обновляем систему и устанавливаем rdesktop
echo "Обновление системы и установка rdesktop..."
apt-get update && apt-get install rdesktop -y
# Добавляем репозиторий LTSP
echo "Добавляем репозиторий LTSP..."
apt install software-properties-common -y
add-apt-repository ppa:ltsp/ppa -y
# Обновляем список пакетов
echo "Обновляем пакетный менеджер..."
apt-get update
# Проверка наличия X.Org Server
XORG_INSTALLED=$(dpkg -l | grep "^ii.*xserver-xorg-core")
if [[ -z "$XORG_INSTALLED" ]]; then
# Минимальная установка X.Org Server
echo "X.Org Server не установлен. Устанавливаем минимально необходимую версию..."
apt-get install xorg -y
else
echo "X.Org Server уже установлен."
fi
# Установка SSH-сервера и Midnight Commander отдельно
echo "Установка SSH-сервера..."
apt-get install ssh -y
echo "Установка Midnight Commander..."
apt-get install mc -y
# Установка компонентов LTSP
echo "Установка необходимых пакетов LTSP..."
apt-get install --install-recommends ltsp ltsp-binaries dnsmasq nfs-kernel-server squashfs-tools ethtool net-tools epoptes -y
# Установка библиотеки Python для графического интерфейса (Tkinter)
echo "Установка библиотек Python для графического интерфейса..."
apt-get install python3-tk -y
# Функция проверки статуса последней выполненной команды
check_status() {
if [[ $? -ne 0 ]]; then
echo "Ошибка при выполнении операции: $*"
exit 1
fi
}
# Пункт №6: Усовершенствование ввода имени пользователя
echo "Добавляем пользователя в группу epoptes..."
read -rp "Введите имя вашего пользователя (или нажмите Enter для текущего пользователя): " USERNAME
USERNAME=${USERNAME:-$(whoami)} # Используем текущее имя пользователя, если ввод пуст
gpasswd -a "$USERNAME" epoptes
check_status "Добавление пользователя в группу epoptes"
#echo "Добавляем пользователя в группу root..."
#sudo usermod -aG root "$USER"
# Пункт №2: Создание Python-скрипта для RDP подключения
echo "Создание скрипта для графического окна RDP..."
cat << EOF > /usr/local/bin/rdp_login.py
import threading
import time
# RDP Script Version: 1.0
import os
import json
import subprocess
from tkinter import *
# Определение пути к файлу настроек относительно домашнего каталога
SETTINGS_FILE = os.path.expanduser("~/.rdp_settings.json")
DEFAULT_SERVERS = ["Server1", "Server2", "192.168.1.3"] # Список серверов по умолчанию
FULLSCREEN_OPTION = "-f" # Опция полноэкранного режима
IGNORE_CERTIFICATE_OPTION = "-P" # Игнорировать сертификаты безопасности
# Имя лог-файла в домашнем каталоге
LOG_FILE_PATH = os.path.expanduser("~/rdp_connection.log")
class RDPCredentialsWindow(Tk):
def __init__(self):
super().__init__()
# Название окна с указанием версии
self.title("RDP Connection Manager v1.0")
# Получаем размеры экрана
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
# Новые размеры окна
window_width = 500
window_height = 450
# Рассчитываем координаты центра экрана
x_position = int((screen_width / 2) - (window_width / 2))
y_position = int((screen_height / 2) - (window_height / 2))
# Задаем новое положение окна
self.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")
# Перехват события закрытия окна (WM_DELETE_WINDOW)
self.protocol("WM_DELETE_WINDOW", self.on_closing)
# Пользовательские переменные
self.default_server_var = StringVar(self)
self.entry_value = StringVar(self)
self.fullscreen_check = BooleanVar(value=True)
self.ignore_cert_check = BooleanVar(value=True)
self.auto_connect_at_startup = BooleanVar(value=False)
# Загружаем настройки из файла SETTINGS_FILE
self.load_settings()
# Основной контент окна
content_frame = Frame(self)
content_frame.pack(expand=True, fill='both', padx=10, pady=10)
# Компоненты интерфейса
label = Label(content_frame, text="Choose or enter a server:", font=("Arial", 12))
label.pack(pady=(10, 5))
dropdown = OptionMenu(content_frame, self.default_server_var, *DEFAULT_SERVERS, command=self.save_settings)
dropdown.pack(pady=5)
entry_label = Label(content_frame, text="Enter custom server address:", font=("Arial", 12))
entry_label.pack(pady=5)
entry_field = Entry(content_frame, textvariable=self.entry_value, width=30)
entry_field.pack(pady=5)
fullscreen_checkbox = Checkbutton(content_frame, text="Open connection in Full Screen mode",
variable=self.fullscreen_check,
onvalue=True, offvalue=False,
command=self.save_settings)
fullscreen_checkbox.pack(pady=5)
ignore_cert_checkbox = Checkbutton(content_frame, text="Ignore certificate errors",
variable=self.ignore_cert_check,
onvalue=True, offvalue=False,
command=self.save_settings)
ignore_cert_checkbox.pack(pady=5)
auto_connect_checkbox = Checkbutton(content_frame, text="Auto Connect at Startup",
variable=self.auto_connect_at_startup,
onvalue=True, offvalue=False,
command=self.save_settings)
auto_connect_checkbox.pack(pady=5)
connect_button = Button(content_frame, text="Connect", command=lambda: threading.Thread(target=self.manual_connect).start())
connect_button.pack(pady=10)
# Виджет для отображения ошибок с возможностью копирования
error_frame = Frame(content_frame)
error_frame.pack(fill=BOTH, expand=True)
scrollbar = Scrollbar(error_frame)
scrollbar.pack(side=RIGHT, fill=Y)
self.error_text = Text(error_frame, height=8, wrap=WORD, yscrollcommand=scrollbar.set)
self.error_text.pack(fill=BOTH, expand=True)
scrollbar.config(command=self.error_text.yview)
# Создаем контекстное меню для копирования текста
self.create_context_menu()
# Автоподключение при старте, если установлен флажок
if self.auto_connect_at_startup.get():
self.after(1000, lambda: threading.Thread(target=self.connect_to_server).start()) # Задержка 1 секунда
def create_context_menu(self):
"""Создает контекстное меню для копирования текста из поля ошибок."""
self.context_menu = Menu(self.error_text, tearoff=0)
self.context_menu.add_command(label="Copy", command=self.copy_selected_text)
self.error_text.bind("<Button-3>", self.show_context_menu)
def copy_selected_text(self):
"""Копирует выделенный текст в буфер обмена."""
selected_text = self.error_text.selection_get()
self.clipboard_clear()
self.clipboard_append(selected_text)
def show_context_menu(self, event):
"""Показывает контекстное меню при щелчке правой кнопкой мыши."""
self.context_menu.post(event.x_root, event.y_root)
def manual_connect(self):
"""Инициирует подключение вручную (при нажатии кнопки)."""
# Сбрасываем автоматическое подключение
self.auto_connect_at_startup.set(False)
self.connect_to_server()
def on_closing(self):
pass # Закрывать окно нельзя
def load_settings(self):
"""Загрузка предыдущих настроек."""
if os.path.exists(SETTINGS_FILE):
with open(SETTINGS_FILE, 'r') as file:
self.settings = json.load(file)
else:
self.settings = {}
# Читаем сохраненный сервер и применяем его
default_server = self.settings.get('default_server')
if default_server is not None:
self.default_server_var.set(default_server)
# Установка значений настроек
self.fullscreen_check.set(self.settings.get('fullscreen', True))
self.ignore_cert_check.set(self.settings.get('ignore_certificate', True))
self.auto_connect_at_startup.set(self.settings.get('auto_connect', False))
def save_settings(self, *_):
"""Сохраняет текущие настройки в файл."""
settings_data = {
'fullscreen': self.fullscreen_check.get(),
'ignore_certificate': self.ignore_cert_check.get(),
'auto_connect': self.auto_connect_at_startup.get(),
'default_server': self.default_server_var.get()
}
with open(SETTINGS_FILE, 'w') as file:
json.dump(settings_data, file)
def clear_error_message(self):
"""Очищает область ошибок."""
self.error_text.delete(1.0, END)
def log_and_show_error(self, error_msg):
"""Логирует ошибку в файл и показывает её в GUI."""
# Запись ошибки в лог-файл
with open(LOG_FILE_PATH, 'a') as log_file:
log_file.write(f"{error_msg}\n")
# Отображение ошибки в интерфейсе
self.clear_error_message()
self.error_text.insert(END, error_msg)
def connect_to_server(self):
"""Инициирует подключение к указанному серверу."""
# Первым делом смотрим на поле ввода
server_address = self.entry_value.get().strip()
# Если поле ввода пустое, берем сервер из выпадающего списка
if not server_address:
server_address = self.default_server_var.get()
# Печать команды для диагностики
print(f"Forming connection command for server: {server_address}")
options = []
if self.fullscreen_check.get():
options.append(FULLSCREEN_OPTION)
if self.ignore_cert_check.get():
options.append(IGNORE_CERTIFICATE_OPTION)
command = ['rdesktop'] + options + [server_address]
# Печать полной команды
print(f"Executing command: {' '.join(command)}")
try:
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output, _ = proc.communicate()
# Показываем вывод команды в случае успеха или ошибки
if proc.returncode != 0:
raise RuntimeError(output.decode())
else:
print(f"Connection successful to {server_address}. Output:\n{output.decode()}")
except Exception as e:
error_message = f"Error connecting to {server_address}: {e}"
self.log_and_show_error(error_message)
if __name__ == "__main__":
app = RDPCredentialsWindow()
app.mainloop()
EOF
chmod +x /usr/local/bin/rdp_login.py
check_status "Создание скрипта rdp_login.py"
# Пункт №3: Автозапуск скрипта при загрузке системы
echo "Настройка автозапуска..."
cat << EOF > /etc/xdg/autostart/autorun-rdp.desktop
[Desktop Entry]
Type=Application
Name=RDP Login Window
Exec=/usr/bin/python3 /usr/local/bin/rdp_login.py
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Terminal=false
EOF
chown root:root /etc/xdg/autostart/autorun-rdp.desktop
chmod 644 /etc/xdg/autostart/autorun-rdp.desktop
check_status "Настройка автозапуска"
# Конфигурируем DNSMasq
echo "Настраиваем DNSMasq..."
ltsp dnsmasq
check_status "Конфигурация DNSMasq"
# Создание образа клиента
echo "Создание образа клиента..."
ltsp image /
check_status "Создание образа клиента"
# Генерируем меню IPXE
echo "Генерация меню IPXE..."
ltsp ipxe
check_status "Генерация меню IPXE"
# Настроить NFS-сервер
echo "Настройка NFS-сервера..."
ltsp nfs
check_status "Настройка NFS-сервера"
# Генерация начального ramdisk
echo "Генерация начального ramdisk..."
ltsp initrd
check_status "Генерация начального ramdisk"
# Пункт №8: Предоставляем возможность выбора перед перезагрузкой
read -n1 -r -p "Для завершения конфигурации потребуется перезагрузка. Продолжить? (Y/y/N/n): " ANSWER
case $ANSWER in
[Yy]* ) # Если введена Y или y
echo "Перезагружаемся..."
reboot
;;
*) # Все остальные случаи (N/n или любое другое значение)
echo "Перезагрузка отменена. Завершите конфигурацию самостоятельно."
;;
esac



Поиск
Друзья
Администрация