install-eye.sh 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102
  1. #!/bin/bash
  2. # Eye Installation Script for ALT Linux/Debian/Ubuntu with PostgreSQL support
  3. # Version: 1.0
  4. # set -e
  5. # Colors for output
  6. RED='\033[0;31m'
  7. GREEN='\033[0;32m'
  8. YELLOW='\033[1;33m'
  9. BLUE='\033[0;34m'
  10. NC='\033[0m' # No Color
  11. # Output functions
  12. print_info() {
  13. echo -e "${GREEN}[INFO]${NC} $1"
  14. }
  15. print_warn() {
  16. echo -e "${YELLOW}[WARN]${NC} $1"
  17. }
  18. print_error() {
  19. echo -e "${RED}[ERROR]${NC} $1"
  20. }
  21. print_step() {
  22. echo -e "${BLUE}=== $1 ===${NC}"
  23. }
  24. # Check for root privileges
  25. check_root() {
  26. if [[ $EUID -ne 0 ]]; then
  27. print_error "This script must be run as root"
  28. print_error "Use: sudo $0"
  29. exit 1
  30. fi
  31. }
  32. service_exists() {
  33. systemctl cat "$1.service" >/dev/null 2>&1
  34. }
  35. safe_start_service() {
  36. local svc="$1"
  37. if service_exists "$svc"; then
  38. if systemctl start "$svc"; then
  39. print_info "Service ${svc} has been successfully started"
  40. else
  41. print_error "Failed to start ${svc}"
  42. fi
  43. fi
  44. }
  45. safe_stop_service() {
  46. local svc="$1"
  47. if service_exists "$svc"; then
  48. if systemctl stop "$svc"; then
  49. print_info "Service ${svc} has been successfully stopped"
  50. else
  51. print_error "Failed to stop ${svc}"
  52. fi
  53. fi
  54. }
  55. stop_eye() {
  56. print_step "Stopping services"
  57. local PHP_VERSION
  58. PHP_VERSION=$(php -v 2>/dev/null | head -n1 | grep -oP '\d+\.\d+' || echo "")
  59. if [ -n "${PHP_VERSION}" ]; then
  60. safe_stop_service "php${PHP_VERSION}-fpm"
  61. fi
  62. for svc in cron eye-statd dhcp-log stat-sync syslog-stat; do
  63. safe_stop_service "$svc"
  64. done
  65. }
  66. start_eye() {
  67. print_step "Starting services"
  68. local PHP_VERSION
  69. PHP_VERSION=$(php -v 2>/dev/null | head -n1 | grep -oP '\d+\.\d+' || echo "")
  70. if [ -n "${PHP_VERSION}" ]; then
  71. safe_start_service "php${PHP_VERSION}-fpm"
  72. fi
  73. for svc in cron eye-statd dhcp-log stat-sync syslog-stat; do
  74. safe_start_service "$svc"
  75. done
  76. }
  77. # Detect distribution and package manager
  78. detect_distro() {
  79. if [[ -f /etc/os-release ]]; then
  80. . /etc/os-release
  81. OS_ID=$ID
  82. OS_VERSION=$VERSION_ID
  83. OS_NAME=$NAME
  84. case $OS_ID in
  85. altlinux)
  86. PACKAGE_MANAGER="apt-get"
  87. SERVICE_MANAGER="systemctl"
  88. OS_FAMILY="alt"
  89. print_info "Detected ALT Linux $OS_VERSION"
  90. ;;
  91. debian)
  92. PACKAGE_MANAGER="apt"
  93. SERVICE_MANAGER="systemctl"
  94. OS_FAMILY="debian"
  95. print_info "Detected Debian $OS_VERSION"
  96. ;;
  97. ubuntu)
  98. PACKAGE_MANAGER="apt"
  99. SERVICE_MANAGER="systemctl"
  100. OS_FAMILY="debian"
  101. print_info "Detected Ubuntu $OS_VERSION"
  102. ;;
  103. *)
  104. print_error "Unsupported distribution: $OS_ID"
  105. print_error "Supported: ALT Linux, Debian, Ubuntu"
  106. exit 1
  107. ;;
  108. esac
  109. else
  110. print_error "Failed to detect distribution"
  111. exit 1
  112. fi
  113. }
  114. select_language() {
  115. print_step "Select Installation Language"
  116. echo "Available languages:"
  117. echo "1) English"
  118. echo "2) Russian (default)"
  119. echo ""
  120. while true; do
  121. read -p "Select language (1 or 2) [2]: " lang_choice
  122. # Если пустой ввод - по умолчанию английский
  123. if [[ -z "$lang_choice" ]]; then
  124. lang_choice="2"
  125. fi
  126. # Обработка ввода (приводим к нижнему регистру)
  127. lang_choice_lower=$(echo "$lang_choice" | tr '[:upper:]' '[:lower:]')
  128. case $lang_choice_lower in
  129. 1|english|en|eng|анг|английский)
  130. EYE_LANG="english"
  131. EYE_LANG_SHORT="en"
  132. print_info "Selected English language"
  133. break
  134. ;;
  135. 2|russian|ru|rus|ру|русский)
  136. EYE_LANG="russian"
  137. EYE_LANG_SHORT="ru"
  138. print_info "Selected Russian language (Русский)"
  139. break
  140. ;;
  141. *)
  142. print_error "Invalid choice: '$lang_choice'"
  143. print_warn "Available options: 1 (English), 2 (Russian)"
  144. print_warn "You can also type: english, en, russian, ru"
  145. ;;
  146. esac
  147. done
  148. }
  149. # Ask user for database type
  150. select_database_type() {
  151. print_step "Select Database Type"
  152. echo "Available database types:"
  153. echo "1) MySQL/MariaDB (default)"
  154. echo "2) PostgreSQL"
  155. echo ""
  156. read -p "Select database type (1 or 2) [1]: " db_choice
  157. case $db_choice in
  158. 2|postgres|postgresql|pgsql)
  159. DB_TYPE="postgresql"
  160. print_info "Selected PostgreSQL"
  161. ;;
  162. *)
  163. DB_TYPE="mysql"
  164. print_info "Selected MySQL/MariaDB"
  165. ;;
  166. esac
  167. }
  168. # Настройка параметров подключения к БД (общая для local и remote)
  169. configure_database_connection() {
  170. echo ""
  171. if [[ "$DB_TYPE" == "postgresql" ]]; then
  172. DEFAULT_PORT=5432
  173. else
  174. DEFAULT_PORT=3306
  175. fi
  176. if [[ "$DB_INSTALL" == "local" ]]; then
  177. echo "Local Database Configuration"
  178. echo "============================"
  179. DB_HOST="127.0.0.1"
  180. DB_PORT="$DEFAULT_PORT"
  181. echo "Database server: $DB_HOST:$DB_PORT (local)"
  182. else
  183. echo "Remote Database Configuration"
  184. echo "============================"
  185. read -r -p "Database server IP address: " DB_HOST
  186. read -r -p "Database port [$DEFAULT_PORT]: " DB_PORT
  187. : "${DB_PORT:=$DEFAULT_PORT}"
  188. fi
  189. read -r -p "Database name [eye]: " DB_NAME
  190. read -r -p "Database username [eye]: " DB_USER
  191. read -r -p "Database user password [$DEF_PASS]: " DB_PASS
  192. echo ""
  193. : "${DB_NAME:=eye}"
  194. : "${DB_USER:=eye}"
  195. : "${DB_PASS:=$DEF_PASS}"
  196. }
  197. # Function for installation type selection
  198. select_installation_type() {
  199. echo "Select installation type:"
  200. echo "1. Web interface + network backend"
  201. echo "2. Web interface only"
  202. echo "3. Network backend only"
  203. echo ""
  204. read -p "Enter selection number [1]: " install_type
  205. if command -v pwgen >/dev/null 2>&1; then
  206. DEF_PASS=$(pwgen -s 16 1)
  207. elif command -v openssl >/dev/null 2>&1; then
  208. DEF_PASS=$(openssl rand -base64 12)
  209. else
  210. DEF_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c16)
  211. fi
  212. case $install_type in
  213. 1)
  214. INSTALL_TYPE="full"
  215. echo "Selected: Web interface + network backend"
  216. read -p "Install database locally? (y/n) [y]: " install_db
  217. if [[ -z "$install_db" || "$install_db" =~ ^[Yy]$ ]]; then
  218. DB_INSTALL="local"
  219. echo "Local database will be installed"
  220. select_database_type
  221. else
  222. DB_INSTALL="remote"
  223. echo "Remote database configuration"
  224. select_database_type
  225. fi
  226. configure_database_connection
  227. ;;
  228. 2)
  229. INSTALL_TYPE="web"
  230. echo "Selected: Web interface only"
  231. DB_INSTALL="remote"
  232. select_database_type
  233. configure_database_connection
  234. ;;
  235. 3)
  236. INSTALL_TYPE="backend"
  237. echo "Selected: Network backend only"
  238. DB_INSTALL="remote"
  239. select_database_type
  240. configure_database_connection
  241. ;;
  242. *)
  243. INSTALL_TYPE="full"
  244. echo "Default selected: Web interface + network backend"
  245. DB_INSTALL="local"
  246. echo "Local database will be installed"
  247. select_database_type
  248. configure_database_connection
  249. ;;
  250. esac
  251. # Защита от неопределённых переменных
  252. : "${DB_TYPE:=mysql}"
  253. : "${DB_INSTALL:=local}"
  254. : "${DB_HOST:=127.0.0.1}"
  255. : "${DB_NAME:=eye}"
  256. : "${DB_USER:=eye}"
  257. : "${DB_PASS:=$DEF_PASS}"
  258. }
  259. # Install dependencies for ALT Linux
  260. install_deps_altlinux() {
  261. print_step "Installing dependencies for ALT Linux"
  262. apt-get update
  263. # Общие утилиты (всегда нужны)
  264. apt-get install -y git wget rsync xxd hwdata pwgen
  265. # === Локальная база данных (если выбрана) ===
  266. if [[ "$DB_INSTALL" == "local" ]]; then
  267. if [[ "$DB_TYPE" == "postgresql" ]]; then
  268. apt-get install -y postgresql17 postgresql17-server postgresql17-contrib postgresql17-perl
  269. else
  270. apt-get install -y mariadb-server mariadb-client
  271. fi
  272. fi
  273. # === Веб-интерфейс (если нужен) ===
  274. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  275. apt-get install -y apache2 php8.2 php8.2-fpm-fcgi apache2-mod_fcgid \
  276. php8.2-intl php8.2-mbstring php8.2-snmp php8.2-zip pear-Mail
  277. if [[ "$DB_TYPE" == "postgresql" ]]; then
  278. apt-get install -y php8.2-pgsql php8.2-pdo_pgsql
  279. else
  280. apt-get install -y php8.2-mysqlnd php8.2-pdo_mysql php8.2-mysqlnd-mysqli
  281. fi
  282. fi
  283. # === Сетевой бэкенд (если нужен) ===
  284. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  285. apt-get install -y fping iptables ipset
  286. # Общие Perl-модули (независимо от СУБД)
  287. apt-get install -y perl \
  288. perl-Net-Patricia perl-NetAddr-IP perl-Config-Tiny \
  289. perl-Net-DNS perl-DateTime perl-Net-Ping \
  290. perl-Net-Netmask perl-Text-Iconv perl-Net-SNMP \
  291. perl-Net-Telnet perl-DBI \
  292. perl-Parallel-ForkManager perl-Proc-Daemon \
  293. perl-DateTime-Format-DateParse perl-DateTime-Format-Strptime \
  294. perl-Net-OpenSSH perl-File-Tail perl-Tie-File \
  295. perl-Crypt-Rijndael perl-Crypt-CBC perl-CryptX perl-Crypt-DES \
  296. perl-File-Path-Tiny perl-Expect perl-Proc-ProcessTable \
  297. perl-Text-CSV perl-Log-Log4perl \
  298. perl-DBD-Pg perl-DBD-mysql
  299. fi
  300. # Дополнительные проверки (например, fping — нужны только бэкенду)
  301. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  302. control fping public
  303. fi
  304. control ping public_caps
  305. }
  306. # Install dependencies for Debian/Ubuntu
  307. install_deps_debian() {
  308. print_step "Installing dependencies for Debian/Ubuntu"
  309. apt-get update
  310. # Общие утилиты (всегда нужны)
  311. apt-get install -y git wget rsync xxd hwdata pwgen bsdmainutils
  312. # === Локальная база данных (если выбрана) ===
  313. if [[ "$DB_INSTALL" == "local" ]]; then
  314. if [[ "$DB_TYPE" == "postgresql" ]]; then
  315. # Устанавливаем generic-пакеты PostgreSQL
  316. apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all
  317. else
  318. apt-get install -y mariadb-server mariadb-client
  319. fi
  320. fi
  321. # === Веб-интерфейс (если нужен) ===
  322. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  323. apt-get install -y apache2 libapache2-mod-fcgid \
  324. php php-fpm \
  325. php-bcmath php-intl php-mbstring php-snmp php-zip php-mail \
  326. php-date php-db
  327. if [[ "$DB_TYPE" == "postgresql" ]]; then
  328. apt-get install -y php-pgsql
  329. else
  330. apt-get install -y php-mysql
  331. fi
  332. fi
  333. # === Сетевой бэкенд (если нужен) ===
  334. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  335. apt-get install -y fping ipset netfilter-persistent
  336. # Perl и обязательные модули (имена корректны для Ubuntu 24.04)
  337. apt-get install -y perl \
  338. libnet-patricia-perl libnetaddr-ip-perl libconfig-tiny-perl \
  339. libnet-dns-perl libdatetime-perl libnet-netmask-perl \
  340. libtext-iconv-perl libnet-snmp-perl libnet-telnet-perl \
  341. libdbi-perl libparallel-forkmanager-perl libproc-daemon-perl \
  342. libdatetime-format-dateparse-perl libnetwork-ipv4addr-perl \
  343. libnet-openssh-perl libfile-tail-perl libdatetime-format-strptime-perl \
  344. libcrypt-rijndael-perl libcrypt-cbc-perl libcryptx-perl \
  345. libcrypt-des-perl libfile-path-tiny-perl libexpect-perl \
  346. libtext-csv-perl liblog-log4perl-perl \
  347. libdbd-pg-perl libdbd-mysql-perl
  348. fi
  349. # === Дополнительно (если нужно) ===
  350. # apt-get install -y bind9 bind9-utils bind9-host
  351. }
  352. # System update
  353. update_system() {
  354. print_step "Updating apt cache"
  355. $PACKAGE_MANAGER update -y
  356. }
  357. upgrade_system() {
  358. print_step "Updating system"
  359. if [[ "$PACKAGE_MANAGER" == "apt-get" ]]; then
  360. apt-get dist-upgrade -y
  361. else
  362. $PACKAGE_MANAGER upgrade -y
  363. fi
  364. }
  365. # Install packages
  366. install_packages() {
  367. print_step "Installing packages"
  368. case $OS_FAMILY in
  369. alt)
  370. install_deps_altlinux
  371. ;;
  372. debian)
  373. install_deps_debian
  374. ;;
  375. esac
  376. }
  377. # Create user and group
  378. create_user_group() {
  379. print_step "Creating user and group"
  380. # Create group
  381. if ! getent group eye >/dev/null; then
  382. groupadd --system eye
  383. print_info "Group 'eye' created"
  384. else
  385. print_info "Group 'eye' already exists"
  386. fi
  387. # Create user
  388. if ! id -u eye >/dev/null 2>&1; then
  389. if [[ "$OS_FAMILY" == "alt" ]]; then
  390. # For ALT Linux
  391. useradd --system --shell /bin/bash --home-dir /opt/Eye \
  392. --gid eye --groups eye eye
  393. else
  394. # For Debian/Ubuntu
  395. adduser --system --disabled-password --disabled-login \
  396. --ingroup eye --home=/opt/Eye eye
  397. fi
  398. print_info "User 'eye' created"
  399. else
  400. print_info "User 'eye' already exists"
  401. fi
  402. # Create directory
  403. mkdir -p /opt/Eye
  404. chown eye:eye /opt/Eye
  405. chmod 770 /opt/Eye
  406. # Add nagios to eye group (if exists)
  407. if id -u nagios >/dev/null 2>&1; then
  408. usermod -a -G eye nagios
  409. print_info "User 'nagios' added to group 'eye'"
  410. fi
  411. }
  412. # Check and apply SNMP SHA512 patch
  413. apply_snmp_patch() {
  414. print_info "Checking for SNMPv3 SHA512 support..."
  415. # File paths
  416. USM_PATCH_FILE="/opt/Eye/docs/patches/sha512.patch"
  417. if [[ "$OS_FAMILY" == "alt" ]]; then
  418. USM_PATCH_FILE="/opt/Eye/docs/patches/sha512.alt.patch"
  419. fi
  420. USM_PM_FILE=""
  421. # Search for USM.pm in system
  422. local usm_paths=(
  423. "/usr/share/perl5/Net/SNMP/Security/USM.pm"
  424. "/usr/lib/perl5/vendor_perl/Net/SNMP/Security/USM.pm"
  425. "/usr/local/share/perl5/Net/SNMP/Security/USM.pm"
  426. )
  427. for path in "${usm_paths[@]}"; do
  428. if [[ -f "$path" ]]; then
  429. USM_PM_FILE="$path"
  430. print_info "Found USM.pm: $USM_PM_FILE"
  431. break
  432. fi
  433. done
  434. if [[ -z "$USM_PM_FILE" ]]; then
  435. print_warn "USM.pm file not found in system"
  436. return 1
  437. fi
  438. # Check if patch already applied
  439. if grep -q "AUTH_PROTOCOL_HMACSHA512" "$USM_PM_FILE"; then
  440. print_info "SHA512 patch already applied"
  441. return 0
  442. fi
  443. # Create backup
  444. cp "$USM_PM_FILE" "${USM_PM_FILE}.backup"
  445. print_info "Backup created: ${USM_PM_FILE}.backup"
  446. # Try to apply patch file
  447. local patch_applied=false
  448. if [[ -f "$USM_PATCH_FILE" ]]; then
  449. print_info "Attempting to apply patch from $USM_PATCH_FILE"
  450. # Check if patch can be applied
  451. if patch --dry-run -l -p1 -i "$USM_PATCH_FILE" -r /tmp/patch.rej "$USM_PM_FILE" 2>/dev/null; then
  452. # Apply patch
  453. if patch -l -p1 -i "$USM_PATCH_FILE" "$USM_PM_FILE" 2>/dev/null; then
  454. print_info "Patch successfully applied!"
  455. patch_applied=true
  456. else
  457. print_warn "Failed to apply patch (dry-run passed but actual application failed)"
  458. fi
  459. else
  460. print_warn "Patch cannot be applied automatically (version mismatch)"
  461. # Check differences
  462. print_info "Checking patch differences..."
  463. if [[ -f "/opt/Eye/docs/patches/USM.pm" ]]; then
  464. diff -u "$USM_PM_FILE" "/opt/Eye/docs/patches/USM.pm" > /tmp/usm.diff 2>/dev/null || true
  465. if [[ -s /tmp/usm.diff ]]; then
  466. print_warn "Differences found in USM.pm file"
  467. echo "Differences:"
  468. head -20 /tmp/usm.diff
  469. echo "..."
  470. fi
  471. fi
  472. fi
  473. fi
  474. # If patch not applied, ask user
  475. if [[ "$patch_applied" == false ]]; then
  476. echo ""
  477. print_warn "Automatic patch application failed"
  478. print_warn "Modification of USM.pm file required for SNMPv3 with SHA512 support"
  479. echo ""
  480. read -p "Do you need SNMPv3 SHA512 support? (y/n): " -n 1 -r
  481. echo
  482. if [[ $REPLY =~ ^[Yy]$ ]]; then
  483. # Try to replace the entire file
  484. if [[ -f "/opt/Eye/docs/patches/USM.pm" ]]; then
  485. print_info "Replacing USM.pm file entirely..."
  486. # Check version compatibility
  487. local original_ver=$(grep -i "version" "$USM_PM_FILE" | head -1)
  488. local patch_ver=$(grep -i "version" "/opt/Eye/docs/patches/USM.pm" | head -1)
  489. if [[ -n "$original_ver" && -n "$patch_ver" ]]; then
  490. print_info "Original file version: $original_ver"
  491. print_info "Patch version: $patch_ver"
  492. fi
  493. # Create additional backup
  494. cp "$USM_PM_FILE" "${USM_PM_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
  495. # Replace file
  496. cp -f "/opt/Eye/docs/patches/USM.pm" "$USM_PM_FILE"
  497. # Check if replacement successful
  498. if grep -q "SHA-512" "$USM_PM_FILE"; then
  499. print_info "USM.pm file successfully replaced, SHA512 support added"
  500. # Save replacement info
  501. echo "USM.pm file was replaced for SHA512 support" > "${USM_PM_FILE}.replaced"
  502. echo "Original file saved as: ${USM_PM_FILE}.backup" >> "${USM_PM_FILE}.replaced"
  503. echo "Replacement date: $(date)" >> "${USM_PM_FILE}.replaced"
  504. return 0
  505. else
  506. print_error "Failed to add SHA512 support after file replacement"
  507. # Restore from backup
  508. cp "${USM_PM_FILE}.backup" "$USM_PM_FILE"
  509. return 1
  510. fi
  511. else
  512. print_error "Patched USM.pm file not found in /opt/Eye/docs/patches/"
  513. return 1
  514. fi
  515. else
  516. print_info "SNMPv3 SHA512 support disabled"
  517. return 0
  518. fi
  519. fi
  520. return 0
  521. }
  522. upgrade_source_code() {
  523. print_step "Upgrading Eye source code"
  524. mkdir -p /opt/Eye
  525. chown eye:eye /opt/Eye
  526. chmod 755 /opt/Eye
  527. # === Обновление документации ===
  528. if [ -d "docs" ]; then
  529. print_info "Updating documentation..."
  530. mkdir -p /opt/Eye/docs
  531. rsync -ar docs/ /opt/Eye/docs/
  532. chown -R eye:eye /opt/Eye/docs
  533. fi
  534. # === Обновление web-интерфейса ===
  535. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  536. print_info "Updating web interface..."
  537. mkdir -p /opt/Eye/html/cfg /opt/Eye/html/js
  538. if [ -d "html" ]; then
  539. rsync -a --exclude cfg/ html/ /opt/Eye/html/
  540. fi
  541. download_additional_scripts
  542. chown -R eye:eye /opt/Eye/html
  543. fi
  544. # === Обновление backend ===
  545. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  546. print_info "Updating backend scripts..."
  547. mkdir -p /opt/Eye/scripts/{cfg,log}
  548. rsync -a --exclude='*/' scripts/ /opt/Eye/scripts/
  549. rsync -a scripts/eyelib/ /opt/Eye/scripts/eyelib/
  550. # Обновляем только если каталог установлен
  551. [[ -d /opt/Eye/scripts/updates ]] && rsync -a scripts/updates/ /opt/Eye/scripts/updates/
  552. [[ -d /opt/Eye/scripts/utils ]] && rsync -a scripts/utils/ /opt/Eye/scripts/utils/
  553. chmod 750 /opt/Eye/scripts
  554. chmod 770 /opt/Eye/scripts/log
  555. chown -R eye:eye /opt/Eye/scripts
  556. declare -a SERVICES=(
  557. dhcp-log
  558. dhcp-log-truncate
  559. eye-statd
  560. stat-sync
  561. syslog-stat
  562. )
  563. SYSTEMD_CHANGED=0
  564. declare -a RESTART_SERVICES=()
  565. for svc in "${SERVICES[@]}"; do
  566. if ! service_exists "$svc"; then
  567. continue
  568. fi
  569. SRC="/opt/Eye/docs/systemd/$svc.service"
  570. [[ -f "$SRC" ]] || { print_info "SKIP $svc: source file missing"; continue; }
  571. DST="/etc/systemd/system/$svc.service"
  572. if [[ ! -f "$DST" ]] || ! cmp -s "$SRC" "$DST"; then
  573. print_info "Updating $svc"
  574. cp -f "$SRC" "$DST"
  575. chmod 644 "$DST"
  576. SYSTEMD_CHANGED=1
  577. RESTART_SERVICES+=("$svc")
  578. print_info "COPIED $SRC -> $DST"
  579. else
  580. print_info "SKIP $svc: file identical"
  581. fi
  582. done
  583. if [[ $SYSTEMD_CHANGED -eq 1 ]]; then
  584. systemctl daemon-reload
  585. for svc in "${RESTART_SERVICES[@]}"; do
  586. systemctl restart "$svc"
  587. done
  588. fi
  589. fi
  590. # === Патч SNMP ===
  591. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  592. apply_snmp_patch
  593. fi
  594. }
  595. # Download and copy source code
  596. install_source_code() {
  597. print_step "Installing Eye source code"
  598. # Создаём корневой каталог
  599. mkdir -p /opt/Eye
  600. chown eye:eye /opt/Eye
  601. chmod 755 /opt/Eye
  602. # === Устанавливаем документацию (всегда) ===
  603. if [ -d "docs" ]; then
  604. print_info "Copying documentation..."
  605. mkdir -p /opt/Eye/docs
  606. cp -R docs/* /opt/Eye/docs/ 2>/dev/null || true
  607. chown -R eye:eye /opt/Eye/docs
  608. fi
  609. # === Устанавливаем веб-интерфейс (если нужен) ===
  610. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  611. print_info "Copying web interface files..."
  612. mkdir -p /opt/Eye/html/cfg /opt/Eye/html/js
  613. if [ -d "html" ]; then
  614. cp -R html/* /opt/Eye/html/ 2>/dev/null || true
  615. fi
  616. download_additional_scripts
  617. chown -R eye:eye /opt/Eye/html
  618. fi
  619. # === Устанавливаем бэкенд (если нужен) ===
  620. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  621. print_info "Copying backend scripts..."
  622. mkdir -p /opt/Eye/scripts/cfg /opt/Eye/scripts/log
  623. if [ -d "scripts" ]; then
  624. cp -R scripts/* /opt/Eye/scripts/ 2>/dev/null || true
  625. fi
  626. chmod 750 /opt/Eye/scripts
  627. chmod 770 /opt/Eye/scripts/log
  628. chown -R eye:eye /opt/Eye/scripts
  629. if [[ -f "/opt/Eye/docs/systemd/stat-sync.service" ]]; then
  630. cp /opt/Eye/docs/systemd/stat-sync.service /etc/systemd/system/
  631. systemctl enable stat-sync.service
  632. fi
  633. fi
  634. # Применяем патч (только если установлен бэкенд, т.к. касается SNMP в Perl)
  635. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  636. apply_snmp_patch
  637. fi
  638. }
  639. # Download additional scripts
  640. download_additional_scripts() {
  641. print_step "Downloading additional scripts"
  642. # Create directories
  643. mkdir -p /opt/Eye/html/js/jq
  644. mkdir -p /opt/Eye/html/js/select2
  645. mkdir -p /opt/Eye/html/js/jstree
  646. # Download jQuery
  647. print_info "Downloading jQuery..."
  648. if ! wget -q https://code.jquery.com/jquery-3.7.0.min.js \
  649. -O /opt/Eye/html/js/jq/jquery.min.js; then
  650. print_warn "Failed to download jQuery, trying alternative source..."
  651. wget -q https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js \
  652. -O /opt/Eye/html/js/jq/jquery.min.js || \
  653. print_error "Failed to download jQuery"
  654. fi
  655. # Download Select2
  656. print_info "Downloading Select2..."
  657. if wget -q https://github.com/select2/select2/archive/4.0.12.tar.gz -O 4.0.12.tar.gz; then
  658. tar -xzf 4.0.12.tar.gz -C /opt/Eye/html/js/select2/ \
  659. --strip-components=2 select2-4.0.12/dist 2>/dev/null || \
  660. tar -xzf 4.0.12.tar.gz -C /opt/Eye/html/js/select2/ \
  661. --strip-components=1 select2-4.0.12/dist 2>/dev/null
  662. rm -f 4.0.12.tar.gz
  663. else
  664. print_warn "Failed to download Select2"
  665. fi
  666. # Download jsTree
  667. print_info "Downloading jsTree..."
  668. if wget -q https://github.com/vakata/jstree/archive/3.3.12.tar.gz -O jstree.tar.gz; then
  669. tar -xzf jstree.tar.gz -C /opt/Eye/html/js/
  670. rsync -a /opt/Eye/html/js/jstree-3.3.12/dist/ /opt/Eye/html/js/jstree/
  671. rm -rf /opt/Eye/html/js/jstree-3.3.12
  672. rm -f jstree.tar.gz
  673. else
  674. print_warn "Failed to download jsTree"
  675. fi
  676. # Set permissions
  677. chown -R eye:eye /opt/Eye/html/js
  678. }
  679. # Configure MySQL
  680. setup_mysql() {
  681. print_step "Configuring MySQL"
  682. # Start and enable service
  683. $SERVICE_MANAGER enable mariadb 2>/dev/null || \
  684. $SERVICE_MANAGER enable mysql 2>/dev/null || true
  685. $SERVICE_MANAGER start mariadb 2>/dev/null || \
  686. $SERVICE_MANAGER start mysql 2>/dev/null || true
  687. # Check MySQL access
  688. if ! command -v mysql &> /dev/null; then
  689. print_error "MySQL client not installed"
  690. return 1
  691. fi
  692. MYSQL_OPT="-u root"
  693. # Check access without password
  694. if mysql -u root -e "SELECT 1;" 2>/dev/null; then
  695. print_info "MySQL accessible with empty password"
  696. echo ""
  697. print_warn "IMPORTANT: Need to set root password for MySQL!"
  698. print_warn "After installation run: mysql_secure_installation"
  699. echo ""
  700. else
  701. # Ask for password and create config file
  702. read -p "Enter MySQL root user password: " DB_ROOT_PASSWORD
  703. echo ""
  704. # Create temporary config file
  705. MYSQL_CNF_FILE="/tmp/mysql_root_eye.cnf"
  706. echo "[client]" > "$MYSQL_CNF_FILE"
  707. echo "user=root" >> "$MYSQL_CNF_FILE"
  708. echo "password=$DB_ROOT_PASSWORD" >> "$MYSQL_CNF_FILE"
  709. chmod 600 "$MYSQL_CNF_FILE"
  710. # Check connection
  711. if mysql --defaults-extra-file="$MYSQL_CNF_FILE" -e "SELECT 1;" &>/dev/null; then
  712. print_info "Successfully connected to MySQL"
  713. MYSQL_OPT="--defaults-extra-file=$MYSQL_CNF_FILE"
  714. else
  715. print_error "Incorrect MySQL root password"
  716. rm -f "$MYSQL_CNF_FILE"
  717. return 1
  718. fi
  719. fi
  720. read -p "Create database and user for Eye? (y/n): " -n 1 -r
  721. echo
  722. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  723. print_warn "Database creation skipped. Create manually:"
  724. print_warn " mysql -u root -p ${DB_NAME}< ${SQL_CREATE_FILE}"
  725. print_warn " mysql -u root -p ${DB_NAME} < ${SQL_DATA_FILE}"
  726. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  727. rm -f "$MYSQL_CNF_FILE"
  728. fi
  729. return 0
  730. fi
  731. # === Проверка: существует ли база данных? ===
  732. if mysql $MYSQL_OPT -sN -e "SHOW DATABASES;" | grep -q "^${DB_NAME}$"; then
  733. print_error "Database '$DB_NAME' already exists. The script has been stopped."
  734. exit 120
  735. fi
  736. print_info "Create database..."
  737. # Import main SQL file
  738. mysql $MYSQL_OPT <<EOF
  739. CREATE DATABASE IF NOT EXISTS ${DB_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  740. EOF
  741. if [[ $? -ne 0 ]]; then
  742. print_error "Error creating database ${DB_NAME}"
  743. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  744. rm -f "$MYSQL_CNF_FILE"
  745. fi
  746. exit 121
  747. fi
  748. print_info "Importing database structure..."
  749. mysql $MYSQL_OPT ${DB_NAME} < ${SQL_CREATE_FILE}
  750. if [[ $? -ne 0 ]]; then
  751. print_error "Error importing create_db.sql"
  752. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  753. rm -f "$MYSQL_CNF_FILE"
  754. fi
  755. exit 122
  756. fi
  757. print_info "Database structure imported"
  758. # Import data
  759. print_info "Importing initial data..."
  760. mysql $MYSQL_OPT ${DB_NAME} < ${SQL_DATA_FILE}
  761. if [[ $? -ne 0 ]]; then
  762. print_error "Error importing data.sql !!!"
  763. exit 123
  764. else
  765. print_info "Initial data imported"
  766. fi
  767. # Create db user
  768. print_info "Creating user ${DB_USER}.."
  769. mysql $MYSQL_OPT <<EOF
  770. CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';
  771. GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';
  772. FLUSH PRIVILEGES;
  773. EOF
  774. if [[ $? -ne 0 ]]; then
  775. print_error "Error creating user $DB_USER"
  776. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  777. rm -f "$MYSQL_CNF_FILE"
  778. fi
  779. exit 124
  780. fi
  781. print_info "User $DB_USER successfully created"
  782. # Save password information
  783. echo "MySQL $DB_USER user password: $DB_PASS" > /root/eye_mysql_password.txt
  784. chmod 600 /root/eye_mysql_password.txt
  785. print_info "User $DB_USER password: $DB_PASS"
  786. print_warn "Password saved in /root/eye_mysql_password.txt"
  787. # Clean up temporary file if created
  788. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  789. rm -f "$MYSQL_CNF_FILE"
  790. fi
  791. return 0
  792. }
  793. # Configure PostgreSQL
  794. setup_postgresql() {
  795. print_step "Configuring PostgreSQL"
  796. PGDATA="/var/lib/pgsql/data"
  797. # Для ALT Linux
  798. if [[ "$OS_FAMILY" == "alt" ]]; then
  799. echo "root ALL=(ALL:ALL) NOPASSWD: ALL" >/etc/sudoers.d/root
  800. PGDATA="/var/lib/pgsql/data"
  801. if [ -z "$(ls -A $PGDATA 2>/dev/null)" ]; then
  802. /etc/init.d/postgresql initdb
  803. # === ВАЖНО: настраиваем pg_hba.conf для безпарольного доступа ===
  804. local pg_hba_file="$PGDATA/pg_hba.conf"
  805. if [[ -f "$pg_hba_file" ]]; then
  806. # Делаем резервную копию
  807. cp "$pg_hba_file" "${pg_hba_file}.backup"
  808. # Вставляем правило для пользователя 'postgres' в начало файла
  809. # Это разрешит подключение без пароля через Unix-сокет
  810. sed -i '1i\
  811. # Allow local postgres user without password\
  812. local all postgres peer\
  813. ' "$pg_hba_file"
  814. print_info "Configured pg_hba.conf to allow peer authentication for 'postgres'"
  815. fi
  816. fi
  817. # Start and enable service
  818. $SERVICE_MANAGER enable postgresql
  819. $SERVICE_MANAGER restart postgresql
  820. else
  821. # Start and enable service
  822. $SERVICE_MANAGER enable postgresql
  823. $SERVICE_MANAGER start postgresql
  824. fi
  825. # Check PostgreSQL access
  826. if ! command -v psql &> /dev/null; then
  827. print_error "PostgreSQL client not installed"
  828. exit 110
  829. fi
  830. # === Проверка: существует ли БД? ===
  831. if sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw "^\s*${DB_NAME}\s*$"; then
  832. print_error "Database '$DB_NAME' already exists. The script has been stopped."
  833. exit 120
  834. fi
  835. # Спросить, создавать ли БД
  836. read -p "Create database and user for Eye? (y/n): " -n 1 -r
  837. echo
  838. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  839. print_warn "Database creation skipped. Create manually as postgres user:"
  840. print_warn " sudo -u postgres createdb -O $DB_USER $DB_NAME"
  841. print_warn " sudo -u postgres psql -d $DB_NAME -f $SQL_DATA_FILE"
  842. return 0
  843. fi
  844. # Определяем локаль на основе языка
  845. if [[ "$EYE_LANG" == "russian" ]]; then
  846. LC_TYPE="ru_RU.UTF-8"
  847. else
  848. LC_TYPE="en_US.UTF-8"
  849. fi
  850. print_info "Creating database '$DB_NAME' with locale '$LC_TYPE'..."
  851. # Set password for stat user
  852. print_info "Setting password for user $DB_USER ..."
  853. sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
  854. sudo -u postgres createdb \
  855. --encoding=UTF8 \
  856. --lc-collate="$LC_TYPE" \
  857. --lc-ctype="$LC_TYPE" \
  858. --template=template0 \
  859. --owner="$DB_USER" \
  860. "$DB_NAME"
  861. if [[ $? -ne 0 ]]; then
  862. print_error "Failed to create database"
  863. exit 121
  864. fi
  865. print_info "Database created successfully with owner '$DB_USER'"
  866. sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
  867. # Теперь подключаемся как новый владелец для импорта
  868. print_info "Importing database structure as '$DB_USER'..."
  869. # Вариант 1: Используя sudo и переключение пользователя в psql
  870. sudo -u postgres psql -d "$DB_NAME" <<EOF
  871. SET ROLE "$DB_USER";
  872. \i $SQL_CREATE_FILE
  873. EOF
  874. if [[ $? -ne 0 ]]; then
  875. print_error "Error importing create_db.sql"
  876. exit 122
  877. fi
  878. print_info "Database structure imported successfully"
  879. # Импортируем данные тоже как владелец
  880. if [[ -f "$SQL_DATA_FILE" ]]; then
  881. print_info "Importing database data as '$DB_USER'..."
  882. sudo -u postgres psql -d "$DB_NAME" <<EOF
  883. SET ROLE "$DB_USER";
  884. \i $SQL_DATA_FILE
  885. EOF
  886. if [[ $? -ne 0 ]]; then
  887. print_error "Warning: failed to import data (may already exist or non-critical)"
  888. exit 123
  889. else
  890. print_info "Database data imported successfully"
  891. fi
  892. fi
  893. # Дополнительные привилегии
  894. print_info "Setting up additional privileges..."
  895. # Дать доступ пользователю postgres к БД
  896. sudo -u postgres psql -c "GRANT CONNECT ON DATABASE $DB_NAME TO postgres;"
  897. # Дать полные права пользователю postgres на все объекты
  898. sudo -u postgres psql -d "$DB_NAME" <<EOF
  899. GRANT ALL ON SCHEMA public TO postgres;
  900. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON TABLES TO postgres;
  901. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres;
  902. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres;
  903. EOF
  904. print_info "Database setup completed successfully"
  905. # Configure PostgreSQL for MD5 authentication
  906. if [[ "$OS_FAMILY" == "alt" ]]; then
  907. local pg_hba_file="/var/lib/pgsql/data/pg_hba.conf"
  908. if [[ -f "$pg_hba_file" ]]; then
  909. # Backup original
  910. cp "$pg_hba_file" "${pg_hba_file}.backup"
  911. # Add local md5 authentication if not present
  912. if ! grep -q "local.*$DB_NAME.*md5" "$pg_hba_file"; then
  913. echo "local $DB_NAME $DB_USER scram-sha-256" >> "$pg_hba_file"
  914. print_info "Added MD5 authentication for $DB_USER user in pg_hba.conf"
  915. fi
  916. fi
  917. else
  918. local pg_hba_file="/etc/postgresql/$(ls /etc/postgresql/ | head -1)/main/pg_hba.conf"
  919. if [[ -f "$pg_hba_file" ]]; then
  920. # Backup original
  921. cp "$pg_hba_file" "${pg_hba_file}.backup"
  922. # Add local md5 authentication if not present
  923. if ! grep -q "local.*$DB_NAME.*md5" "$pg_hba_file"; then
  924. echo "local $DB_NAME $DB_USER scram-sha-256" >> "$pg_hba_file"
  925. print_info "Added MD5 authentication for $DB_USER user in pg_hba.conf"
  926. fi
  927. fi
  928. fi
  929. # Restart PostgreSQL to apply changes
  930. $SERVICE_MANAGER restart postgresql
  931. # Save password information
  932. echo "PostgreSQL $DB_USER user password: $DB_PASS" > /root/eye_postgres_password.txt
  933. chmod 600 /root/eye_postgres_password.txt
  934. print_info "User $DB_USER password: $DB_PASS"
  935. print_warn "Password saved in /root/eye_postgres_password.txt"
  936. return 0
  937. }
  938. # Configure database based on selected type
  939. setup_database() {
  940. # Пропускаем настройку, если БД — удалённая
  941. if [[ "$DB_INSTALL" != "local" ]]; then
  942. print_info "Database is configured remotely — skipping local setup"
  943. return 0
  944. fi
  945. print_step "Setting up local database"
  946. # Определяем пути к SQL-файлам в зависимости от типа БД и языка
  947. if [[ "$DB_TYPE" == "mysql" ]]; then
  948. if [[ "$EYE_LANG" == "russian" && -d "/opt/Eye/docs/databases/mysql/ru" ]]; then
  949. SQL_DATA_FILE="/opt/Eye/docs/databases/mysql/ru/data.sql"
  950. SQL_CREATE_FILE="/opt/Eye/docs/databases/mysql/ru/create_db.sql"
  951. else
  952. SQL_DATA_FILE="/opt/Eye/docs/databases/mysql/en/data.sql"
  953. SQL_CREATE_FILE="/opt/Eye/docs/databases/mysql/en/create_db.sql"
  954. fi
  955. elif [[ "$DB_TYPE" == "postgresql" ]]; then
  956. if [[ "$EYE_LANG" == "russian" && -d "/opt/Eye/docs/databases/postgres/ru" ]]; then
  957. SQL_DATA_FILE="/opt/Eye/docs/databases/postgres/ru/data.sql"
  958. SQL_CREATE_FILE="/opt/Eye/docs/databases/postgres/ru/create_db.sql"
  959. else
  960. SQL_DATA_FILE="/opt/Eye/docs/databases/postgres/en/data.sql"
  961. SQL_CREATE_FILE="/opt/Eye/docs/databases/postgres/en/create_db.sql"
  962. fi
  963. else
  964. print_error "Unsupported database type: $DB_TYPE"
  965. exit 130
  966. fi
  967. # Проверка существования файлов
  968. if [[ ! -f "$SQL_CREATE_FILE" || ! -f "$SQL_DATA_FILE" ]]; then
  969. print_error "SQL files not found for DB_TYPE=$DB_TYPE and EYE_LANG=$EYE_LANG"
  970. exit 131
  971. fi
  972. print_info "Using SQL files for $EYE_LANG language"
  973. # Выполняем настройку в зависимости от СУБД
  974. if [[ "$DB_TYPE" == "postgresql" ]]; then
  975. setup_postgresql
  976. else
  977. setup_mysql
  978. fi
  979. }
  980. # Configure configuration files
  981. setup_configs() {
  982. print_step "Configuring configuration files"
  983. # Генерация или запрос ключей шифрования
  984. print_info "Setting up encryption keys..."
  985. if [[ "$DB_INSTALL" == "local" ]]; then
  986. # Для локальной БД — генерируем автоматически
  987. if command -v pwgen &> /dev/null; then
  988. ENC_PASSWORD=$(pwgen 16 1)
  989. else
  990. ENC_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c16)
  991. fi
  992. ENC_VECTOR=$(tr -dc 0-9 </dev/urandom | head -c 16)
  993. print_info "Encryption keys generated automatically (local database)."
  994. print_info "Password: $ENC_PASSWORD"
  995. print_info "Vector: $ENC_VECTOR"
  996. else
  997. # Для удалённой БД — ОБЯЗАТЕЛЬНО запрашиваем у пользователя
  998. echo ""
  999. print_info "Remote database detected. You MUST provide the encryption keys"
  1000. print_info "that are already in use by other Eye components connected to this database."
  1001. echo ""
  1002. while [[ -z "$ENC_PASSWORD" ]]; do
  1003. read -p "Enter ENCRYPTION_KEY (16+ characters): " ENC_PASSWORD
  1004. if [[ ${#ENC_PASSWORD} -lt 16 ]]; then
  1005. print_warn "Key should be at least 16 characters long."
  1006. ENC_PASSWORD=""
  1007. fi
  1008. done
  1009. while [[ -z "$ENC_VECTOR" ]]; do
  1010. read -p "Enter ENCRYPTION_IV (exactly 16 digits): " ENC_VECTOR
  1011. if [[ ! "$ENC_VECTOR" =~ ^[0-9]{16}$ ]]; then
  1012. print_warn "IV must consist of exactly 16 digits (0-9)."
  1013. ENC_VECTOR=""
  1014. fi
  1015. done
  1016. print_info "Encryption keys accepted for remote database."
  1017. fi
  1018. # === Настройка веб-конфигурации (только если нужен веб) ===
  1019. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  1020. if [[ -f "/opt/Eye/html/cfg/config.sample.php" ]]; then
  1021. cp /opt/Eye/html/cfg/config.sample.php /opt/Eye/html/cfg/config.php
  1022. # Определяем DB_TYPE для PHP (mysql или pgsql)
  1023. PHP_DB_TYPE="$DB_TYPE"
  1024. [[ "$DB_TYPE" == "postgresql" ]] && PHP_DB_TYPE="pgsql"
  1025. # Подстановка реальных значений
  1026. sed -i "s/define(\"DB_TYPE\",\"[^\"]*\");/define(\"DB_TYPE\",\"$PHP_DB_TYPE\");/" /opt/Eye/html/cfg/config.php
  1027. sed -i "s/define(\"DB_HOST\",\"[^\"]*\");/define(\"DB_HOST\",\"$DB_HOST\");/" /opt/Eye/html/cfg/config.php
  1028. sed -i "s/define(\"DB_PORT\",\"[^\"]*\");/define(\"DB_PORT\",\"$DB_PORT\");/" /opt/Eye/html/cfg/config.php
  1029. sed -i "s/define(\"DB_NAME\",\"[^\"]*\");/define(\"DB_NAME\",\"$DB_NAME\");/" /opt/Eye/html/cfg/config.php
  1030. sed -i "s/define(\"DB_USER\",\"[^\"]*\");/define(\"DB_USER\",\"$DB_USER\");/" /opt/Eye/html/cfg/config.php
  1031. sed -i "s/define(\"DB_PASS\",\"[^\"]*\");/define(\"DB_PASS\",\"$DB_PASS\");/" /opt/Eye/html/cfg/config.php
  1032. # Ключи шифрования
  1033. sed -i "s/ENCRYPTION_KEY\",\"[^\"]*\"/ENCRYPTION_KEY\",\"$ENC_PASSWORD\"/" /opt/Eye/html/cfg/config.php
  1034. sed -i "s/ENCRYPTION_IV\",\"[^\"]*\"/ENCRYPTION_IV\",\"$ENC_VECTOR\"/" /opt/Eye/html/cfg/config.php
  1035. print_info "Web configuration file config.php created"
  1036. else
  1037. print_warn "Web config template not found, skipping PHP config"
  1038. fi
  1039. fi
  1040. # === Настройка конфигурации бэкенда (только если нужен бэкенд) ===
  1041. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  1042. if [[ -f "/opt/Eye/scripts/cfg/config.sample" ]]; then
  1043. cp /opt/Eye/scripts/cfg/config.sample /opt/Eye/scripts/cfg/config
  1044. # Подстановка значений
  1045. sed -i "s/^DBTYPE=.*/DBTYPE=$DB_TYPE/" /opt/Eye/scripts/cfg/config
  1046. sed -i "s/DBTYPE=db_type/DBTYPE=$DB_TYPE/" /opt/Eye/scripts/cfg/config
  1047. sed -i "s/^DBHOST=.*/DBHOST=$DB_HOST/" /opt/Eye/scripts/cfg/config
  1048. sed -i "s/^DBPORT=.*/DBPORT=$DB_PORT/" /opt/Eye/scripts/cfg/config
  1049. sed -i "s/^DBNAME=.*/DBNAME=$DB_NAME/" /opt/Eye/scripts/cfg/config
  1050. sed -i "s/^DBUSER=.*/DBUSER=$DB_USER/" /opt/Eye/scripts/cfg/config
  1051. sed -i "s/^DBPASS=.*/DBPASS=$DB_PASS/" /opt/Eye/scripts/cfg/config
  1052. # Ключи шифрования
  1053. sed -i "s/^encryption_key=.*/encryption_key=$ENC_PASSWORD/" /opt/Eye/scripts/cfg/config
  1054. sed -i "s/encryption_key=!!!CHANGE_ME!!!!/encryption_key=$ENC_PASSWORD/" /opt/Eye/scripts/cfg/config
  1055. sed -i "s/^encryption_iv=.*/encryption_iv=$ENC_VECTOR/" /opt/Eye/scripts/cfg/config
  1056. sed -i "s/encryption_iv=0123456789012345/encryption_iv=$ENC_VECTOR/" /opt/Eye/scripts/cfg/config
  1057. print_info "Backend configuration file scripts/cfg/config created"
  1058. else
  1059. print_warn "Backend config template not found, skipping scripts config"
  1060. fi
  1061. fi
  1062. # === Установка прав (только для существующих каталогов) ===
  1063. if [[ -d "/opt/Eye/html/cfg" ]]; then
  1064. chown -R eye:eye /opt/Eye/html/cfg
  1065. chmod 750 /opt/Eye/html/cfg
  1066. chmod 660 /opt/Eye/html/cfg/config.php 2>/dev/null || true
  1067. fi
  1068. if [[ -d "/opt/Eye/scripts/cfg" ]]; then
  1069. chown -R eye:eye /opt/Eye/scripts/cfg
  1070. chmod 750 /opt/Eye/scripts/cfg
  1071. chmod 660 /opt/Eye/scripts/cfg/config 2>/dev/null || true
  1072. fi
  1073. }
  1074. # Функция применения языковых настроек к конфигурации
  1075. apply_language_settings() {
  1076. print_info "Applying language settings: $EYE_LANG"
  1077. # Применяем языковые настройки только если установлен веб-интерфейс
  1078. if [[ "$INSTALL_TYPE" != "web" && "$INSTALL_TYPE" != "full" ]]; then
  1079. print_info "Web interface not installed — skipping language configuration"
  1080. return 0
  1081. fi
  1082. # Проверяем, существует ли каталог конфигурации веба
  1083. if [[ ! -d "/opt/Eye/html/cfg" ]]; then
  1084. print_warn "Web config directory not found — skipping language setup"
  1085. return 0
  1086. fi
  1087. CONFIG_PHP="/opt/Eye/html/cfg/config.php"
  1088. if [[ ! -f "$CONFIG_PHP" ]]; then
  1089. print_warn "Web config file not found — skipping language setup"
  1090. return 0
  1091. fi
  1092. if [[ "$EYE_LANG" == "russian" ]]; then
  1093. # Установка русского языка
  1094. sed -i "s/define(\"HTML_LANG\",\"[^\"]*\"\");/define(\"HTML_LANG\",\"russian\");/g" "$CONFIG_PHP"
  1095. sed -i "s/setlocale(LC_ALL, '[^']*');/setlocale(LC_ALL, 'ru_RU.UTF-8');/g" "$CONFIG_PHP"
  1096. print_info "Web interface language set to Russian"
  1097. else
  1098. # Установка английского языка (по умолчанию)
  1099. sed -i "s/define(\"HTML_LANG\",\"[^\"]*\"\");/define(\"HTML_LANG\",\"english\");/g" "$CONFIG_PHP"
  1100. sed -i "s/setlocale(LC_ALL, '[^']*');/setlocale(LC_ALL, 'en_US.UTF-8');/g" "$CONFIG_PHP"
  1101. print_info "Web interface language set to English"
  1102. fi
  1103. }
  1104. # Configure Apache and PHP
  1105. setup_apache_php() {
  1106. print_step "Configuring Apache and PHP"
  1107. # Determine PHP version
  1108. PHP_VERSION=$(php -v 2>/dev/null | head -n1 | grep -oP '\d+\.\d+' || echo "8.2")
  1109. echo "Версия PHP: $PHP_VERSION"
  1110. # Configure PHP for all distributions
  1111. if [[ "$OS_FAMILY" == "alt" ]]; then
  1112. # ALT Linux
  1113. PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini"
  1114. APACHE_CONF_DIR="/etc/httpd2/conf"
  1115. APACHE_SITES_DIR="$APACHE_CONF_DIR/sites-available"
  1116. DEFAULT_CONF="$APACHE_SITES_DIR/000-default.conf"
  1117. APACHE_USER="apache2"
  1118. else
  1119. # Debian/Ubuntu
  1120. PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini"
  1121. APACHE_CONF_DIR="/etc/apache2"
  1122. APACHE_SITES_DIR="$APACHE_CONF_DIR/sites-available"
  1123. DEFAULT_CONF="$APACHE_SITES_DIR/000-default.conf"
  1124. APACHE_USER="www-data"
  1125. fi
  1126. # Configure Apache
  1127. if [[ -f "/opt/Eye/docs/apache/000-default.conf" ]]; then
  1128. print_info "Using prepared Apache template for ALT Linux"
  1129. # Create directory if it doesn't exist
  1130. mkdir -p "$APACHE_SITES_DIR"
  1131. # Copy prepared config
  1132. cp "/opt/Eye/docs/apache/000-default.conf" "$DEFAULT_CONF"
  1133. # Enable site
  1134. if [[ -f "$APACHE_CONF_DIR/sites-enabled/000-default.conf" ]]; then
  1135. rm -f "$APACHE_CONF_DIR/sites-enabled/000-default.conf"
  1136. ln -sf "$DEFAULT_CONF" "$APACHE_CONF_DIR/sites-enabled/000-default.conf"
  1137. fi
  1138. fi
  1139. # Configure sudoers
  1140. if [[ -f "/opt/Eye/docs/sudoers.d/www-data" ]]; then
  1141. # Use prepared template, substituting correct user
  1142. sed "s/www-data/eye/g" /opt/Eye/docs/sudoers.d/www-data > /etc/sudoers.d/eye
  1143. chmod 440 /etc/sudoers.d/eye
  1144. print_info "Sudoers file created from template"
  1145. fi
  1146. # Restart Apache
  1147. if [[ "$OS_FAMILY" == "alt" ]]; then
  1148. # ALT Linux uses httpd2
  1149. APACHE_SERVICE="httpd2"
  1150. else
  1151. APACHE_SERVICE="apache2"
  1152. fi
  1153. # usermod -a -G eye $APACHE_USER
  1154. if [[ "$OS_FAMILY" == "debian" ]]; then
  1155. a2dismod php${PHP_VERSION} 2>/dev/null
  1156. a2dismod mpm_prefork 2>/dev/null
  1157. a2enmod mpm_event 2>/dev/null
  1158. a2enconf php${PHP_VERSION}-fpm 2>/dev/null
  1159. fi
  1160. mkdir -p /var/log/php-fpm/
  1161. a2enmod setenvif
  1162. a2enmod proxy
  1163. a2enmod proxy_fcgi
  1164. print_info "Apache configured, sudoers user: $APACHE_USER"
  1165. print_info "Apache service: $APACHE_SERVICE"
  1166. # Configure php-fpm
  1167. print_info "Configure php-fpm${PHP_VERSION}"
  1168. if [[ -f "/opt/Eye/docs/php-fpm/eye.conf" ]]; then
  1169. print_info "Using prepared php-fpm template"
  1170. if [[ "$OS_FAMILY" == "alt" ]]; then
  1171. cp "/opt/Eye/docs/php-fpm/eye.conf" /etc/fpm${PHP_VERSION}/php-fpm.d/
  1172. else
  1173. cp "/opt/Eye/docs/php-fpm/eye.conf" /etc/php/${PHP_VERSION}/fpm/pool.available/
  1174. ln -sf "/etc/php/${PHP_VERSION}/fpm/pool.available/eye.conf" "/etc/php/${PHP_VERSION}/fpm/pool.d/eye.conf"
  1175. fi
  1176. fi
  1177. $SERVICE_MANAGER enable "$APACHE_SERVICE"
  1178. $SERVICE_MANAGER restart "$APACHE_SERVICE"
  1179. $SERVICE_MANAGER enable php${PHP_VERSION}-fpm.service
  1180. $SERVICE_MANAGER restart php${PHP_VERSION}-fpm.service
  1181. # Check configuration
  1182. if [[ "$OS_FAMILY" == "alt" ]]; then
  1183. httpd2 -t 2>/dev/null && print_info "Apache (httpd2) configuration is valid" || print_warn "Check Apache configuration"
  1184. else
  1185. apache2ctl -t 2>/dev/null && print_info "Apache configuration is valid" || print_warn "Check Apache configuration"
  1186. fi
  1187. }
  1188. # Configure cron and logrotate
  1189. setup_cron_logrotate() {
  1190. print_step "Configuring cron and logrotate"
  1191. # Cron
  1192. if [[ -f "/opt/Eye/docs/cron/stat" ]]; then
  1193. cp /opt/Eye/docs/cron/stat /etc/cron.d/eye
  1194. chmod 644 /etc/cron.d/eye
  1195. print_info "Cron job added: /etc/cron.d/eye"
  1196. fi
  1197. # Logrotate
  1198. if [ -f /etc/dnsmasq.conf ] && [ -f "/opt/Eye/docs/logrotate/dnsmasq" ]; then
  1199. cp /opt/Eye/docs/logrotate/dnsmasq /etc/logrotate.d/dnsmasq-eye
  1200. fi
  1201. if [ -e /opt/Eye/scripts ] && [ -f "/opt/Eye/docs/logrotate/scripts" ]; then
  1202. cp /opt/Eye/docs/logrotate/scripts /etc/logrotate.d/eye-scripts
  1203. fi
  1204. print_info "Cron and logrotate configuration completed"
  1205. print_warn "Edit /etc/cron.d/eye to enable required scripts"
  1206. }
  1207. # Configure DHCP server (dnsmasq)
  1208. setup_dhcp_server() {
  1209. print_step "Configuring DHCP server"
  1210. read -p "Configure DHCP server (dnsmasq)? (y/n): " -n 1 -r
  1211. echo
  1212. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  1213. return 0
  1214. fi
  1215. if [[ "$OS_FAMILY" == "debian" ]]; then
  1216. apt install dnsmasq -y
  1217. else
  1218. apt-get install dnsmasq -y
  1219. fi
  1220. # Backup configuration
  1221. if [[ -f "/etc/dnsmasq.conf" ]]; then
  1222. cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup
  1223. fi
  1224. # Copy configuration from Eye
  1225. if [[ -f "/opt/Eye/docs/addons/dnsmasq.conf" ]]; then
  1226. cat /opt/Eye/docs/addons/dnsmasq.conf > /etc/dnsmasq.conf
  1227. fi
  1228. # Copy systemd services
  1229. if [[ -f "/opt/Eye/docs/systemd/dhcp-log.service" ]]; then
  1230. cp /opt/Eye/docs/systemd/dhcp-log.service /etc/systemd/system/
  1231. mkdir -p /etc/systemd/system/dnsmasq.service.d
  1232. cp -f /opt/Eye/docs/systemd/dnsmasq.service.d/override.conf /etc/systemd/system/dnsmasq.service.d
  1233. fi
  1234. if [[ -f "/opt/Eye/docs/systemd/dhcp-log-truncate.service" ]]; then
  1235. cp /opt/Eye/docs/systemd/dhcp-log-truncate.service /etc/systemd/system/
  1236. fi
  1237. # Enable services
  1238. $SERVICE_MANAGER enable dnsmasq
  1239. # $SERVICE_MANAGER start dnsmasq
  1240. print_info "DHCP server configured"
  1241. print_warn "Edit /etc/dnsmasq.conf for your network"
  1242. }
  1243. # Configure syslog-ng
  1244. setup_syslog() {
  1245. print_step "Configuring syslog-ng"
  1246. read -p "Configure remote log collection (syslog-ng)? (y/n): " -n 1 -r
  1247. echo
  1248. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  1249. return 0
  1250. fi
  1251. if [[ "$OS_FAMILY" == "debian" ]]; then
  1252. apt install syslog-ng -y
  1253. else
  1254. apt-get install syslog-ng syslog-ng-journal -y
  1255. fi
  1256. # Create backup of main config
  1257. if [[ -f "/etc/syslog-ng/syslog-ng.conf" ]]; then
  1258. cp /etc/syslog-ng/syslog-ng.conf /etc/syslog-ng/syslog-ng.conf.backup
  1259. print_info "Backup created: /etc/syslog-ng/syslog-ng.conf.backup"
  1260. fi
  1261. # Copy additional config for Eye
  1262. if [[ -f "/opt/Eye/docs/syslog-ng/eye.conf" ]]; then
  1263. mkdir -p /etc/syslog-ng/conf.d
  1264. cp /opt/Eye/docs/syslog-ng/eye.conf /etc/syslog-ng/conf.d/eye.conf
  1265. # Check if conf.d inclusion already exists in main config
  1266. if [[ -f "/etc/syslog-ng/syslog-ng.conf" ]]; then
  1267. if ! grep -q "@include.*conf\.d" /etc/syslog-ng/syslog-ng.conf && \
  1268. ! grep -q "include.*conf\.d" /etc/syslog-ng/syslog-ng.conf; then
  1269. # Add conf.d directory inclusion to end of file
  1270. echo "" >> /etc/syslog-ng/syslog-ng.conf
  1271. echo "# Include Eye monitoring configuration" >> /etc/syslog-ng/syslog-ng.conf
  1272. echo "@include \"/etc/syslog-ng/conf.d/*.conf\"" >> /etc/syslog-ng/syslog-ng.conf
  1273. print_info "Added conf.d directory inclusion to syslog-ng.conf"
  1274. fi
  1275. fi
  1276. print_info "Configuration file eye.conf copied to /etc/syslog-ng/conf.d/"
  1277. else
  1278. print_warn "eye.conf configuration file not found in /opt/Eye/docs/syslog-ng/"
  1279. fi
  1280. # options block
  1281. syslogng_options='options {
  1282. chain_hostnames(off);
  1283. flush_lines(0);
  1284. use_dns(no);
  1285. use_fqdn(no);
  1286. dns_cache(no);
  1287. owner("root");
  1288. group("adm");
  1289. perm(0640);
  1290. stats_freq(0);
  1291. time_reopen(10);
  1292. log_fifo_size(1000);
  1293. create_dirs(yes);
  1294. keep_hostname(no);
  1295. };'
  1296. # Check for options in main config
  1297. if [[ -f "/etc/syslog-ng/syslog-ng.conf" ]]; then
  1298. if ! grep -q "^options\s*{" /etc/syslog-ng/syslog-ng.conf; then
  1299. # Add options block if it doesn't exist
  1300. if grep -q "^@version:" /etc/syslog-ng/syslog-ng.conf; then
  1301. # Insert after @version: line
  1302. sed -i "/^@version:/a\\$syslogng_options" /etc/syslog-ng/syslog-ng.conf
  1303. else
  1304. # Insert at beginning of file
  1305. sed -i "1i\\$syslogng_options" /etc/syslog-ng/syslog-ng.conf
  1306. fi
  1307. print_info "Added options block to syslog-ng.conf"
  1308. else
  1309. # Check for required parameters in existing options block
  1310. local missing_params=()
  1311. if ! grep -q "time_reopen\s*(.*)" /etc/syslog-ng/syslog-ng.conf; then
  1312. missing_params+=("time_reopen(10)")
  1313. fi
  1314. if ! grep -q "log_fifo_size\s*(.*)" /etc/syslog-ng/syslog-ng.conf; then
  1315. missing_params+=("log_fifo_size(1000)")
  1316. fi
  1317. if ! grep -q "chain_hostnames\s*(.*)" /etc/syslog-ng/syslog-ng.conf; then
  1318. missing_params+=("chain_hostnames(off)")
  1319. fi
  1320. if ! grep -q "create_dirs\s*(.*)" /etc/syslog-ng/syslog-ng.conf; then
  1321. missing_params+=("create_dirs(yes)")
  1322. fi
  1323. if ! grep -q "keep_hostname\s*(.*)" /etc/syslog-ng/syslog-ng.conf; then
  1324. missing_params+=("keep_hostname(no)")
  1325. fi
  1326. # Add missing parameters
  1327. if [[ ${#missing_params[@]} -gt 0 ]]; then
  1328. # Find options block and add parameters to end of block
  1329. sed -i '/^options\s*{/,/^}/ {
  1330. /^}/ i\ '"$(IFS='; '; echo "${missing_params[*]}")"';
  1331. }' /etc/syslog-ng/syslog-ng.conf
  1332. print_info "Added parameters to options block: ${missing_params[*]}"
  1333. fi
  1334. fi
  1335. fi
  1336. # Copy systemd service for Eye log processing
  1337. if [[ -f "/opt/Eye/docs/systemd/syslog-stat.service" ]]; then
  1338. cp /opt/Eye/docs/systemd/syslog-stat.service /etc/systemd/system/
  1339. chmod 644 /etc/systemd/system/syslog-stat.service
  1340. print_info "syslog-stat service copied"
  1341. fi
  1342. # Create log directory if it doesn't exist
  1343. mkdir -p /opt/Eye/scripts/log
  1344. chown eye:eye /opt/Eye/scripts/log
  1345. chmod 770 /opt/Eye/scripts/log
  1346. # Enable and start services
  1347. $SERVICE_MANAGER daemon-reload
  1348. if $SERVICE_MANAGER enable syslog-ng; then
  1349. print_info "syslog-ng service enabled for autostart"
  1350. else
  1351. print_warn "Failed to enable syslog-ng for autostart"
  1352. fi
  1353. if $SERVICE_MANAGER restart syslog-ng; then
  1354. print_info "syslog-ng service restarted"
  1355. else
  1356. print_warn "Failed to restart syslog-ng"
  1357. fi
  1358. if [[ -f "/etc/systemd/system/syslog-stat.service" ]]; then
  1359. if $SERVICE_MANAGER enable syslog-stat; then
  1360. print_info "syslog-stat service enabled for autostart"
  1361. else
  1362. print_warn "Failed to enable syslog-stat for autostart"
  1363. fi
  1364. if $SERVICE_MANAGER start syslog-stat; then
  1365. print_info "syslog-stat service started"
  1366. else
  1367. print_warn "Failed to start syslog-stat"
  1368. fi
  1369. fi
  1370. # Check syslog-ng configuration
  1371. if command -v syslog-ng &> /dev/null; then
  1372. if syslog-ng --syntax-only; then
  1373. print_info "syslog-ng configuration is valid"
  1374. else
  1375. print_error "Error in syslog-ng configuration"
  1376. print_warn "Check files: /etc/syslog-ng/syslog-ng.conf and /etc/syslog-ng/conf.d/eye.conf"
  1377. fi
  1378. fi
  1379. print_info "syslog-ng configuration completed"
  1380. print_info "To receive logs from devices, configure them to send to IP: $(hostname -f)"
  1381. }
  1382. # Configure additional services
  1383. setup_additional_services() {
  1384. print_step "Configuring additional services"
  1385. # stat-sync service
  1386. if [[ -f "/opt/Eye/docs/systemd/stat-sync.service" ]]; then
  1387. cp /opt/Eye/docs/systemd/stat-sync.service /etc/systemd/system/
  1388. $SERVICE_MANAGER enable stat-sync.service
  1389. print_info "stat-sync service enabled"
  1390. fi
  1391. # eye-statd service (NetFlow)
  1392. if [[ -f "/opt/Eye/docs/systemd/eye-statd.service" ]]; then
  1393. cp /opt/Eye/docs/systemd/eye-statd.service /etc/systemd/system/
  1394. $SERVICE_MANAGER enable eye-statd.service
  1395. print_info "eye-statd service (NetFlow) enabled"
  1396. fi
  1397. # add ipset
  1398. if [[ -f "/opt/Eye/docs/systemd/init.d/ipset" ]]; then
  1399. mkdir -p /etc/init.d
  1400. cp /opt/Eye/docs/systemd/init.d/ipset /etc/init.d
  1401. if [[ -f "/opt/Eye/docs/systemd/netfilter-persistent.service.d" ]]; then
  1402. if [[ "$OS_FAMILY" == "alt" ]]; then
  1403. mkdir -p /etc/systemd/system/iptables.service.d
  1404. cp /opt/Eye/docs/systemd/netfilter-persistent.service.d/override.conf /etc/systemd/system/iptables.service.d
  1405. else
  1406. mkdir -p /etc/systemd/system/netfilter-persistent.service.d
  1407. cp /opt/Eye/docs/systemd/netfilter-persistent.service.d/override.conf /etc/systemd/system/netfilter-persistent.service.d
  1408. fi
  1409. $SERVICE_MANAGER daemon-reload
  1410. fi
  1411. print_info "ipset installed"
  1412. fi
  1413. # Configure DHCP
  1414. setup_dhcp_server
  1415. # Configure syslog
  1416. setup_syslog
  1417. }
  1418. # Import MAC address database
  1419. import_mac_database() {
  1420. print_step "Importing MAC address database"
  1421. if [[ -f "/opt/Eye/scripts/utils/mac-oids/download-macs.sh" ]]; then
  1422. cd /opt/Eye/scripts/utils/mac-oids/
  1423. # Download MAC database
  1424. print_info "Downloading MAC address database..."
  1425. bash download-macs.sh
  1426. # Update vendors
  1427. if [[ -f "update-mac-vendors.pl" ]]; then
  1428. print_info "Updating vendor information..."
  1429. perl update-mac-vendors.pl
  1430. fi
  1431. cd - >/dev/null
  1432. else
  1433. print_warn "MAC address import scripts not found"
  1434. fi
  1435. }
  1436. # Final instructions
  1437. show_final_instructions() {
  1438. echo ""
  1439. echo -e "${GREEN}===========================================${NC}"
  1440. echo -e "${GREEN} INSTALLATION COMPLETED SUCCESSFULLY! ${NC}"
  1441. echo -e "${GREEN}===========================================${NC}"
  1442. echo ""
  1443. echo "SYSTEM INFORMATION:"
  1444. echo " Distribution: $OS_NAME"
  1445. echo " Version: $OS_VERSION"
  1446. echo " Database: $DB_TYPE"
  1447. echo " Language: $EYE_LANG"
  1448. echo " User: eye"
  1449. echo " Directory: /opt/Eye"
  1450. echo ""
  1451. echo ""
  1452. echo "TO COMPLETE SETUP, EXECUTE:"
  1453. echo ""
  1454. echo "1. Configure database security:"
  1455. if [[ "$DB_TYPE" == "postgresql" ]]; then
  1456. print_info " PostgreSQL: Edit pg_hba.conf if needed"
  1457. if [[ -f "/root/eye_postgres_password.txt" ]]; then
  1458. echo ""
  1459. echo "3. PostgreSQL 'stat' user password saved in:"
  1460. echo " /root/eye_postgres_password.txt"
  1461. echo ""
  1462. fi
  1463. else
  1464. echo " mysql_secure_installation"
  1465. if [[ -f "/root/eye_mysql_password.txt" ]]; then
  1466. echo ""
  1467. echo "3. MySQL 'stat' user password saved in:"
  1468. echo " /root/eye_mysql_password.txt"
  1469. echo ""
  1470. fi
  1471. fi
  1472. echo ""
  1473. echo "2. Check and edit configuration files:"
  1474. echo " /opt/Eye/html/cfg/config.php"
  1475. echo " /opt/Eye/scripts/cfg/config"
  1476. echo ""
  1477. echo "4. Configure cron jobs:"
  1478. echo " nano /etc/cron.d/eye"
  1479. echo " Uncomment required scripts"
  1480. echo ""
  1481. echo "5. Configure if necessary:"
  1482. echo " - DHCP: /etc/dnsmasq.conf"
  1483. echo " - NetFlow: configure on network devices"
  1484. echo ""
  1485. echo "6. WEB INTERFACE ACCESS:"
  1486. echo " URL: http://$(hostname -f)/"
  1487. echo " Admin: http://$(hostname -f)/admin/"
  1488. echo " Login: admin"
  1489. echo " Password: admin"
  1490. echo ""
  1491. echo -e "${RED}IMPORTANT:${NC}"
  1492. echo " - CHANGE admin password and API key!"
  1493. echo " - Configure users and networks in web interface"
  1494. echo ""
  1495. echo -e "${GREEN}===========================================${NC}"
  1496. echo ""
  1497. }
  1498. # Final instructions
  1499. show_final_upgrade() {
  1500. echo ""
  1501. echo -e "${GREEN}===========================================${NC}"
  1502. echo -e "${GREEN} UPGRADE COMPLETED SUCCESSFULLY! ${NC}"
  1503. echo -e "${GREEN}===========================================${NC}"
  1504. echo ""
  1505. }
  1506. # Install function
  1507. eye_install() {
  1508. clear
  1509. echo -e "${GREEN}===========================================${NC}"
  1510. echo -e "${GREEN} Installing Eye Monitoring System ${NC}"
  1511. echo -e "${GREEN} for ALT Linux/Debian/Ubuntu ${NC}"
  1512. echo -e "${GREEN}===========================================${NC}"
  1513. echo ""
  1514. # Инициализация глобальных переменных
  1515. DB_PASS=""
  1516. DB_USER=""
  1517. DB_NAME="eye_db"
  1518. DB_HOST="127.0.0.1"
  1519. DB_TYPE="mysql"
  1520. EYE_LANG="russian"
  1521. EYE_LANG_SHORT="ru"
  1522. SQL_DATA_FILE=""
  1523. SQL_CREATE_FILE=""
  1524. INSTALL_TYPE="full"
  1525. DB_INSTALL="local"
  1526. # Обязательные шаги (всегда)
  1527. check_root
  1528. detect_distro
  1529. select_language
  1530. # Выбор типа установки (устанавливает INSTALL_TYPE, DB_INSTALL, DB_TYPE и параметры БД)
  1531. select_installation_type
  1532. # Обновление системы и установка пакетов (зависит от типа установки и ОС)
  1533. update_system
  1534. install_packages # ← внутри уже учитывает INSTALL_TYPE и DB_INSTALL
  1535. # Пользователь нужен всегда (для /opt/Eye)
  1536. create_user_group
  1537. # Установка исходного кода (учитывает INSTALL_TYPE)
  1538. install_source_code
  1539. # Настройка БД — ТОЛЬКО если локальная
  1540. if [[ "$DB_INSTALL" == "local" ]]; then
  1541. setup_database
  1542. fi
  1543. # Настройка конфигов — всегда (но внутри учитывает INSTALL_TYPE)
  1544. setup_configs
  1545. # Язык — только если установлен веб
  1546. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  1547. apply_language_settings
  1548. fi
  1549. # Веб-сервер — только если нужен веб
  1550. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "web" ]]; then
  1551. setup_apache_php
  1552. fi
  1553. # Cron и logrotate — только если есть бэкенд (там — фоновые задачи и логи)
  1554. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  1555. setup_cron_logrotate
  1556. fi
  1557. # Доп. сервисы (dnsmasq, syslog-ng и т.п.) — только для бэкенда
  1558. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  1559. setup_additional_services
  1560. fi
  1561. # Импорт MAC-базы — только если есть бэкенд (он её использует)
  1562. if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
  1563. import_mac_database
  1564. fi
  1565. show_final_instructions
  1566. }
  1567. backup_current_installation() {
  1568. print_step "Creating full backup of current Eye installation"
  1569. local EYE_ROOT="/opt/Eye"
  1570. local BACKUP_DIR="/opt"
  1571. local TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
  1572. local BACKUP_FILE="$BACKUP_DIR/eye_backup_${TIMESTAMP}.tar.gz"
  1573. # Проверка: существует ли инсталляция
  1574. if [[ ! -d "$EYE_ROOT" ]]; then
  1575. print_warn "Directory $EYE_ROOT not found — skipping backup"
  1576. return 0
  1577. fi
  1578. # Проверка свободного места (~300 МБ на всякий случай)
  1579. local FREE_SPACE_KB=$(df "$BACKUP_DIR" | awk 'NR==2 {print $4}')
  1580. local MIN_FREE_KB=307200 # ~300 MB
  1581. if [[ $FREE_SPACE_KB -lt $MIN_FREE_KB ]]; then
  1582. print_error "Not enough free space in $BACKUP_DIR for full backup (need ~300 MB)"
  1583. return 1
  1584. fi
  1585. print_info "Creating full backup of $EYE_ROOT (excluding logs and docs)"
  1586. print_info "Backup file: $BACKUP_FILE"
  1587. # Архивируем ВЕСЬ /opt/Eye, но исключаем:
  1588. # - docs/ — не меняется, идёт с дистрибутивом
  1589. # - scripts/log/ — логи (большие, не конфигурация)
  1590. # - html/log/ — если есть
  1591. tar -czf "$BACKUP_FILE" \
  1592. --exclude="docs" \
  1593. --exclude="netflow" \
  1594. --exclude="scripts/log" \
  1595. --exclude="scripts/log/*" \
  1596. --exclude="html/log" \
  1597. --exclude="html/log/*" \
  1598. -C / "opt/Eye" 2>/dev/null
  1599. if [[ $? -eq 0 && -f "$BACKUP_FILE" ]]; then
  1600. print_info "✅ Backup completed successfully"
  1601. chmod 600 "$BACKUP_FILE"
  1602. chown root:root "$BACKUP_FILE"
  1603. else
  1604. print_error "❌ Failed to create backup archive"
  1605. return 1
  1606. fi
  1607. }
  1608. # Upgrade function
  1609. eye_upgrade() {
  1610. clear
  1611. echo -e "${GREEN}===========================================${NC}"
  1612. echo -e "${GREEN} Update Eye Monitoring System ${NC}"
  1613. echo -e "${GREEN}===========================================${NC}"
  1614. echo ""
  1615. check_root
  1616. detect_distro
  1617. stop_eye
  1618. backup_current_installation || {
  1619. echo "CRITICAL: Backup failed. Aborting upgrade."
  1620. start_eye
  1621. exit 1
  1622. }
  1623. update_system
  1624. install_packages
  1625. upgrade_source_code
  1626. if [ -f /opt/Eye/scripts/updates/upgrade.pl ]; then
  1627. perl /opt/Eye/scripts/updates/upgrade.pl
  1628. import_mac_database
  1629. fi
  1630. start_eye
  1631. show_final_upgrade
  1632. }
  1633. # Function to display help
  1634. show_help() {
  1635. echo "Usage: $0 [options]"
  1636. echo ""
  1637. echo "Options:"
  1638. echo " --help, -h Show this help"
  1639. echo " --upgrade, -u Automatic upgrade"
  1640. echo " --install, -i Interactive install"
  1641. echo ""
  1642. echo "Supported distributions:"
  1643. echo " - ALT Linux 11.1+"
  1644. echo " - Debian 11+"
  1645. echo " - Ubuntu 20.04+"
  1646. echo ""
  1647. }
  1648. # Function to check user existence
  1649. check_user() {
  1650. id "eye" &>/dev/null
  1651. return $?
  1652. }
  1653. # Function to check directory existence
  1654. check_directory() {
  1655. [ -d "/opt/Eye" ]
  1656. return $?
  1657. }
  1658. # Function to check if Eye config files exist
  1659. check_eye_configs() {
  1660. # Веб-конфиг
  1661. if [[ -f "/opt/Eye/html/cfg/config.php" ]]; then
  1662. return 0
  1663. fi
  1664. # Бэкенд-конфиг
  1665. if [[ -f "/opt/Eye/scripts/cfg/config" ]]; then
  1666. return 0
  1667. fi
  1668. return 1
  1669. }
  1670. # Handle command line arguments
  1671. case "$1" in
  1672. --help|-h)
  1673. show_help
  1674. exit 0
  1675. ;;
  1676. --upgrade|-u)
  1677. mode="upgrade"
  1678. echo "Mode set to: upgrade"
  1679. ;;
  1680. --install|-i)
  1681. mode="install"
  1682. echo "Mode set to: install"
  1683. ;;
  1684. *)
  1685. # Auto-detect mode
  1686. echo "Auto-detecting installation status..."
  1687. if check_user; then
  1688. user_exists=true
  1689. echo "✓ User 'eye' exists"
  1690. else
  1691. user_exists=false
  1692. echo "✗ User 'eye' does not exist"
  1693. fi
  1694. if check_directory; then
  1695. dir_exists=true
  1696. echo "✓ Directory /opt/Eye exists"
  1697. else
  1698. dir_exists=false
  1699. echo "✗ Directory /opt/Eye does not exist"
  1700. fi
  1701. # Проверяем наличие хотя бы одного конфига Eye
  1702. eye_config_found=false
  1703. if [[ -f "/opt/Eye/html/cfg/config.php" ]] || [[ -f "/opt/Eye/scripts/cfg/config" ]]; then
  1704. eye_config_found=true
  1705. echo "✓ Eye configuration detected"
  1706. fi
  1707. if $user_exists && $dir_exists && $eye_config_found; then
  1708. mode="upgrade"
  1709. echo "Existing Eye installation detected. Switching to upgrade mode."
  1710. # === Восстанавливаем INSTALL_TYPE ===
  1711. if [[ -f "/opt/Eye/html/cfg/config.php" ]] && [[ -f "/opt/Eye/scripts/cfg/config" ]]; then
  1712. INSTALL_TYPE="full"
  1713. elif [[ -f "/opt/Eye/html/cfg/config.php" ]]; then
  1714. INSTALL_TYPE="web"
  1715. elif [[ -f "/opt/Eye/scripts/cfg/config" ]]; then
  1716. INSTALL_TYPE="backend"
  1717. else
  1718. INSTALL_TYPE="full" # fallback
  1719. fi
  1720. # === Восстанавливаем DB_INSTALL (local/remote) ===
  1721. DB_HOST=""
  1722. if [[ -f "/opt/Eye/html/cfg/config.php" ]]; then
  1723. # Извлекаем DB_HOST из PHP-конфига
  1724. DB_HOST=$(grep -oP 'define\s*\(\s*"DB_HOST"\s*,\s*"\K[^"]+' /opt/Eye/html/cfg/config.php 2>/dev/null)
  1725. fi
  1726. if [[ -z "$DB_HOST" && -f "/opt/Eye/scripts/cfg/config" ]]; then
  1727. # Извлекаем из Perl-конфига
  1728. DB_HOST=$(grep -oP '^DBHOST=\K.*' /opt/Eye/scripts/cfg/config 2>/dev/null)
  1729. fi
  1730. if [[ "$DB_HOST" == "127.0.0.1" || "$DB_HOST" == "localhost" || "$DB_HOST" == "::1" ]]; then
  1731. DB_INSTALL="local"
  1732. else
  1733. DB_INSTALL="remote"
  1734. fi
  1735. # === Восстанавливаем DB_TYPE ===
  1736. if [[ -f "/opt/Eye/html/cfg/config.php" ]]; then
  1737. DB_TYPE=$(grep -oP 'define\s*\(\s*"DB_TYPE"\s*,\s*"\K[^"]+' /opt/Eye/html/cfg/config.php 2>/dev/null)
  1738. # В PHP может быть 'pgsql' вместо 'postgresql'
  1739. if [[ "$DB_TYPE" == "pgsql" ]]; then
  1740. DB_TYPE="postgresql"
  1741. elif [[ "$DB_TYPE" == "mysql" ]]; then
  1742. DB_TYPE="mysql"
  1743. fi
  1744. elif [[ -f "/opt/Eye/scripts/cfg/config" ]]; then
  1745. DB_TYPE=$(grep -oP '^DBTYPE=\K.*' /opt/Eye/scripts/cfg/config 2>/dev/null)
  1746. fi
  1747. # Защита от неопределённых значений
  1748. : "${INSTALL_TYPE:=full}"
  1749. : "${DB_INSTALL:=remote}"
  1750. : "${DB_TYPE:=mysql}"
  1751. echo " → INSTALL_TYPE = $INSTALL_TYPE"
  1752. echo " → DB_INSTALL = $DB_INSTALL"
  1753. echo " → DB_TYPE = $DB_TYPE"
  1754. else
  1755. mode="install"
  1756. echo "No existing Eye installation found. Switching to install mode."
  1757. fi
  1758. ;;
  1759. esac
  1760. echo ""
  1761. echo "Selected mode: $mode"
  1762. # Main execution based on mode
  1763. case "$mode" in
  1764. "upgrade")
  1765. echo "Starting upgrade process..."
  1766. # Start upgrade
  1767. eye_upgrade
  1768. ;;
  1769. "install")
  1770. echo "Starting installation process..."
  1771. # Start installation
  1772. eye_install
  1773. ;;
  1774. *)
  1775. echo "Error: Unknown mode '$mode'"
  1776. exit 1
  1777. ;;
  1778. esac
  1779. # Exit with success code
  1780. exit 0