install.sh
· 18 KiB · Bash
Originalformat
#!/bin/bash
set -e
# Цвета для вывода
ANSI_RED := $(shell tput -Txterm setaf 1)
ANSI_GREEN := $(shell tput -Txterm setaf 2)
ANSI_YELLOW := $(shell tput -Txterm setaf 3)
ANSI_RESET := $(shell tput -Txterm sgr0)
# ==================== ФУНКЦИИ ====================
# Проверка прав root
check_root() {
if [ "$EUID" -ne 0 ]; then
echo -e "${ANSI_RED}Ошибка: скрипт должен запускаться от root${ANSI_RESET}"
exit 1
fi
}
# Запрос имени хоста
ask_hostname() {
local current_hostname=$(hostname)
read -e -p "${ANSI_YELLOW}Введите имя хоста: (текущее: $current_hostname) ${ANSI_RESET}" -i "${current_hostname}" NEW_HOSTNAME
echo "$NEW_HOSTNAME"
}
# Запрос имени пользователя
ask_username() {
echo -e "${ANSI_YELLOW}Введите имя нового пользователя:${ANSI_RESET}"
read -p "Username: " NEW_USER
if [ -z "$NEW_USER" ]; then
echo -e "${ANSI_RED}Имя пользователя не может быть пустым.${ANSI_RESET}"
exit 1
fi
echo "$NEW_USER"
}
# Запрос пароля
ask_password() {
local username=$1
echo -e "${ANSI_YELLOW}Введите пароль для пользователя $username:${ANSI_RESET}"
read -s -p "Password: " USER_PASS
echo
if [ -z "$USER_PASS" ]; then
echo -e "${ANSI_RED}Пароль не может быть пустым.${ANSI_RESET}"
exit 1
fi
echo "$USER_PASS"
}
# Запрос настройки прокси
ask_proxy() {
echo -e "\n${ANSI_YELLOW}Использовать прокси-сервер apt-cacher-ng? (y/n):${ANSI_RESET}"
read -p "Use proxy? " USE_PROXY
if [[ "$USE_PROXY" =~ ^[Yy]$ ]]; then
echo -e "${ANSI_YELLOW}Введите URL прокси-сервера (например: http://192.168.1.100:3142):${ANSI_RESET}"
read -p "Proxy URL: " PROXY_URL
if [ -n "$PROXY_URL" ]; then
configure_proxy "$PROXY_URL"
else
echo -e "${ANSI_RED}URL прокси не введен, пропускаем${ANSI_RESET}"
fi
fi
}
# Настройка прокси для apt
configure_proxy() {
local proxy_url=$1
echo -e "${ANSI_GREEN}Настройка прокси для apt...${ANSI_RESET}"
cat > /etc/apt/apt.conf.d/02aptproxy << EOF
Acquire::http::proxy "$proxy_url";
Acquire::ftp::proxy "$proxy_url";
EOF
echo -e "${ANSI_GREEN}Прокси настроен в /etc/apt/apt.conf.d/02aptproxy${ANSI_RESET}"
}
# Установка имени хоста
set_hostname() {
local hostname=$1
echo -e "\n${ANSI_GREEN}=== Установка имени хоста: $hostname ===${ANSI_RESET}"
hostnamectl set-hostname "$hostname"
if grep -q "^127.0.1.1" /etc/hosts; then
sed -i "s/^127.0.1.1.*/127.0.1.1\t$hostname/" /etc/hosts
else
echo "127.0.1.1\t$hostname" >> /etc/hosts
fi
echo -e "${ANSI_GREEN}Имя хоста установлено.${ANSI_RESET}"
}
# Добавление репозитория MEPHI
add_mephi_repository() {
. /etc/os-release 2>/dev/null || { echo "Failed to determine release"; exit 1; }
[ -z "$VERSION_CODENAME" ] && echo "VERSION_CODENAME not found" && exit 1
local conf_file="/etc/apt/sources.list.d/debian_mephi.list"
if grep -qs "mirror.mephi.ru.*$VERSION_CODENAME" "$conf_file" 2>/dev/null; then
echo -e "Repository for $VERSION_CODENAME already exists in $conf_file"
else
echo -e "Adding repository for Debian $VERSION_CODENAME"
cat >> "$conf_file" << EOF
# Added $(date '+%Y-%m-%d')
deb http://mirror.mephi.ru/debian/ $VERSION_CODENAME main non-free-firmware
deb-src http://mirror.mephi.ru/debian/ $VERSION_CODENAME main non-free-firmware
EOF
echo "Repository added, updating package list..."
apt update
fi
}
# Обновление системы
update_system() {
echo -e "${ANSI_GREEN}=== Обновление системы ===${ANSI_RESET}"
apt update
apt -y upgrade
}
# Установка пакетов
install_packages() {
local packages=(
pv nano curl wget sudo lsb-release iptables
unzip pigz zstd
ncdu gdu
screen tmux lynx
htop btop iftop mtr ioping
git jq yq pwgen
bind9-dnsutils net-tools ssh-audit
cloud-guest-utils qemu-guest-agent
console-setup
)
echo -e "${ANSI_GREEN}Installing packages...${ANSI_RESET}"
apt-get update
apt-get install -y "${packages[@]}"
}
# Настройка SSH
configure_ssh() {
echo -e "${ANSI_GREEN}Allowing SSH root login${ANSI_RESET}"
sed -i 's/^.*PermitRootLogin.*$/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart sshd
echo -e "${ANSI_GREEN}Ok.${ANSI_RESET}"
}
# Настройка таймзоны и локали
configure_locale() {
echo "tzdata tzdata/Areas select Europe" | debconf-set-selections
echo "tzdata tzdata/Zones/Europe select Moscow" | debconf-set-selections
DEBIAN_FRONTEND=noninteractive dpkg-reconfigure tzdata
cat > /etc/locale.gen << EOF
ru_RU.UTF-8 UTF-8
en_US.UTF-8 UTF-8
EOF
locale-gen
update-locale LANG=en_US.UTF-8
locale -a | grep -E "en_US|ru_RU"
source /etc/default/locale
dpkg-reconfigure console-setup
dpkg-reconfigure keyboard-configuration
}
# Настройка journald
configure_journald() {
mkdir -p /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/size.conf << EOF
[Journal]
SystemMaxUse=1G
SystemMaxFileSize=50M
MaxLevelStore=warning
EOF
systemctl restart systemd-journald
}
# Создание пользователя
create_user() {
local username=$1
local password=$2
useradd -m "$username" && echo "$username:$password" | chpasswd && passwd -e "$username"
usermod -aG sudo "$username"
touch "/home/$username/.Xauthority"
chown "$username:$username" "/home/$username/.Xauthority"
echo -e "${ANSI_GREEN}Пользователь $username с паролем '${ANSI_YELLOW}$password${ANSI_GREEN}' создан${ANSI_RESET}"
}
# Настройка истории для пользователя
configure_user_history() {
local username=$1
cat >> "/home/$username/.bashrc" << 'EOF'
export HISTSIZE=10000
export HISTFILESIZE=50000
export HISTTIMEFORMAT="%F %T "
export HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
export TERM=xterm-256color
EOF
chown "$username:$username" "/home/$username/.bashrc"
}
# Настройка истории для root
configure_root_history() {
cat >> /root/.bashrc << 'EOF'
export HISTSIZE=10000
export HISTFILESIZE=50000
export HISTTIMEFORMAT="%F %T "
export HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
export TERM=xterm-256color
EOF
source /root/.bashrc
}
# Очистка документации git
clean_git_docs() {
rm -rf /usr/share/doc/git/RelNotes
}
# Финальное сообщение
finish_setup() {
echo -e "${ANSI_GREEN}=== Настройка завершена ===${ANSI_RESET}"
}
# Запись конфигурационного файла
write_config_file() {
local file_path=$1
local create_backup=${2:-true} # создать резервную копию? (по умолчанию true)
echo -e "${ANSI_GREEN}=== Запись конфигурации в $file_path ===${ANSI_RESET}"
# Создание резервной копии
if [ "$create_backup" = true ] && [ -f "$file_path" ]; then
local backup_path="${file_path}.backup.$(date +%Y%m%d_%H%M%S)"
cp "$file_path" "$backup_path"
echo -e "${ANSI_YELLOW}Создана резервная копия: $backup_path${ANSI_RESET}"
fi
# Создание директории, если её нет
local dir_path=$(dirname "$file_path")
if [ ! -d "$dir_path" ]; then
mkdir -p "$dir_path"
echo -e "${ANSI_YELLOW}Создана директория: $dir_path${ANSI_RESET}"
fi
# Чтение содержимого из heredoc
cat > "$file_path"
# Установка правильных прав (опционально)
chmod 644 "$file_path"
echo -e "${ANSI_GREEN}Файл успешно записан: $file_path${ANSI_RESET}"
}
make_motd_generator() {
write_config_file "/etc/update-motd.d/99-mymotd-generator" false << 'EOF'
#!/bin/bash
# Text Color Variables http://misc.flogisoft.com/bash/tip_colors_and_formatting
tcLtG="\033[00;37m" # LIGHT GRAY
tcDkG="\033[01;30m" # DARK GRAY
tcLtR="\033[01;31m" # LIGHT RED
tcLtGRN="\033[01;32m" # LIGHT GREEN
tcLtBL="\033[01;34m" # LIGHT BLUE
tcLtP="\033[01;35m" # LIGHT PURPLE
tcLtC="\033[01;36m" # LIGHT CYAN
tcW="\033[01;37m" # WHITE
tcRESET="\033[0m"
tcORANGE="\033[38;5;209m"
# Time of day
HOUR=$(date +"%H")
if [ $HOUR -lt 12 -a $HOUR -ge 0 ]; then TIME="morning"
elif [ $HOUR -lt 17 -a $HOUR -ge 12 ]; then TIME="afternoon"
else TIME="evening"
fi
# System uptime
uptime=`cat /proc/uptime | cut -f1 -d.`
upDays=$((uptime/60/60/24))
upHours=$((uptime/60/60%24))
upMins=$((uptime/60%60))
# System + Memory
MEMORY_USED=`free -b | grep Mem | awk '{print $3/$2 * 100.0}'`
SWAP_USED=`free -b | grep Swap | awk '{print $3/$2 * 100.0}'`
NUM_PROCS=`ps aux | wc -l`
# IP первого сетевого интерфейса
LOCAL_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+\.\d+\.\d+\.\d+' | grep -v '^127\.' | head -n 1)
# Имя сервера
HOSTNAME=$(hostname)
# ОS
OS=$(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"')
# Пользователь
USER_NAME=$(whoami)
[ "$USER_NAME" = "root" ] && USER_NAME="${tcLtR}${USER_NAME}${tcRESET}"
# Load average
LOADAVG=$(awk '{print $1" "$2" "$3}' /proc/loadavg)
SYS_LOADS=`cat /proc/loadavg | awk '{print $1}'`
# RAM: всего и свободно (в мегабайтах)
RAM_TOTAL=$(free -m | awk '/Mem:/ {print $2}')
RAM_FREE=$(free -m | awk '/Mem:/ {print $7}')
RAM_FREE_PCT=$(( RAM_FREE * 100 / RAM_TOTAL ))
# Количество CPU
CPU_COUNT=$(nproc)
# Uptime
UPTIME=$(uptime -p)
# HDD: для корневого раздела /
DISK_TOTAL_HUMAN=$(df -h / | awk 'NR==2 {print $2}')
DISK_FREE_HUMAN=$(df -h / | awk 'NR==2 {print $4}')
# Используем df без форматирования для процентов
DISK_TOTAL=$(df -k / | awk 'NR==2 {print $2}')
DISK_FREE=$(df -k / | awk 'NR==2 {print $4}')
DISK_FREE_PCT=$(( DISK_FREE * 100 / DISK_TOTAL ))
echo -e "$tcDkG ==============================================================="
echo -e $tcLtG " Good $TIME! $tcORANGE $LOCAL_IP"
echo -e $tcDkG "==============================================================="
echo -e $tcLtG " - Hostname :$tcW ${HOSTNAME}"
echo -e $tcLtG " - IP Address :$tcW ${LOCAL_IP:-N/A}"
echo -e $tcLtG " - User :$tcW ${USER_NAME}"
echo -e $tcLtG "==============================================================="
echo -e $tcLtG " - OS Release :$tcW ${OS}"
echo -e $tcLtG " - Kernel : `uname -a | awk '{print $1" "$3" "$12}'`"
echo -e $tcLtG " - Users : Currently `users | wc -w` user(s) logged on"
echo -e $tcLtG "==============================================================="
echo -e $tcLtG " - Server Time : `date`"
echo -e $tcLtG " - System load : ${SYS_LOADS} / ${NUM_PROCS} processes running"
echo -e $tcLtG " - Load average : ${LOADAVG}"
echo -e $tcLtG " - System uptime : ${upDays} days ${upHours} hours ${upMins} minutes"
echo -e $tcLtG "==============================================================="
echo -e $tcLtG " - CPU : ${CPU_COUNT} CPU"
echo -e $tcLtG " - RAM : ${RAM_TOTAL} MB, ${RAM_FREE} MB (${RAM_FREE_PCT}%) free"
echo -e $tcLtG " - HDD : ${DISK_TOTAL_HUMAN}, ${DISK_FREE_HUMAN} (${DISK_FREE_PCT}%) free"
echo -e $tcLtG " - Swap used % : ${SWAP_USED}"
echo -e $tcDkG "==============================================================="
echo -e $tcRESET ""
EOF
write_config_file "/etc/issue" false << 'EOF'
Debian GNU/Linux 12 \n \l
Local IP: не доступен
EOF
}
install_midnight_commanger() {
apt-get -y install mc
write_config_file "/root/.config/mc/ini" false << 'EOF'
[Midnight-Commander]
verbose=true
shell_patterns=true
auto_save_setup=true
preallocate_space=false
auto_menu=false
use_internal_view=true
use_internal_edit=false
clear_before_exec=true
confirm_delete=true
confirm_overwrite=true
confirm_execute=false
confirm_history_cleanup=true
confirm_exit=false
confirm_directory_hotlist_delete=false
confirm_view_dir=false
safe_delete=false
safe_overwrite=false
use_8th_bit_as_meta=false
mouse_move_pages_viewer=true
mouse_close_dialog=false
fast_refresh=false
drop_menus=false
wrap_mode=true
old_esc_mode=true
cd_symlinks=true
show_all_if_ambiguous=false
use_file_to_guess_type=true
alternate_plus_minus=false
only_leading_plus_minus=true
show_output_starts_shell=false
xtree_mode=false
file_op_compute_totals=true
classic_progressbar=true
use_netrc=true
ftpfs_always_use_proxy=false
ftpfs_use_passive_connections=true
ftpfs_use_passive_connections_over_proxy=false
ftpfs_use_unix_list_options=true
ftpfs_first_cd_then_ls=true
ignore_ftp_chattr_errors=true
editor_fill_tabs_with_spaces=false
editor_return_does_auto_indent=false
editor_backspace_through_tabs=false
editor_fake_half_tabs=true
editor_option_save_position=true
editor_option_auto_para_formatting=false
editor_option_typewriter_wrap=false
editor_edit_confirm_save=true
editor_syntax_highlighting=true
editor_persistent_selections=true
editor_drop_selection_on_copy=true
editor_cursor_beyond_eol=false
editor_cursor_after_inserted_block=false
editor_visible_tabs=true
editor_visible_spaces=true
editor_line_state=false
editor_simple_statusbar=false
editor_check_new_line=false
editor_show_right_margin=false
editor_group_undo=true
editor_state_full_filename=true
editor_ask_filename_before_edit=false
nice_rotating_dash=true
shadows=true
mcview_remember_file_position=false
auto_fill_mkdir_name=true
copymove_persistent_attr=true
pause_after_run=1
mouse_repeat_rate=100
double_click_speed=250
old_esc_mode_timeout=1000000
max_dirt_limit=10
num_history_items_recorded=60
vfs_timeout=60
ftpfs_directory_timeout=900
ftpfs_retry_seconds=30
fish_directory_timeout=900
editor_tab_spacing=8
editor_word_wrap_line_length=72
editor_option_save_mode=0
editor_backup_extension=~
editor_filesize_threshold=64M
editor_stop_format_chars=-+*\\,.;:&>
mcview_eof=
skin=modarcon16
filepos_max_saved_entries=1024
[Layout]
output_lines=0
left_panel_size=86
top_panel_size=0
message_visible=false
keybar_visible=true
xterm_title=true
command_prompt=true
menubar_visible=true
free_space=true
horizontal_split=false
vertical_equal=true
horizontal_equal=true
[Misc]
timeformat_recent=%b %e %H:%M
timeformat_old=%b %e %Y
ftp_proxy_host=gate
ftpfs_password=anonymous@
display_codepage=UTF-8
source_codepage=Other_8_bit
autodetect_codeset=
spell_language=en
clipboard_store=
clipboard_paste=
[Colors]
base_color=
linux=
color_terminals=
xterm-256color=
[Panels]
show_mini_info=true
kilobyte_si=false
mix_all_files=false
show_backups=true
show_dot_files=true
fast_reload=false
fast_reload_msg_shown=false
mark_moves_down=true
reverse_files_only=true
auto_save_setup_panels=false
navigate_with_arrows=false
panel_scroll_pages=true
panel_scroll_center=false
mouse_move_pages=true
filetype_mode=true
permission_mode=false
torben_fj_mode=false
quick_search_mode=2
select_flags=6
[Panelize]
Find *.orig after patching=find . -name \\*.orig -print
Find SUID and SGID programs=find . \\( \\( -perm -04000 -a -perm /011 \\) -o \\( -perm -02000 -a -perm /01 \\) \\) -print
Find rejects after patching=find . -name \\*.rej -print
Modified git files=git ls-files --modified
EOF
write_config_file "/root/.config/mc/panels.ini" false << 'EOF'
[New Left Panel]
display=listing
reverse=false
case_sensitive=true
exec_first=false
sort_order=name
list_mode=full
brief_cols=2
user_format=half type name | size | owner
user_status0=half type name | size | perm
user_status1=half type name | size | perm
user_status2=half type name | size | perm
user_status3=half type name | size | perm
user_mini_status=false
filter_flags=7
list_format=user
[New Right Panel]
display=listing
reverse=false
case_sensitive=true
exec_first=false
sort_order=name
list_mode=full
brief_cols=2
user_format=half type name | size | owner
user_status0=half type name | size | perm
user_status1=half type name | size | perm
user_status2=half type name | size | perm
user_status3=half type name | size | perm
user_mini_status=false
filter_flags=7
list_format=user
[Dirs]
current_is_left=false
other_dir=/root
EOF
}
# ==================== ОСНОВНАЯ ЛОГИКА ====================
main() {
check_root
echo -e "${ANSI_GREEN}=== Настройка системы ===${ANSI_RESET}"
# Сбор данных
NEW_HOSTNAME=$(ask_hostname)
NEW_USER=$(ask_username)
USER_PASS=$(ask_password "$NEW_USER")
ask_proxy
# Выполнение настроек
set_hostname "$NEW_HOSTNAME"
add_mephi_repository
update_system
install_packages
configure_ssh
configure_locale
configure_journald
create_user "$NEW_USER" "$USER_PASS"
configure_user_history "$NEW_USER"
configure_root_history
clean_git_docs
make_motd_generator
install_midnight_commanger
finish_setup
}
# Запуск главной функции
main "$@"
| 1 | #!/bin/bash |
| 2 | |
| 3 | set -e |
| 4 | |
| 5 | # Цвета для вывода |
| 6 | ANSI_RED := $(shell tput -Txterm setaf 1) |
| 7 | ANSI_GREEN := $(shell tput -Txterm setaf 2) |
| 8 | ANSI_YELLOW := $(shell tput -Txterm setaf 3) |
| 9 | ANSI_RESET := $(shell tput -Txterm sgr0) |
| 10 | |
| 11 | # ==================== ФУНКЦИИ ==================== |
| 12 | |
| 13 | # Проверка прав root |
| 14 | check_root() { |
| 15 | if [ "$EUID" -ne 0 ]; then |
| 16 | echo -e "${ANSI_RED}Ошибка: скрипт должен запускаться от root${ANSI_RESET}" |
| 17 | exit 1 |
| 18 | fi |
| 19 | } |
| 20 | |
| 21 | # Запрос имени хоста |
| 22 | ask_hostname() { |
| 23 | local current_hostname=$(hostname) |
| 24 | read -e -p "${ANSI_YELLOW}Введите имя хоста: (текущее: $current_hostname) ${ANSI_RESET}" -i "${current_hostname}" NEW_HOSTNAME |
| 25 | echo "$NEW_HOSTNAME" |
| 26 | } |
| 27 | |
| 28 | # Запрос имени пользователя |
| 29 | ask_username() { |
| 30 | echo -e "${ANSI_YELLOW}Введите имя нового пользователя:${ANSI_RESET}" |
| 31 | read -p "Username: " NEW_USER |
| 32 | if [ -z "$NEW_USER" ]; then |
| 33 | echo -e "${ANSI_RED}Имя пользователя не может быть пустым.${ANSI_RESET}" |
| 34 | exit 1 |
| 35 | fi |
| 36 | echo "$NEW_USER" |
| 37 | } |
| 38 | |
| 39 | # Запрос пароля |
| 40 | ask_password() { |
| 41 | local username=$1 |
| 42 | echo -e "${ANSI_YELLOW}Введите пароль для пользователя $username:${ANSI_RESET}" |
| 43 | read -s -p "Password: " USER_PASS |
| 44 | echo |
| 45 | if [ -z "$USER_PASS" ]; then |
| 46 | echo -e "${ANSI_RED}Пароль не может быть пустым.${ANSI_RESET}" |
| 47 | exit 1 |
| 48 | fi |
| 49 | echo "$USER_PASS" |
| 50 | } |
| 51 | |
| 52 | # Запрос настройки прокси |
| 53 | ask_proxy() { |
| 54 | echo -e "\n${ANSI_YELLOW}Использовать прокси-сервер apt-cacher-ng? (y/n):${ANSI_RESET}" |
| 55 | read -p "Use proxy? " USE_PROXY |
| 56 | if [[ "$USE_PROXY" =~ ^[Yy]$ ]]; then |
| 57 | echo -e "${ANSI_YELLOW}Введите URL прокси-сервера (например: http://192.168.1.100:3142):${ANSI_RESET}" |
| 58 | read -p "Proxy URL: " PROXY_URL |
| 59 | if [ -n "$PROXY_URL" ]; then |
| 60 | configure_proxy "$PROXY_URL" |
| 61 | else |
| 62 | echo -e "${ANSI_RED}URL прокси не введен, пропускаем${ANSI_RESET}" |
| 63 | fi |
| 64 | fi |
| 65 | } |
| 66 | |
| 67 | # Настройка прокси для apt |
| 68 | configure_proxy() { |
| 69 | local proxy_url=$1 |
| 70 | echo -e "${ANSI_GREEN}Настройка прокси для apt...${ANSI_RESET}" |
| 71 | cat > /etc/apt/apt.conf.d/02aptproxy << EOF |
| 72 | Acquire::http::proxy "$proxy_url"; |
| 73 | Acquire::ftp::proxy "$proxy_url"; |
| 74 | EOF |
| 75 | echo -e "${ANSI_GREEN}Прокси настроен в /etc/apt/apt.conf.d/02aptproxy${ANSI_RESET}" |
| 76 | } |
| 77 | |
| 78 | # Установка имени хоста |
| 79 | set_hostname() { |
| 80 | local hostname=$1 |
| 81 | echo -e "\n${ANSI_GREEN}=== Установка имени хоста: $hostname ===${ANSI_RESET}" |
| 82 | hostnamectl set-hostname "$hostname" |
| 83 | if grep -q "^127.0.1.1" /etc/hosts; then |
| 84 | sed -i "s/^127.0.1.1.*/127.0.1.1\t$hostname/" /etc/hosts |
| 85 | else |
| 86 | echo "127.0.1.1\t$hostname" >> /etc/hosts |
| 87 | fi |
| 88 | echo -e "${ANSI_GREEN}Имя хоста установлено.${ANSI_RESET}" |
| 89 | } |
| 90 | |
| 91 | # Добавление репозитория MEPHI |
| 92 | add_mephi_repository() { |
| 93 | . /etc/os-release 2>/dev/null || { echo "Failed to determine release"; exit 1; } |
| 94 | [ -z "$VERSION_CODENAME" ] && echo "VERSION_CODENAME not found" && exit 1 |
| 95 | |
| 96 | local conf_file="/etc/apt/sources.list.d/debian_mephi.list" |
| 97 | |
| 98 | if grep -qs "mirror.mephi.ru.*$VERSION_CODENAME" "$conf_file" 2>/dev/null; then |
| 99 | echo -e "Repository for $VERSION_CODENAME already exists in $conf_file" |
| 100 | else |
| 101 | echo -e "Adding repository for Debian $VERSION_CODENAME" |
| 102 | cat >> "$conf_file" << EOF |
| 103 | |
| 104 | # Added $(date '+%Y-%m-%d') |
| 105 | deb http://mirror.mephi.ru/debian/ $VERSION_CODENAME main non-free-firmware |
| 106 | deb-src http://mirror.mephi.ru/debian/ $VERSION_CODENAME main non-free-firmware |
| 107 | EOF |
| 108 | echo "Repository added, updating package list..." |
| 109 | apt update |
| 110 | fi |
| 111 | } |
| 112 | |
| 113 | # Обновление системы |
| 114 | update_system() { |
| 115 | echo -e "${ANSI_GREEN}=== Обновление системы ===${ANSI_RESET}" |
| 116 | apt update |
| 117 | apt -y upgrade |
| 118 | } |
| 119 | |
| 120 | # Установка пакетов |
| 121 | install_packages() { |
| 122 | local packages=( |
| 123 | pv nano curl wget sudo lsb-release iptables |
| 124 | unzip pigz zstd |
| 125 | ncdu gdu |
| 126 | screen tmux lynx |
| 127 | htop btop iftop mtr ioping |
| 128 | git jq yq pwgen |
| 129 | bind9-dnsutils net-tools ssh-audit |
| 130 | cloud-guest-utils qemu-guest-agent |
| 131 | console-setup |
| 132 | ) |
| 133 | |
| 134 | echo -e "${ANSI_GREEN}Installing packages...${ANSI_RESET}" |
| 135 | apt-get update |
| 136 | apt-get install -y "${packages[@]}" |
| 137 | } |
| 138 | |
| 139 | # Настройка SSH |
| 140 | configure_ssh() { |
| 141 | echo -e "${ANSI_GREEN}Allowing SSH root login${ANSI_RESET}" |
| 142 | sed -i 's/^.*PermitRootLogin.*$/PermitRootLogin yes/' /etc/ssh/sshd_config |
| 143 | systemctl restart sshd |
| 144 | echo -e "${ANSI_GREEN}Ok.${ANSI_RESET}" |
| 145 | } |
| 146 | |
| 147 | # Настройка таймзоны и локали |
| 148 | configure_locale() { |
| 149 | echo "tzdata tzdata/Areas select Europe" | debconf-set-selections |
| 150 | echo "tzdata tzdata/Zones/Europe select Moscow" | debconf-set-selections |
| 151 | DEBIAN_FRONTEND=noninteractive dpkg-reconfigure tzdata |
| 152 | |
| 153 | cat > /etc/locale.gen << EOF |
| 154 | ru_RU.UTF-8 UTF-8 |
| 155 | en_US.UTF-8 UTF-8 |
| 156 | EOF |
| 157 | |
| 158 | locale-gen |
| 159 | update-locale LANG=en_US.UTF-8 |
| 160 | locale -a | grep -E "en_US|ru_RU" |
| 161 | source /etc/default/locale |
| 162 | |
| 163 | dpkg-reconfigure console-setup |
| 164 | dpkg-reconfigure keyboard-configuration |
| 165 | } |
| 166 | |
| 167 | # Настройка journald |
| 168 | configure_journald() { |
| 169 | mkdir -p /etc/systemd/journald.conf.d |
| 170 | cat > /etc/systemd/journald.conf.d/size.conf << EOF |
| 171 | [Journal] |
| 172 | SystemMaxUse=1G |
| 173 | SystemMaxFileSize=50M |
| 174 | MaxLevelStore=warning |
| 175 | EOF |
| 176 | |
| 177 | systemctl restart systemd-journald |
| 178 | } |
| 179 | |
| 180 | # Создание пользователя |
| 181 | create_user() { |
| 182 | local username=$1 |
| 183 | local password=$2 |
| 184 | |
| 185 | useradd -m "$username" && echo "$username:$password" | chpasswd && passwd -e "$username" |
| 186 | usermod -aG sudo "$username" |
| 187 | |
| 188 | touch "/home/$username/.Xauthority" |
| 189 | chown "$username:$username" "/home/$username/.Xauthority" |
| 190 | |
| 191 | echo -e "${ANSI_GREEN}Пользователь $username с паролем '${ANSI_YELLOW}$password${ANSI_GREEN}' создан${ANSI_RESET}" |
| 192 | } |
| 193 | |
| 194 | # Настройка истории для пользователя |
| 195 | configure_user_history() { |
| 196 | local username=$1 |
| 197 | cat >> "/home/$username/.bashrc" << 'EOF' |
| 198 | export HISTSIZE=10000 |
| 199 | export HISTFILESIZE=50000 |
| 200 | export HISTTIMEFORMAT="%F %T " |
| 201 | export HISTCONTROL=ignoredups:ignorespace |
| 202 | shopt -s histappend |
| 203 | export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND" |
| 204 | export TERM=xterm-256color |
| 205 | EOF |
| 206 | chown "$username:$username" "/home/$username/.bashrc" |
| 207 | } |
| 208 | |
| 209 | # Настройка истории для root |
| 210 | configure_root_history() { |
| 211 | cat >> /root/.bashrc << 'EOF' |
| 212 | export HISTSIZE=10000 |
| 213 | export HISTFILESIZE=50000 |
| 214 | export HISTTIMEFORMAT="%F %T " |
| 215 | export HISTCONTROL=ignoredups:ignorespace |
| 216 | shopt -s histappend |
| 217 | export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND" |
| 218 | export TERM=xterm-256color |
| 219 | EOF |
| 220 | source /root/.bashrc |
| 221 | } |
| 222 | |
| 223 | # Очистка документации git |
| 224 | clean_git_docs() { |
| 225 | rm -rf /usr/share/doc/git/RelNotes |
| 226 | } |
| 227 | |
| 228 | # Финальное сообщение |
| 229 | finish_setup() { |
| 230 | echo -e "${ANSI_GREEN}=== Настройка завершена ===${ANSI_RESET}" |
| 231 | } |
| 232 | |
| 233 | # Запись конфигурационного файла |
| 234 | write_config_file() { |
| 235 | local file_path=$1 |
| 236 | local create_backup=${2:-true} # создать резервную копию? (по умолчанию true) |
| 237 | |
| 238 | echo -e "${ANSI_GREEN}=== Запись конфигурации в $file_path ===${ANSI_RESET}" |
| 239 | |
| 240 | # Создание резервной копии |
| 241 | if [ "$create_backup" = true ] && [ -f "$file_path" ]; then |
| 242 | local backup_path="${file_path}.backup.$(date +%Y%m%d_%H%M%S)" |
| 243 | cp "$file_path" "$backup_path" |
| 244 | echo -e "${ANSI_YELLOW}Создана резервная копия: $backup_path${ANSI_RESET}" |
| 245 | fi |
| 246 | |
| 247 | # Создание директории, если её нет |
| 248 | local dir_path=$(dirname "$file_path") |
| 249 | if [ ! -d "$dir_path" ]; then |
| 250 | mkdir -p "$dir_path" |
| 251 | echo -e "${ANSI_YELLOW}Создана директория: $dir_path${ANSI_RESET}" |
| 252 | fi |
| 253 | |
| 254 | # Чтение содержимого из heredoc |
| 255 | cat > "$file_path" |
| 256 | |
| 257 | # Установка правильных прав (опционально) |
| 258 | chmod 644 "$file_path" |
| 259 | |
| 260 | echo -e "${ANSI_GREEN}Файл успешно записан: $file_path${ANSI_RESET}" |
| 261 | } |
| 262 | |
| 263 | make_motd_generator() { |
| 264 | write_config_file "/etc/update-motd.d/99-mymotd-generator" false << 'EOF' |
| 265 | #!/bin/bash |
| 266 | |
| 267 | # Text Color Variables http://misc.flogisoft.com/bash/tip_colors_and_formatting |
| 268 | tcLtG="\033[00;37m" # LIGHT GRAY |
| 269 | tcDkG="\033[01;30m" # DARK GRAY |
| 270 | tcLtR="\033[01;31m" # LIGHT RED |
| 271 | tcLtGRN="\033[01;32m" # LIGHT GREEN |
| 272 | tcLtBL="\033[01;34m" # LIGHT BLUE |
| 273 | tcLtP="\033[01;35m" # LIGHT PURPLE |
| 274 | tcLtC="\033[01;36m" # LIGHT CYAN |
| 275 | tcW="\033[01;37m" # WHITE |
| 276 | tcRESET="\033[0m" |
| 277 | tcORANGE="\033[38;5;209m" |
| 278 | |
| 279 | # Time of day |
| 280 | HOUR=$(date +"%H") |
| 281 | if [ $HOUR -lt 12 -a $HOUR -ge 0 ]; then TIME="morning" |
| 282 | elif [ $HOUR -lt 17 -a $HOUR -ge 12 ]; then TIME="afternoon" |
| 283 | else TIME="evening" |
| 284 | fi |
| 285 | |
| 286 | # System uptime |
| 287 | uptime=`cat /proc/uptime | cut -f1 -d.` |
| 288 | upDays=$((uptime/60/60/24)) |
| 289 | upHours=$((uptime/60/60%24)) |
| 290 | upMins=$((uptime/60%60)) |
| 291 | |
| 292 | # System + Memory |
| 293 | MEMORY_USED=`free -b | grep Mem | awk '{print $3/$2 * 100.0}'` |
| 294 | SWAP_USED=`free -b | grep Swap | awk '{print $3/$2 * 100.0}'` |
| 295 | NUM_PROCS=`ps aux | wc -l` |
| 296 | |
| 297 | # IP первого сетевого интерфейса |
| 298 | LOCAL_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+\.\d+\.\d+\.\d+' | grep -v '^127\.' | head -n 1) |
| 299 | |
| 300 | # Имя сервера |
| 301 | HOSTNAME=$(hostname) |
| 302 | |
| 303 | # ОS |
| 304 | OS=$(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"') |
| 305 | |
| 306 | # Пользователь |
| 307 | USER_NAME=$(whoami) |
| 308 | [ "$USER_NAME" = "root" ] && USER_NAME="${tcLtR}${USER_NAME}${tcRESET}" |
| 309 | |
| 310 | # Load average |
| 311 | LOADAVG=$(awk '{print $1" "$2" "$3}' /proc/loadavg) |
| 312 | SYS_LOADS=`cat /proc/loadavg | awk '{print $1}'` |
| 313 | |
| 314 | # RAM: всего и свободно (в мегабайтах) |
| 315 | RAM_TOTAL=$(free -m | awk '/Mem:/ {print $2}') |
| 316 | RAM_FREE=$(free -m | awk '/Mem:/ {print $7}') |
| 317 | RAM_FREE_PCT=$(( RAM_FREE * 100 / RAM_TOTAL )) |
| 318 | |
| 319 | # Количество CPU |
| 320 | CPU_COUNT=$(nproc) |
| 321 | |
| 322 | # Uptime |
| 323 | UPTIME=$(uptime -p) |
| 324 | |
| 325 | # HDD: для корневого раздела / |
| 326 | DISK_TOTAL_HUMAN=$(df -h / | awk 'NR==2 {print $2}') |
| 327 | DISK_FREE_HUMAN=$(df -h / | awk 'NR==2 {print $4}') |
| 328 | |
| 329 | # Используем df без форматирования для процентов |
| 330 | DISK_TOTAL=$(df -k / | awk 'NR==2 {print $2}') |
| 331 | DISK_FREE=$(df -k / | awk 'NR==2 {print $4}') |
| 332 | DISK_FREE_PCT=$(( DISK_FREE * 100 / DISK_TOTAL )) |
| 333 | |
| 334 | echo -e "$tcDkG ===============================================================" |
| 335 | echo -e $tcLtG " Good $TIME! $tcORANGE $LOCAL_IP" |
| 336 | echo -e $tcDkG "===============================================================" |
| 337 | echo -e $tcLtG " - Hostname :$tcW ${HOSTNAME}" |
| 338 | echo -e $tcLtG " - IP Address :$tcW ${LOCAL_IP:-N/A}" |
| 339 | echo -e $tcLtG " - User :$tcW ${USER_NAME}" |
| 340 | echo -e $tcLtG "===============================================================" |
| 341 | echo -e $tcLtG " - OS Release :$tcW ${OS}" |
| 342 | echo -e $tcLtG " - Kernel : `uname -a | awk '{print $1" "$3" "$12}'`" |
| 343 | echo -e $tcLtG " - Users : Currently `users | wc -w` user(s) logged on" |
| 344 | echo -e $tcLtG "===============================================================" |
| 345 | echo -e $tcLtG " - Server Time : `date`" |
| 346 | echo -e $tcLtG " - System load : ${SYS_LOADS} / ${NUM_PROCS} processes running" |
| 347 | echo -e $tcLtG " - Load average : ${LOADAVG}" |
| 348 | echo -e $tcLtG " - System uptime : ${upDays} days ${upHours} hours ${upMins} minutes" |
| 349 | echo -e $tcLtG "===============================================================" |
| 350 | echo -e $tcLtG " - CPU : ${CPU_COUNT} CPU" |
| 351 | echo -e $tcLtG " - RAM : ${RAM_TOTAL} MB, ${RAM_FREE} MB (${RAM_FREE_PCT}%) free" |
| 352 | echo -e $tcLtG " - HDD : ${DISK_TOTAL_HUMAN}, ${DISK_FREE_HUMAN} (${DISK_FREE_PCT}%) free" |
| 353 | echo -e $tcLtG " - Swap used % : ${SWAP_USED}" |
| 354 | echo -e $tcDkG "===============================================================" |
| 355 | echo -e $tcRESET "" |
| 356 | EOF |
| 357 | |
| 358 | write_config_file "/etc/issue" false << 'EOF' |
| 359 | Debian GNU/Linux 12 \n \l |
| 360 | |
| 361 | Local IP: не доступен |
| 362 | EOF |
| 363 | } |
| 364 | |
| 365 | install_midnight_commanger() { |
| 366 | apt-get -y install mc |
| 367 | |
| 368 | write_config_file "/root/.config/mc/ini" false << 'EOF' |
| 369 | [Midnight-Commander] |
| 370 | verbose=true |
| 371 | shell_patterns=true |
| 372 | auto_save_setup=true |
| 373 | preallocate_space=false |
| 374 | auto_menu=false |
| 375 | use_internal_view=true |
| 376 | use_internal_edit=false |
| 377 | clear_before_exec=true |
| 378 | confirm_delete=true |
| 379 | confirm_overwrite=true |
| 380 | confirm_execute=false |
| 381 | confirm_history_cleanup=true |
| 382 | confirm_exit=false |
| 383 | confirm_directory_hotlist_delete=false |
| 384 | confirm_view_dir=false |
| 385 | safe_delete=false |
| 386 | safe_overwrite=false |
| 387 | use_8th_bit_as_meta=false |
| 388 | mouse_move_pages_viewer=true |
| 389 | mouse_close_dialog=false |
| 390 | fast_refresh=false |
| 391 | drop_menus=false |
| 392 | wrap_mode=true |
| 393 | old_esc_mode=true |
| 394 | cd_symlinks=true |
| 395 | show_all_if_ambiguous=false |
| 396 | use_file_to_guess_type=true |
| 397 | alternate_plus_minus=false |
| 398 | only_leading_plus_minus=true |
| 399 | show_output_starts_shell=false |
| 400 | xtree_mode=false |
| 401 | file_op_compute_totals=true |
| 402 | classic_progressbar=true |
| 403 | use_netrc=true |
| 404 | ftpfs_always_use_proxy=false |
| 405 | ftpfs_use_passive_connections=true |
| 406 | ftpfs_use_passive_connections_over_proxy=false |
| 407 | ftpfs_use_unix_list_options=true |
| 408 | ftpfs_first_cd_then_ls=true |
| 409 | ignore_ftp_chattr_errors=true |
| 410 | editor_fill_tabs_with_spaces=false |
| 411 | editor_return_does_auto_indent=false |
| 412 | editor_backspace_through_tabs=false |
| 413 | editor_fake_half_tabs=true |
| 414 | editor_option_save_position=true |
| 415 | editor_option_auto_para_formatting=false |
| 416 | editor_option_typewriter_wrap=false |
| 417 | editor_edit_confirm_save=true |
| 418 | editor_syntax_highlighting=true |
| 419 | editor_persistent_selections=true |
| 420 | editor_drop_selection_on_copy=true |
| 421 | editor_cursor_beyond_eol=false |
| 422 | editor_cursor_after_inserted_block=false |
| 423 | editor_visible_tabs=true |
| 424 | editor_visible_spaces=true |
| 425 | editor_line_state=false |
| 426 | editor_simple_statusbar=false |
| 427 | editor_check_new_line=false |
| 428 | editor_show_right_margin=false |
| 429 | editor_group_undo=true |
| 430 | editor_state_full_filename=true |
| 431 | editor_ask_filename_before_edit=false |
| 432 | nice_rotating_dash=true |
| 433 | shadows=true |
| 434 | mcview_remember_file_position=false |
| 435 | auto_fill_mkdir_name=true |
| 436 | copymove_persistent_attr=true |
| 437 | pause_after_run=1 |
| 438 | mouse_repeat_rate=100 |
| 439 | double_click_speed=250 |
| 440 | old_esc_mode_timeout=1000000 |
| 441 | max_dirt_limit=10 |
| 442 | num_history_items_recorded=60 |
| 443 | vfs_timeout=60 |
| 444 | ftpfs_directory_timeout=900 |
| 445 | ftpfs_retry_seconds=30 |
| 446 | fish_directory_timeout=900 |
| 447 | editor_tab_spacing=8 |
| 448 | editor_word_wrap_line_length=72 |
| 449 | editor_option_save_mode=0 |
| 450 | editor_backup_extension=~ |
| 451 | editor_filesize_threshold=64M |
| 452 | editor_stop_format_chars=-+*\\,.;:&> |
| 453 | mcview_eof= |
| 454 | skin=modarcon16 |
| 455 | |
| 456 | filepos_max_saved_entries=1024 |
| 457 | |
| 458 | [Layout] |
| 459 | output_lines=0 |
| 460 | left_panel_size=86 |
| 461 | top_panel_size=0 |
| 462 | message_visible=false |
| 463 | keybar_visible=true |
| 464 | xterm_title=true |
| 465 | command_prompt=true |
| 466 | menubar_visible=true |
| 467 | free_space=true |
| 468 | horizontal_split=false |
| 469 | vertical_equal=true |
| 470 | horizontal_equal=true |
| 471 | |
| 472 | [Misc] |
| 473 | timeformat_recent=%b %e %H:%M |
| 474 | timeformat_old=%b %e %Y |
| 475 | ftp_proxy_host=gate |
| 476 | ftpfs_password=anonymous@ |
| 477 | display_codepage=UTF-8 |
| 478 | source_codepage=Other_8_bit |
| 479 | autodetect_codeset= |
| 480 | spell_language=en |
| 481 | clipboard_store= |
| 482 | clipboard_paste= |
| 483 | |
| 484 | [Colors] |
| 485 | base_color= |
| 486 | linux= |
| 487 | color_terminals= |
| 488 | |
| 489 | xterm-256color= |
| 490 | |
| 491 | [Panels] |
| 492 | show_mini_info=true |
| 493 | kilobyte_si=false |
| 494 | mix_all_files=false |
| 495 | show_backups=true |
| 496 | show_dot_files=true |
| 497 | fast_reload=false |
| 498 | fast_reload_msg_shown=false |
| 499 | mark_moves_down=true |
| 500 | reverse_files_only=true |
| 501 | auto_save_setup_panels=false |
| 502 | navigate_with_arrows=false |
| 503 | panel_scroll_pages=true |
| 504 | panel_scroll_center=false |
| 505 | mouse_move_pages=true |
| 506 | filetype_mode=true |
| 507 | permission_mode=false |
| 508 | torben_fj_mode=false |
| 509 | quick_search_mode=2 |
| 510 | select_flags=6 |
| 511 | |
| 512 | [Panelize] |
| 513 | Find *.orig after patching=find . -name \\*.orig -print |
| 514 | Find SUID and SGID programs=find . \\( \\( -perm -04000 -a -perm /011 \\) -o \\( -perm -02000 -a -perm /01 \\) \\) -print |
| 515 | Find rejects after patching=find . -name \\*.rej -print |
| 516 | Modified git files=git ls-files --modified |
| 517 | |
| 518 | EOF |
| 519 | |
| 520 | write_config_file "/root/.config/mc/panels.ini" false << 'EOF' |
| 521 | [New Left Panel] |
| 522 | display=listing |
| 523 | reverse=false |
| 524 | case_sensitive=true |
| 525 | exec_first=false |
| 526 | sort_order=name |
| 527 | list_mode=full |
| 528 | brief_cols=2 |
| 529 | user_format=half type name | size | owner |
| 530 | user_status0=half type name | size | perm |
| 531 | user_status1=half type name | size | perm |
| 532 | user_status2=half type name | size | perm |
| 533 | user_status3=half type name | size | perm |
| 534 | user_mini_status=false |
| 535 | filter_flags=7 |
| 536 | list_format=user |
| 537 | |
| 538 | [New Right Panel] |
| 539 | display=listing |
| 540 | reverse=false |
| 541 | case_sensitive=true |
| 542 | exec_first=false |
| 543 | sort_order=name |
| 544 | list_mode=full |
| 545 | brief_cols=2 |
| 546 | user_format=half type name | size | owner |
| 547 | user_status0=half type name | size | perm |
| 548 | user_status1=half type name | size | perm |
| 549 | user_status2=half type name | size | perm |
| 550 | user_status3=half type name | size | perm |
| 551 | user_mini_status=false |
| 552 | filter_flags=7 |
| 553 | list_format=user |
| 554 | |
| 555 | [Dirs] |
| 556 | current_is_left=false |
| 557 | other_dir=/root |
| 558 | EOF |
| 559 | |
| 560 | |
| 561 | |
| 562 | |
| 563 | } |
| 564 | |
| 565 | # ==================== ОСНОВНАЯ ЛОГИКА ==================== |
| 566 | |
| 567 | main() { |
| 568 | check_root |
| 569 | |
| 570 | echo -e "${ANSI_GREEN}=== Настройка системы ===${ANSI_RESET}" |
| 571 | |
| 572 | # Сбор данных |
| 573 | NEW_HOSTNAME=$(ask_hostname) |
| 574 | NEW_USER=$(ask_username) |
| 575 | USER_PASS=$(ask_password "$NEW_USER") |
| 576 | ask_proxy |
| 577 | |
| 578 | # Выполнение настроек |
| 579 | set_hostname "$NEW_HOSTNAME" |
| 580 | add_mephi_repository |
| 581 | update_system |
| 582 | install_packages |
| 583 | configure_ssh |
| 584 | configure_locale |
| 585 | configure_journald |
| 586 | create_user "$NEW_USER" "$USER_PASS" |
| 587 | configure_user_history "$NEW_USER" |
| 588 | configure_root_history |
| 589 | clean_git_docs |
| 590 | |
| 591 | make_motd_generator |
| 592 | |
| 593 | install_midnight_commanger |
| 594 | |
| 595 | finish_setup |
| 596 | } |
| 597 | |
| 598 | # Запуск главной функции |
| 599 | main "$@" |