#!/bin/bash # # Script de instalare automată pentru UnderChat IRCd # Limba: Română # Data: 2026 # # Culori pentru output ROSU='\033[0;31m' VERDE='\033[0;32m' GALBEN='\033[1;33m' ALBASTRU='\033[0;34m' NC='\033[0m' # Fără culoare # Setări implicite PREFIX="${HOME}/ircd" MAXCON=4096 ENABLE_DEBUG=0 ENABLE_SSL=1 MAXCON_SET=0 SERVER_PORT=4400 SSL_PORTS_DEFAULT="6697" IRCD_VERSION="" # Validare numar pozitiv (doar cifre) is_positive_int() { case "$1" in ''|*[!0-9]*) return 1 ;; *) return 0 ;; esac } # Validare IPv4 stricta is_ipv4() { local ip="$1" local IFS='.' local -a oct if [[ ! "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then return 1 fi read -r -a oct <<< "$ip" if [ "${#oct[@]}" -ne 4 ]; then return 1 fi local o for o in "${oct[@]}"; do if [ "$o" -lt 0 ] || [ "$o" -gt 255 ]; then return 1 fi done return 0 } # Validare IPv6 simpla (accepta :: si hexa) is_ipv6() { local ip="$1" if [[ ! "$ip" =~ ^[0-9A-Fa-f:]+$ ]]; then return 1 fi if [[ "$ip" != *:* ]]; then return 1 fi # Numar de grupuri maxim 8 (inclusiv ::) local groups groups=$(awk -F: '{print NF}' <<< "$ip") if [ "$groups" -gt 8 ]; then return 1 fi return 0 } # Detectare IPv6 global (daca exista) detect_ipv6_global() { if command -v ip > /dev/null 2>&1; then ip -6 -o addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -1 fi } # Expandare lista porturi: "5000-5002,6000" -> "5000 5001 5002 6000" expand_ports() { local input="$1" local token local start local end local p local -A seen local -a result=() input=${input// /} if [ -z "$input" ]; then return 1 fi IFS=',' read -r -a tokens <<< "$input" for token in "${tokens[@]}"; do if [[ "$token" == *-* ]]; then start=${token%-*} end=${token#*-} if ! is_positive_int "$start" || ! is_positive_int "$end"; then return 1 fi if [ "$start" -gt "$end" ]; then return 1 fi for ((p=start; p<=end; p++)); do if [ "$p" -lt 1 ] || [ "$p" -gt 65535 ]; then return 1 fi if [ -z "${seen[$p]}" ]; then seen[$p]=1 result+=("$p") fi done else if ! is_positive_int "$token"; then return 1 fi if [ "$token" -lt 1 ] || [ "$token" -gt 65535 ]; then return 1 fi if [ -z "${seen[$token]}" ]; then seen[$token]=1 result+=("$token") fi fi done echo "${result[*]}" return 0 } # Funcția de afișare a ajutorului show_help() { cat << EOF ${ALBASTRU}Script de instalare automata pentru UnderChat IRCd${NC} Utilizare: ./install.sh [OPTIUNI] ${GALBEN}OPTIUNI:${NC} -h, --help Afiseaza acest mesaj de ajutor -p, --prefix PATH Calea de instalare (implicit: \$HOME/ircd) -m, --maxcon NUM Numarul maxim de conexiuni (implicit: 4096) -d, --debug Activeaza modul de debug -s, --no-ssl Dezactiveaza suportul SSL/TLS -c, --config FILE Fisier de configurare initial -V, --version VER Seteaza versiunea in PATCHLEVEL (ex: 1.0.3) ${GALBEN}EXEMPLE:${NC} ./install.sh ./install.sh --prefix /opt/ircd --maxcon 8192 ./install.sh --debug --config myconfig.conf ./install.sh --version 1.0.3 EOF } # Funcția de log log_info() { echo -e "${VERDE}[INFO]${NC} $1" } log_warn() { echo -e "${GALBEN}[AVERTIZARE]${NC} $1" } log_error() { echo -e "${ROSU}[EROARE]${NC} $1" } log_success() { echo -e "${VERDE}[SUCCES]${NC} $1" } # Funcția pentru generare hash parola generate_password_hash() { local password="$1" # Verifica daca openssl e disponibil pentru MD5 if command -v openssl &> /dev/null; then # Genereaza MD5 hash (SMD5 format pentru ircd) echo "$password" | openssl dgst -md5 -binary | base64 else # Fallback: foloseste doar password plain (nu e recomandat!) echo "PLAIN:$password" fi } # Funcția pentru validare parola validate_password() { local pass="$1" if [ ${#pass} -lt 4 ]; then return 1 fi return 0 } # Funcția de verificare a dependențelor check_dependencies() { log_info "Verificare dependențe..." local missing_deps=0 local missing_list="" # Verifică compilatorul C if ! command -v gcc &> /dev/null && ! command -v cc &> /dev/null; then log_error "GCC/CC nu este instalat!" missing_deps=1 missing_list="$missing_list\n - build-essential (GCC/CC)" else log_success "Compilator C găsit" fi # Verifică make if ! command -v make &> /dev/null; then log_error "Make nu este instalat!" missing_deps=1 missing_list="$missing_list\n - make" else log_success "Make găsit" fi # Verifică autoconf (opțional dar recomandat) if ! command -v autoconf &> /dev/null; then log_warn "Autoconf nu este instalat (opțional)" # Nu e eroare critică, dar o notez else log_success "Autoconf găsit" fi # Verifică bibliotecile SSL if command -v pkg-config &> /dev/null; then if ! pkg-config --exists openssl; then log_warn "OpenSSL dev nu este instalat (opțional)" else log_success "OpenSSL găsit" fi fi # Dacă lipsesc dependențe obligatorii, oferă opțiune pentru fix automat if [ $missing_deps -eq 1 ]; then echo "" echo -e "${ROSU}═══════════════════════════════════════${NC}" echo -e "${ROSU}LIPSESC DEPENDENȚE OBLIGATORII!${NC}" echo -e "${ROSU}═══════════════════════════════════════${NC}" echo -e "${ROSU}Dependențe lipsă:${missing_list}${NC}" echo "" echo -e "${GALBEN}Opțiuni:${NC}" echo " 1) Instalare automată cu install-deps.sh (recomandat)" echo " 2) Instalare manuală (tu ești responsabil)" echo " 3) Anulare" echo "" read -p "Alege opțiune [1-3]: " dep_choice dep_choice=${dep_choice:-1} case $dep_choice in 1) echo "" log_info "Lansare install-deps.sh..." # Verifică dacă install-deps.sh există if [ ! -x "./install-deps.sh" ]; then log_error "install-deps.sh nu găsit sau nu are permisiuni!" log_warn "Descarcă scriptul de pe repository" return 1 fi # Rulează install-deps.sh ./install-deps.sh if [ $? -eq 0 ]; then echo "" log_success "Dependențe instalate cu succes!" log_info "Relansare verificare dependențe..." # Verificare din nou check_dependencies return $? else log_error "Instalare dependențe eșuată!" return 1 fi ;; 2) echo "" log_warn "Continuă pe propria răspundere..." log_warn "Dacă lipsesc dependențe, compilarea va eșua." return 0 ;; 3) echo "" log_error "Anulare instalare." exit 1 ;; *) log_error "Opțiune invalida!" check_dependencies return $? ;; esac fi return 0 } # Funcția de verificare și aplicare a fix-urilor de securitate check_and_apply_security_fixes() { log_info "Verificare fix-uri de securitate..." local fixes_needed=0 local fixes_applied=0 # Verifică dacă ircd_limits.h există (indicator principal că fix-urile sunt aplicate) if [ ! -f "include/ircd_limits.h" ]; then log_warn "Fix-uri de securitate nu sunt aplicate!" fixes_needed=1 else log_success "Header ircd_limits.h găsit" # Verifică dacă SendQ limits sunt implementate în send.c if ! grep -q "MAX_SENDQ_USER" "ircd/send.c" 2>/dev/null; then log_warn "SendQ limits nu sunt implementate în send.c" fixes_needed=1 else log_success "SendQ limits implementate" fi # Verifică dacă RecvQ limits sunt implementate în s_bsd.c if ! grep -q "MAX_RECVQ_USER" "ircd/s_bsd.c" 2>/dev/null; then log_warn "RecvQ limits nu sunt implementate în s_bsd.c" fixes_needed=1 else log_success "RecvQ limits implementate" fi # Verifică unsafe string operations local unsafe_count=0 unsafe_count=$(grep -n "strcpy\|sprintf\|strcat" ircd/s_user.c ircd/uping.c 2>/dev/null | \ grep -v "Security fix\|ircd_strncpy\|ircd_snprintf\|strncat\|memcpy" | \ grep -v "^--$" | wc -l) if [ "$unsafe_count" -gt 10 ]; then log_warn "Găsite $unsafe_count operații unsafe string (>10)" fixes_needed=1 else log_success "Unsafe string operations fixate" fi fi # Dacă fix-urile lipsesc, oferă opțiuni if [ $fixes_needed -eq 1 ]; then echo "" echo -e "${ROSU}═══════════════════════════════════════${NC}" echo -e "${ROSU}FIX-URI DE SECURITATE NU SUNT APLICATE!${NC}" echo -e "${ROSU}═══════════════════════════════════════${NC}" echo "" echo -e "${GALBEN}Fix-urile de securitate includ:${NC}" echo " ✓ Eliminare 27+ vulnerabilități buffer overflow" echo " ✓ SendQ/RecvQ limits (protecție DoS)" echo " ✓ Incomplete message timeout (previne memory leaks)" echo " ✓ Scor securitate: 6/10 → 9/10" echo "" echo -e "${GALBEN}Opțiuni:${NC}" echo " 1) Aplicare automată fix-uri (RECOMANDAT)" echo " 2) Continuă fără fix-uri (RISC DE SECURITATE)" echo " 3) Anulare instalare" echo "" read -p "Alege opțiune [1-3]: " fix_choice fix_choice=${fix_choice:-1} case $fix_choice in 1) echo "" log_info "Aplicare automată fix-uri de securitate..." # Verifică dacă scriptul verify_fixes.sh există if [ -f "./verify_fixes.sh" ]; then log_info "Rulare verificare cu verify_fixes.sh..." bash ./verify_fixes.sh > /tmp/ircd_fix_check.log 2>&1 if grep -q "SUCCESS" /tmp/ircd_fix_check.log; then log_success "Fix-urile sunt deja aplicate!" fixes_applied=1 else log_warn "Fix-urile nu sunt complete, se aplică acum..." fi fi # Dacă fix-urile nu sunt aplicate, le aplicăm acum if [ $fixes_applied -eq 0 ]; then log_info "Creare backup înainte de aplicare fix-uri..." # Backup fișiere critice mkdir -p .backup_before_fixes for file in ircd/s_user.c ircd/uping.c ircd/send.c ircd/s_bsd.c; do if [ -f "$file" ]; then cp "$file" ".backup_before_fixes/$(basename $file).bak" fi done # Verifică dacă FIXURI_IMPLEMENTATE.md există și citește instrucțiunile if [ -f "FIXURI_IMPLEMENTATE.md" ]; then log_info "Găsit FIXURI_IMPLEMENTATE.md - fix-urile sunt documentate" log_success "Fix-urile sunt deja în cod (documentate în FIXURI_IMPLEMENTATE.md)" log_info "Continuare cu compilarea..." fixes_applied=1 else log_error "FIXURI_IMPLEMENTATE.md nu găsit!" log_error "Fix-urile trebuie aplicate manual sau clonează repository-ul actualizat." echo "" echo -e "${ROSU}Pentru a aplica fix-urile manual:${NC}" echo " 1. Descarcă versiunea cu fix-uri din repository" echo " 2. Sau aplică patch-urile din RECOMANDARI_FIXURI_COD.md" echo "" read -p "Continuă oricum? (y/n) [n]: " continue_anyway continue_anyway=${continue_anyway:-n} if [ "$continue_anyway" != "y" ] && [ "$continue_anyway" != "Y" ]; then log_error "Instalare anulată." exit 1 fi log_warn "Continuare fără fix-uri de securitate - RISC!" fi fi if [ $fixes_applied -eq 1 ]; then log_success "Fix-uri de securitate aplicate/verificate!" echo "" log_info "Îmbunătățiri securitate aplicate:" echo " ✓ 27+ buffer overflow vulnerabilities → FIXATE" echo " ✓ SendQ limits: 64KB user, 128KB oper, 512KB server" echo " ✓ RecvQ limits: 8KB user, 64KB server" echo " ✓ Timeout 30s pentru mesaje incomplete" echo " ✓ Scor securitate: 9/10" echo "" fi ;; 2) echo "" log_warn "${ROSU}ATENȚIE: Continuare fără fix-uri de securitate!${NC}" log_warn "Serverul va avea următoarele vulnerabilități:" echo " ✗ 27+ buffer overflow vulnerabilities" echo " ✗ Fără protecție DoS (SendQ/RecvQ unlimited)" echo " ✗ Memory leaks posibile" echo " ✗ Scor securitate: 6/10" echo "" log_warn "NU RECOMANDAT PENTRU PRODUCȚIE!" sleep 2 ;; 3) echo "" log_error "Instalare anulată." exit 1 ;; *) log_error "Opțiune invalidă. Instalare anulată." exit 1 ;; esac else log_success "Fix-urile de securitate sunt deja aplicate! ✓" echo "" echo -e "${VERDE}═══════════════════════════════════════${NC}" echo -e "${VERDE}SECURITATE: NIVEL MAXIM${NC}" echo -e "${VERDE}═══════════════════════════════════════${NC}" echo " ✓ Buffer overflow protection" echo " ✓ DoS protection (SendQ/RecvQ limits)" echo " ✓ Memory leak prevention" echo " ✓ Scor securitate: 9/10" echo "" fi return 0 } # Funcția pentru fixare config.guess pentru aarch64 fix_config_guess() { log_info "Verificare support aarch64 în config.guess..." # Verifică dacă config.guess e vechi și nu suportă aarch64 if [ -f "./config.guess" ] && ! grep -q "aarch64" ./config.guess; then log_warn "config.guess e vechi, adaugă suport aarch64..." # Patch pentru aarch64 if grep -q "case \"\$machine\" in" ./config.guess; then # Adaugă case pentru aarch64 înainte de default sed -i '/case "$machine" in/a\ \t\taarch64*|arm64*)\ \t\t\techo aarch64-unknown-linux-gnu\ \t\t\texit 0\ \t\t\t;;' ./config.guess log_success "Support aarch64 adăugat la config.guess" fi fi # Dacă config.guess tot nu merge, folosește --build flag return 0 } # Funcția de setare versiune in PATCHLEVEL set_patchlevel_version() { local version="$1" local patchlevel_file="./include/patchlevel.h" if [ -z "$version" ]; then return 0 fi if [ ! -f "$patchlevel_file" ]; then log_warn "Fisierul $patchlevel_file nu exista, sar peste setarea versiunii" return 0 fi local current current=$(grep -E '^#define PATCHLEVEL ' "$patchlevel_file" | sed -E 's/^#define PATCHLEVEL "([^"]+)".*/\1/') if [ -z "$current" ]; then log_warn "Nu pot determina PATCHLEVEL curent, sar peste setarea versiunii" return 0 fi local new_patchlevel if echo "$current" | grep -q '(.*)'; then # Extract prefix before parentheses local prefix=$(echo "$current" | sed -E 's/^(.*)\([^)]*\)$/\1/') new_patchlevel="${prefix}(${version})" else new_patchlevel="UnderChat(${version})" fi sed -i "s|^#define PATCHLEVEL \".*\"|#define PATCHLEVEL \"$new_patchlevel\"|" "$patchlevel_file" log_success "Versiune setata in PATCHLEVEL: $new_patchlevel" } # Funcția de configurare configure_ircd() { log_info "Configurare UnderChat IRCd..." # Fixează config.guess pentru aarch64 fix_config_guess local config_args="--prefix=$PREFIX" config_args="$config_args --with-maxcon=$MAXCON" if [ $ENABLE_DEBUG -eq 1 ]; then config_args="$config_args --enable-debug" fi if [ $ENABLE_SSL -eq 0 ]; then config_args="$config_args --disable-ssl" fi # Adaugă --build flag pentru sisteme care nu pot detecta if [ "$(uname -m)" = "aarch64" ]; then config_args="$config_args --build=aarch64-unknown-linux-gnu" log_info "Detectat aarch64, adaugă --build=aarch64-unknown-linux-gnu" fi log_info "Parametri configure: $config_args" if [ ! -f "./configure" ]; then log_error "Fișierul configure nu găsit!" return 1 fi ./configure $config_args if [ $? -ne 0 ]; then log_error "Configurare eșuată!" return 1 fi log_success "Configurare finalizată cu succes" return 0 } # Funcția de compilare compile_ircd() { log_info "Compilare UnderChat IRCd..." # Verifică dacă autoconf este disponibil if ! command -v autoconf &> /dev/null; then log_warn "Autoconf nu este instalat, dezactivare la Makefile..." # Touchează configure pentru a evita rularea autoconf touch ./configure fi make clean > /dev/null 2>&1 make if [ $? -ne 0 ]; then log_error "Compilare eșuată!" log_warn "Încearcă: sudo apt-get install autoconf automake libtool" return 1 fi log_success "Compilare finalizată cu succes" return 0 } # Funcția de instalare install_ircd() { log_info "Instalare UnderChat IRCd..." make install if [ $? -ne 0 ]; then log_error "Instalare eșuată!" return 1 fi log_success "Instalare finalizată cu succes" return 0 } # Funcția de generare a fișierului de configurare generate_config() { local config_file="$1" local server_name="${2:-localhost.localdomain}" local server_desc="${3:-UnderChat IRCd Server}" local server_numeric="${4:-1}" local admin_location="${5:-Romania}" local admin_contact="${6:-admin@underchat.ro}" local vhost_ipv4="${7:-127.0.0.1}" local vhost_ipv6="${8:-}" local network="${9:-underchat.org}" local oper_user="${10:-AdminRoot}" local oper_pass="${11:-\$PLAIN\$password}" local is_hub="${12:-no}" local hub_config="${13:-no}" local hub_name="${14}" local hub_host="${15}" local hub_port="${16:-4400}" local hub_pass="${17}" local client_ports_list="${18}" local server_port="${19:-4400}" local ssl_ports_list="${20}" local oper_stealth="${21:-no}" # NOU: Stealth oper mode # Linie IPv6 comentata daca nu e furnizata local vhost6_line=" # vhost = \"2001:db8::1\";" local vhost6_port_4400=" # vhost = \"2001:db8::1\" $server_port;" if [ -n "$vhost_ipv6" ]; then vhost6_line=" vhost = \"$vhost_ipv6\";" vhost6_port_4400=" vhost = \"$vhost_ipv6\" $server_port;" fi # Generare blocuri Port pentru clienti local client_ports_block="" local port for port in $client_ports_list; do if [ -n "$vhost_ipv6" ]; then client_ports_block+=$'Port {\n' client_ports_block+=$' vhost = "'"$vhost_ipv4"'" '"$port"$';\n' client_ports_block+=$' vhost = "'"$vhost_ipv6"'" '"$port"$';\n' client_ports_block+=$' hidden = yes;\n'; client_ports_block+=$'}\n\n' else client_ports_block+=$'Port {\n' client_ports_block+=$' vhost = "'"$vhost_ipv4"'" '"$port"$';\n' client_ports_block+=$' # vhost = "2001:db8::1" '"$port"$';\n' client_ports_block+=$' hidden = yes;\n'; client_ports_block+=$'}\n\n' fi done # Generare blocuri Port pentru SSL local ssl_ports_block="" if [ -n "$ssl_ports_list" ]; then for port in $ssl_ports_list; do if [ -n "$vhost_ipv6" ]; then ssl_ports_block+=$'Port {\n' ssl_ports_block+=$' vhost = "'"$vhost_ipv4"'" '"$port"$';\n' ssl_ports_block+=$' vhost = "'"$vhost_ipv6"'" '"$port"$';\n' ssl_ports_block+=$' ssl = yes;\n'; ssl_ports_block+=$' hidden = yes;\n'; ssl_ports_block+=$'}\n\n' else ssl_ports_block+=$'Port {\n' ssl_ports_block+=$' vhost = "'"$vhost_ipv4"'" '"$port"$';\n' ssl_ports_block+=$' # vhost = "2001:db8::1" '"$port"$';\n' ssl_ports_block+=$' ssl = yes;\n'; ssl_ports_block+=$' hidden = yes;\n'; ssl_ports_block+=$'}\n\n' fi done else ssl_ports_block="# Porturi SSL neconfigurate" fi log_info "Generare fișier de configurare: $config_file" mkdir -p "$(dirname "$config_file")" cat > "$config_file" << EOFCONFIG # Fișier de configurare pentru UnderChat IRCd # Generat automat în data: 2026 # Limba: Română # Model: UnderChat.org Professional IRC Server # ============================================================================ # SECȚIUNE: GENERAL # ============================================================================ General { # Numele serverului (trebuie unic în rețea) name = "EOFCONFIG_NAME"; # Virtual Host - IP pe care ascultă vhost = "EOFCONFIG_VHOST4"; EOFCONFIG_VHOST6_LINE # Descrierea serverului description = "EOFCONFIG_DESC"; # Numeric-ul serverului (0-4095, trebuie unic în rețea) numeric = EOFCONFIG_NUMERIC; # Servere DNS pentru rezolvare domenii dns server = "8.8.8.8"; dns server = "1.1.1.1"; }; # ============================================================================ # SECȚIUNE: ADMIN # ============================================================================ Admin { # Locații (maxim 2) Location = "The EOFCONFIG_NETWORK World"; Location = "Location: EOFCONFIG_ADMIN_LOC"; # Contacti Contact = "IRC Admins "; }; # ============================================================================ # SECȚIUNE: CLASE DE CONEXIUNI # ============================================================================ # Clasă pentru servere principale (hub) Class { name = "Server"; pingfreq = 1 minutes 30 seconds; connectfreq = 5 minutes; maxlinks = 1; sendq = 9000000; }; # Clasă pentru servere principale (LeafServer) Class { name = "LeafServer"; pingfreq = 1 minutes 30 seconds; connectfreq = 5 minutes; maxlinks = 0; sendq = 9000000; }; # Clasă pentru clienți obișnuiți Class { name = "Local"; pingfreq = 1 minutes 30 seconds; sendq = 160000; maxlinks = 100; usermode = "+i"; }; # Clasă pentru clienți normali (implicit) Class { name = "Other"; pingfreq = 1 minutes 30 seconds; sendq = 160000; maxlinks = 2048; usermode = "+ix"; }; # Clasă pentru IRCcloud Class { name = "irccloud"; pingfreq = 1 minutes 30 seconds; sendq = 160000; maxlinks = 100; usermode = "+i"; }; # Clasa pentru IRCcloud2 Client { host = "*@*irccloud.com"; class = "irccloud"; maxlinks = 50; }; Client { class = "irccloud"; host = "*@*xshellz.com"; maxlinks = 50; }; # Clasă pentru operatori Class { name = "Opers"; pingfreq = 1 minutes 30 seconds; sendq = 160000; maxlinks = 20; local = no; freeform = yes; mode_lchan = yes; deop_lchan = yes; walk_lchan = yes; show_invis = yes; see_chan = yes; list_chan = yes; usermode = "+W"; remove = yes; }; # ============================================================================ # SECȚIUNE: CLIENT - Restricții pentru conexiuni # ============================================================================ # Configurare implicită pentru toți clienții Client { host = "*@*"; ip = "*@*"; class = "Other"; maxlinks = 3; }; #Configurare implicita pentru AUTOJOIN + mesaj Client { host = "*@*"; ip = "*@*"; class = "Other"; autojoinchannel = "#CService"; autojoinnotice = "*** Notice -- You are now being autojoined into #CService and #zT channels. Have fun!"; maxlinks = 6; }; # ============================================================================ # SECȚIUNE: JUPED NICKS - Nick-uri rezervate # ============================================================================ Jupe { # Litere și caractere speciale nick = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,{,|,},~,-,_,\`"; nick = "EuWorld,UWorld,UWorld2,Defender,Cloner,OPERServ,Oper"; nick = "login,underchat,protocol,pass,newpass,org"; nick = "LPT1,LPT2,COM1,COM2,COM3,COM4,AUX,AUTH"; # Servicii de rețea nick = "StatServ,NoteServ"; nick = "ChanServ,ChanSaver"; nick = "NickServ,NickSaver"; }; # ========================================================================== # SECȚIUNE: PORTURI # ========================================================================== # Port pentru server-to-server Port { vhost = "EOFCONFIG_VHOST4" EOFCONFIG_SERVER_PORT; EOFCONFIG_VHOST6_PORT_4400 server = yes; hidden = yes; }; # Porturi publice pentru clienți EOFCONFIG_CLIENT_PORTS # Porturi SSL/TLS pentru clienți EOFCONFIG_SSL_PORTS # ============================================================================ # SECȚIUNE: OPERATORI # ============================================================================ EOFCONFIG_OPERATOR_BLOCK # ============================================================================ # SECȚIUNE: CONNECT - Legări cu alte servere # ============================================================================ EOFCONFIG_HUB_CONNECT # ============================================================================ # SECȚIUNE: CRULE - Reguli de Conectare Inteligente (SmartRoute) # ============================================================================ EOFCONFIG_CRULES # ============================================================================ # SECȚIUNE: UWORLD - Servere de servicii # ============================================================================ UWorld { name = "services.EOFCONFIG_NETWORK"; name = "channels.EOFCONFIG_NETWORK"; name = "defender.EOFCONFIG_NETWORK"; name = "stats.EOFCONFIG_NETWORK"; name = "snoop.EOFCONFIG_NETWORK"; name = "proxyscaner.EOFCONFIG_NETWORK"; name = "proxy.EOFCONFIG_NETWORK"; }; # MOTD Server targetat pentru #motd { # host = "*.net"; # file = "net.motd"; #}; #motd { # host = "*.ro"; # file = "ro.motd"; #}; #motd { # host = "*.hu"; # file = "hu.motd"; #}; # ============================================================================ # SECȚIUNE: PSEUDO - Alias-uri Comenzi pentru Servicii # ============================================================================ EOFCONFIG_PSEUDO # ============================================================================ # SECȚIUNE: SPOOFHOST - Mascarea Hostname-urilor # ============================================================================ EOFCONFIG_SPOOFHOST # ============================================================================ # SECȚIUNE: WEBIRC - Gateway-uri Web-to-IRC # ============================================================================ EOFCONFIG_WEBIRC # ============================================================================ # SECȚIUNE: FEATURE - Caracteristici și setări # ============================================================================ features { # Network details "NETWORK" = "EOFCONFIG_NETWORK"; "DOMAINNAME" = "EOFCONFIG_NETWORK"; # Logging "LOG" = "SYSTEM" "FILE" "$PREFIX/log/ircd.log"; "LOG" = "SYSTEM" "LEVEL" "CRIT"; # Server settings "HUB" = "EOFCONFIG_HUB_SETTING"; "RELIABLE_CLOCK" = "FALSE"; "WALLOPS_OPER_ONLY" = "TRUE"; "NODNS" = "FALSE"; "NOIDENT" = "FALSE"; # Client settings "CLIENT_FLOOD" = "1024"; "BUFFERPOOL" = "27000000"; "DEFAULTMAXSENDQLENGTH" = "40000"; # Anti-Clone Protection (CRITIC!) "IPCHECK_CLONE_LIMIT" = "4"; "IPCHECK_CLONE_PERIOD" = "40"; "IPCHECK_CLONE_DELAY" = "600"; # Security & Anti-Abuse "AUTH_TIMEOUT" = "9"; "IRCD_RES_TIMEOUT" = "4"; "IRCD_RES_RETRIES" = "2"; "GLINEMAXUSERCOUNT" = "20"; "TARGET_LIMITING" = "TRUE"; "IDLE_FROM_MSG" = "TRUE"; # Extended Accounts Support (pentru servicii IRC) # TRUE = X3 modern cu sintaxă extinsă (R,M,U,C,A,D,H) # FALSE = Sintaxă standard (X, Anope 1.x, majoritatea serviciilor) "EXTENDED_ACCOUNTS" = "FALSE"; # Host hiding "HOST_HIDING" = "TRUE"; "HOST_HIDING_STYLE" = "3"; "HIDDEN_HOST" = "users.EOFCONFIG_NETWORK"; "HIDDEN_IP" = "127.0.0.1"; "HOST_HIDING_PREFIX" = "UnderChat"; "HOST_HIDING_KEY1" = "aoAr1HnR6gl3sJ7hVz4Zb7x4YwpW"; "HOST_HIDING_KEY2" = "sdfjkLJKHlkjdkfjsdklfjlkjKLJ"; "HOST_HIDING_KEY3" = "KJklJSDFLkjLKDFJSLKjlKJFlkjS"; "HOST_HIDING_COMPONENTS" = "1"; # Host hiding - Mesaje set/unset +x "HIDDEN_HOST_QUIT" = "TRUE"; "HIDDEN_HOST_SET_MESSAGE" = "Registered"; "HIDDEN_HOST_UNSET_MESSAGE" = "UnRegistered"; # Channels "MAXCHANNELSPERUSER" = "60"; "CHANNELLEN" = "200"; "MAXBANS" = "50"; # Nick settings "NICKLEN" = "12"; "NICKNAMEHISTORYLENGTH" = "800"; # Timing "HANGONGOODLINK" = "300"; "HANGONRETRYDELAY" = "10"; "CONNECTTIMEOUT" = "90"; "PINGFREQUENCY" = "120"; "CONNECTFREQUENCY" = "600"; # Welcome messages - toate în lib/ ca directorul principal "MPATH" = "$PREFIX/lib/ircd.motd"; "RPATH" = "$PREFIX/lib/remote.motd"; "PPATH" = "$PREFIX/var/ircd.pid"; # Stats visibility "HIS_STATS_u" = "FALSE"; "HIS_STATS_U" = "TRUE"; "HIS_STATS_a" = "TRUE"; "HIS_STATS_c" = "TRUE"; "HIS_STATS_d" = "TRUE"; "HIS_STATS_e" = "TRUE"; "HIS_STATS_f" = "TRUE"; "HIS_STATS_g" = "TRUE"; "HIS_STATS_i" = "TRUE"; "HIS_STATS_j" = "TRUE"; "HIS_STATS_J" = "TRUE"; "HIS_STATS_k" = "TRUE"; "HIS_STATS_l" = "TRUE"; "HIS_STATS_L" = "TRUE"; "HIS_STATS_m" = "TRUE"; "HIS_STATS_M" = "TRUE"; "HIS_STATS_o" = "TRUE"; "HIS_STATS_p" = "TRUE"; "HIS_STATS_q" = "TRUE"; "HIS_STATS_r" = "TRUE"; "HIS_STATS_R" = "TRUE"; "HIS_STATS_S" = "TRUE"; "HIS_STATS_s" = "TRUE"; "HIS_STATS_t" = "TRUE"; "HIS_STATS_T" = "TRUE"; "HIS_STATS_v" = "TRUE"; "HIS_STATS_w" = "TRUE"; "HIS_STATS_x" = "TRUE"; "HIS_STATS_y" = "TRUE"; "HIS_STATS_z" = "TRUE"; "HIS_STATS_Z" = "TRUE"; "HIS_STATS_W" = "TRUE"; "HIS_STATS_E" = "TRUE"; "HIS_STATS_IAUTH" = "TRUE"; # Whois privacy "HIS_WHOIS_SERVERNAME" = "TRUE"; "HIS_WHOIS_IDLETIME" = "TRUE"; "HIS_WHOIS_LOCALCHAN" = "TRUE"; # Who privacy "HIS_WHO_SERVERNAME" = "TRUE"; "HIS_WHO_HOPCOUNT" = "TRUE"; # Network info "HIS_NETSPLIT" = "TRUE"; "HIS_SERVERNAME" = "*.EOFCONFIG_NETWORK"; "HIS_SERVERINFO" = "The EOFCONFIG_NETWORK World"; # Privacy - Hide network topology "HIS_SNOTICES" = "TRUE"; "HIS_SNOTICES_OPER_ONLY" = "TRUE"; "HIS_DEBUG_OPER_ONLY" = "TRUE"; "HIS_WALLOPS" = "TRUE"; "HIS_MAP" = "TRUE"; "HIS_LINKS" = "TRUE"; "HIS_TRACE" = "TRUE"; "HIS_MODEWHO" = "TRUE"; "HIS_BANWHO" = "TRUE"; "HIS_KILLWHO" = "FALSE"; "HIS_REWRITE" = "TRUE"; "HIS_REMOTE" = "TRUE"; "HIS_IRCOPS" = "TRUE"; "HIS_IRCOPS_SERVERS" = "TRUE"; # Network URLs "HIS_URLSERVERS" = "http://EOFCONFIG_NETWORK/servers"; "URLREG" = "http://cservice.EOFCONFIG_NETWORK/live/"; # Operational "CHECK" = "TRUE"; "CHECK_EXTENDED" = "TRUE"; "MAX_CHECK_OUTPUT" = "1000"; "OPER_WHOIS_PARANOIA" = "TRUE"; # Admin commands "SETHOST" = "TRUE"; "NETWORK_REHASH" = "TRUE"; # Channel modes "HALFOPS" = "TRUE"; "CHMODE_c" = "TRUE"; "CHMODE_C" = "TRUE"; "CHMODE_M" = "TRUE"; "CHMODE_N" = "TRUE"; "CHMODE_m_NONICKCHANGE" = "TRUE"; "EXCEPTS" = "TRUE"; "MAXEXCEPTS" = "45"; # Channel modes extra "CHMODE_a" = "TRUE"; "CHMODE_L" = "TRUE"; "CHMODE_O" = "TRUE"; "CHMODE_Q" = "TRUE"; "CHMODE_S" = "TRUE"; "CHMODE_T" = "TRUE"; # Extended Bans "EXTBANS" = "TRUE"; "EXTBAN_a" = "TRUE"; "EXTBAN_c" = "TRUE"; "EXTBAN_j" = "TRUE"; "EXTBAN_n" = "TRUE"; "EXTBAN_q" = "TRUE"; "EXTBAN_r" = "TRUE"; "EXTBAN_m" = "TRUE"; "EXTBAN_M" = "TRUE"; # IRCv3 Capabilities "CAP_multi_prefix" = "TRUE"; "CAP_userhost_in_names" = "TRUE"; "CAP_extended_join" = "TRUE"; "CAP_away_notify" = "TRUE"; "CAP_account_notify" = "TRUE"; "CAP_tls" = "TRUE"; # GeoIP "GEOIP_ENABLE" = "TRUE"; "MMDB_FILE" = "GeoLite2-Country.mmdb"; "GEOIP_FILE" = "GeoIP.dat"; "GEOIP_IPV6_FILE" = "GeoIPv6.dat"; # SASL Authentication "CAP_sasl" = "TRUE"; # Diverse features "MAXSILES" = "15"; "LISTDELAY" = "15"; "ANNOUNCE_INVITES" = "TRUE"; "MAXWATCHS" = "128"; "SILENCE_CHANMSGS" = "TRUE"; "CONNEXIT_NOTICES" = "TRUE"; "CONFIG_OPERCMDS" = "TRUE"; "OPER_HIDE" = "TRUE"; # Operatori - Mesaje Custom "WHOIS_OPER" = "is an UnderChat Staff Member"; "WHOIS_SERVICE" = "is an UnderChat Network Service"; "WHOIS_ADMIN" = "is an UnderChat Founder"; "OPERMOTD" = "TRUE"; "OMPATH" = "$PREFIX/lib/ircd.opermotd"; # SSL/TLS "SSL_CERTFILE" = "$PREFIX/lib/ircd.pem"; "SSL_KEYFILE" = "$PREFIX/lib/ircd.pem"; "SSL_NOSSLV2" = "TRUE"; # CTCP versioning "CTCP_VERSIONING" = "FALSE"; # Server notice masks "SNOMASK_OPERDEFAULT" = "1024"; "SNOMASK_DEFAULT" = "1024"; }; EOFCONFIG # Generare bloc Operator (vizibil sau invizibil) local operator_block="" if [ "$oper_stealth" = "yes" ]; then # Operator INVIZIBIL (stealth mode) operator_block="# Operator INVIZIBIL (Stealth Mode) # NU apare în /WHOIS ca staff, hostname normal ca user obișnuit Operator { name = \"EOFCONFIG_OPER_USER\"; password = \"EOFCONFIG_OPER_PASS\"; host = \"*@*\"; class = \"Opers\"; admin = yes; snomask = 157445; # FĂRĂ swhois = NU apare \"is an UnderChat Staff Member\" hide_oper = yes; # Ascunde din /STATS o hide_channels = yes; # Ascunde canalele în /WHOIS whois_notice = no; # NU trimite notice când primești /WHOIS };" else # Operator VIZIBIL (standard) operator_block="# Operator VIZIBIL (Standard Mode) # Apare în /WHOIS ca staff, hostname Staff.Network Operator { name = \"EOFCONFIG_OPER_USER\"; password = \"EOFCONFIG_OPER_PASS\"; host = \"*@*\"; class = \"Opers\"; admin = yes; snomask = 157445; swhois = \"is an UnderChat Staff Member\"; hide_oper = no; # Vizibil în /STATS o hide_channels = yes; # Ascunde canalele în /WHOIS whois_notice = yes; # Trimite notice când primești /WHOIS };" fi # Înlocuiește placeholder-ele sed -i "s|EOFCONFIG_NAME|$server_name|g" "$config_file" sed -i "s|EOFCONFIG_DESC|$server_desc|g" "$config_file" sed -i "s|EOFCONFIG_NUMERIC|$server_numeric|g" "$config_file" sed -i "s|EOFCONFIG_PREFIX|$PREFIX|g" "$config_file" sed -i "s|EOFCONFIG_NETWORK|$network_name|g" "$config_file" sed -i "s|EOFCONFIG_ADMIN_LOC|$admin_location|g" "$config_file" sed -i "s|EOFCONFIG_ADMIN_CONTACT|$admin_contact|g" "$config_file" sed -i "s|EOFCONFIG_VHOST4|$vhost_ipv4|g" "$config_file" sed -i "s|EOFCONFIG_VHOST6_LINE|$vhost6_line|g" "$config_file" sed -i "s|EOFCONFIG_VHOST6_PORT_4400|$vhost6_port_4400|g" "$config_file" sed -i "s|EOFCONFIG_SERVER_PORT|$server_port|g" "$config_file" sed -i "s|EOFCONFIG_CLIENT_PORTS|$client_ports_block|g" "$config_file" sed -i "s|EOFCONFIG_SSL_PORTS|$ssl_ports_block|g" "$config_file" # Înlocuire bloc Operator cu awk (pentru a păstra newlines) awk -v operator="$operator_block" ' /EOFCONFIG_OPERATOR_BLOCK/ { print operator next } { print } ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" sed -i "s|EOFCONFIG_OPER_USER|$oper_user|g" "$config_file" sed -i "s|EOFCONFIG_OPER_PASS|$oper_pass|g" "$config_file" # Setare HUB flag if [ "$is_hub" = "y" ] || [ "$is_hub" = "Y" ]; then sed -i 's|EOFCONFIG_HUB_SETTING|TRUE|g' "$config_file" else sed -i 's|EOFCONFIG_HUB_SETTING|FALSE|g' "$config_file" fi # Generare CONNECT section pentru link server-to-server (independent de HUB/LEAF) if [ "$hub_config" = "yes" ]; then # Escape-uim caracterele speciale pentru sed hub_name_escaped=$(printf '%s\n' "$hub_name" | sed 's:[][\/.^$*]:\\&:g') hub_host_escaped=$(printf '%s\n' "$hub_host" | sed 's:[][\/.^$*]:\\&:g') hub_pass_escaped=$(printf '%s\n' "$hub_pass" | sed 's:[][\/.^$*|]:\\&:g') # Generăm blocul Connect folosind awk pentru înlocuire sigură awk -v name="$hub_name_escaped" -v host="$hub_host_escaped" -v pass="$hub_pass_escaped" -v port="$hub_port" ' /EOFCONFIG_HUB_CONNECT/ { print "# Conectare server-to-server" print "Connect {" print " name = \"" name "\";" print " host = \"" host "\";" print " password = \"" pass "\";" print " port = " port ";" print " class = \"Server\";" print " autoconnect = yes;" print " hub;" print "};" next } { print } ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" else sed -i 's|EOFCONFIG_HUB_CONNECT|# Niciun link server-to-server configurat|g' "$config_file" fi # Generare CRULE section (dacă există) if [ -n "$CRULE_CONFIG" ]; then # Escape-uim CRULE_CONFIG pentru awk awk -v crule="$CRULE_CONFIG" ' /EOFCONFIG_CRULES/ { print crule next } { print } ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" else sed -i 's|EOFCONFIG_CRULES|# CRULE: Neconfigurata|g' "$config_file" fi # Generare PSEUDO section (dacă există) if [ -n "$PSEUDO_CONFIG" ]; then awk -v pseudo="$PSEUDO_CONFIG" ' /EOFCONFIG_PSEUDO/ { print pseudo next } { print } ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" else sed -i 's|EOFCONFIG_PSEUDO|# PSEUDO: Neconfigurata|g' "$config_file" fi # Generare SPOOFHOST section (dacă există) if [ -n "$SPOOFHOST_CONFIG" ]; then awk -v spoofhost="$SPOOFHOST_CONFIG" ' /EOFCONFIG_SPOOFHOST/ { print spoofhost next } { print } ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" else sed -i 's|EOFCONFIG_SPOOFHOST|# SPOOFHOST: Neconfigurata|g' "$config_file" fi # Generare WEBIRC section (dacă există) if [ -n "$WEBIRC_CONFIG" ]; then awk -v webirc="$WEBIRC_CONFIG" ' /EOFCONFIG_WEBIRC/ { print webirc next } { print } ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" else sed -i 's|EOFCONFIG_WEBIRC|# WEBIRC: Neconfigurata|g' "$config_file" fi log_success "Fișier de configurare generat: $config_file" return 0 } # Funcția principală main() { # Parsare argumente while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help exit 0 ;; -p|--prefix) PREFIX="$2" shift 2 ;; -m|--maxcon) if ! is_positive_int "$2"; then log_error "Valoare invalidă pentru --maxcon: $2" exit 1 fi MAXCON="$2" MAXCON_SET=1 shift 2 ;; -d|--debug) ENABLE_DEBUG=1 shift ;; -s|--no-ssl) ENABLE_SSL=0 shift ;; -c|--config) CONFIG_FILE="$2" shift 2 ;; -V|--version) IRCD_VERSION="$2" shift 2 ;; *) log_error "Optiune necunoscuta: $1" show_help exit 1 ;; esac done echo -e "${ALBASTRU}" echo "=========================================" echo " Instalare UnderChat IRCd" echo "=========================================" echo -e "${NC}" # Cerere max conexiuni (doar dacă nu a fost setat din argumente) if [ $MAXCON_SET -eq 0 ]; then echo "" while true; do read -p " Maxim conexiuni [${MAXCON}]: " maxcon_input if [ -z "$maxcon_input" ]; then break fi if is_positive_int "$maxcon_input"; then MAXCON="$maxcon_input" break fi log_error "Maxim conexiuni trebuie să fie un număr întreg pozitiv." done fi # Verificare dependențe check_dependencies if [ $? -ne 0 ]; then exit 1 fi # Verificare și aplicare fix-uri de securitate (CRITIC!) echo "" echo -e "${ALBASTRU}═══════════════════════════════════════${NC}" echo -e "${ALBASTRU}VERIFICARE SECURITATE${NC}" echo -e "${ALBASTRU}═══════════════════════════════════════${NC}" check_and_apply_security_fixes if [ $? -ne 0 ]; then log_error "Verificare securitate eșuată!" exit 1 fi # Setare versiune (optional) set_patchlevel_version "$IRCD_VERSION" # Configurare configure_ircd if [ $? -ne 0 ]; then exit 1 fi # Compilare compile_ircd if [ $? -ne 0 ]; then exit 1 fi # Instalare install_ircd if [ $? -ne 0 ]; then exit 1 fi # Generare fișier de configurare local conf_file="${PREFIX}/lib/ircd.conf" if [ -z "$CONFIG_FILE" ]; then # Citire interactivă de parametri echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE SERVER${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" read -p " Domeniu rețea [underchat.org]: " network_name network_name=${network_name:-underchat.org} read -p " Nume server [ns1.${network_name}]: " server_name server_name=${server_name:-ns1.${network_name}} read -p " Descriere server [The ${network_name} Network]: " server_desc server_desc=${server_desc:-The ${network_name} Network} # IPv4 while true; do read -p " Virtual Host / IP (IPv4) [127.0.0.1]: " vhost_ipv4 vhost_ipv4=${vhost_ipv4:-127.0.0.1} if is_ipv4 "$vhost_ipv4"; then break fi log_error "IPv4 invalid. Exemplu: 192.168.1.10" done # IPv6 (auto-detect) local auto_ipv6 auto_ipv6=$(detect_ipv6_global) while true; do if [ -n "$auto_ipv6" ]; then read -p " Virtual Host / IP (IPv6) [${auto_ipv6}] ("'"'"'"-"'"'"'" pentru gol): " vhost_ipv6 if [ "$vhost_ipv6" = "-" ]; then vhost_ipv6="" break fi vhost_ipv6=${vhost_ipv6:-$auto_ipv6} else read -p " Virtual Host / IP (IPv6) [gol pentru comentat]: " vhost_ipv6 vhost_ipv6=${vhost_ipv6:-} fi if [ -z "$vhost_ipv6" ] || is_ipv6 "$vhost_ipv6"; then break fi log_error "IPv6 invalid. Exemplu: 2001:db8::1" done # Port server-to-server while true; do read -p " Port server-to-server [${SERVER_PORT}]: " server_port_input server_port_input=${server_port_input:-$SERVER_PORT} if is_positive_int "$server_port_input" && [ "$server_port_input" -ge 1 ] && [ "$server_port_input" -le 65535 ]; then SERVER_PORT="$server_port_input" break fi log_error "Port invalid. Exemplu: 4400" done # Porturi publice IRC (clienti) local default_ports="6660-6669,7000" while true; do read -p " Porturi publice IRC [${default_ports}]: " client_ports_input client_ports_input=${client_ports_input:-$default_ports} client_ports_list=$(expand_ports "$client_ports_input") if [ $? -eq 0 ]; then break fi log_error "Format invalid. Exemple: 5000-5002,6000 sau 6667" done # Porturi SSL pentru clienti if [ $ENABLE_SSL -eq 1 ]; then while true; do read -p " Porturi SSL IRC [${SSL_PORTS_DEFAULT}] (gol pentru a sari): " ssl_ports_input if [ -z "$ssl_ports_input" ]; then ssl_ports_list="" break fi ssl_ports_list=$(expand_ports "$ssl_ports_input") if [ $? -eq 0 ]; then break fi log_error "Format invalid. Exemple: 6697,7001 sau 7000-7002" done else ssl_ports_list="" fi read -p " Numeric server [1]: " server_numeric server_numeric=${server_numeric:-1} read -p " Locație admin [Romania]: " admin_location admin_location=${admin_location:-Romania} read -p " Contact admin [admin@${network_name}]: " admin_contact admin_contact=${admin_contact:-admin@${network_name}} # Configurare Operator echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE OPERATOR${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" read -p " Username operator [AdminRoot]: " oper_username oper_username=${oper_username:-AdminRoot} # Cerere parola și validare while true; do read -s -p " Parola operator: " oper_password echo "" if ! validate_password "$oper_password"; then log_error "Parola prea scurtă! Minim 4 caractere." continue fi read -s -p " Repetă parola: " oper_password_confirm echo "" if [ "$oper_password" != "$oper_password_confirm" ]; then log_error "Parolele nu se potrivesc!" continue fi # Generare hash folosind umkpasswd (dacă este disponibil) log_info "Generare hash parola criptată..." # Verifică dacă umkpasswd există (după instalare) if [ -f "$PREFIX/bin/umkpasswd" ]; then # Folosește umkpasswd pentru a genera hash MD5 oper_hash=$("$PREFIX/bin/umkpasswd" -m md5 "$oper_password" 2>/dev/null | grep '^\$' | head -1) if [ -z "$oper_hash" ]; then # Fallback la $PLAIN$ dacă umkpasswd eșuează log_warn "umkpasswd eșuat, folosim $PLAIN$ temporar" oper_hash="\$PLAIN\$$oper_password" else log_success "Parola operator criptată cu MD5: ${oper_hash:0:20}..." fi else # umkpasswd nu există încă, folosim $PLAIN$ temporar log_warn "umkpasswd nu este disponibil, folosim $PLAIN$ temporar" log_warn "După instalare, rulează: $PREFIX/bin/umkpasswd -m md5 și actualizează parola" oper_hash="\$PLAIN\$$oper_password" fi log_success "Parola operator criptată" break done # Configurare Stealth Mode (Oper Invizibil) echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}MOD OPERATOR${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo "" echo " Alege modul de operator:" echo "" echo " ${VERDE}1) VIZIBIL${NC} (standard, recomandat)" echo " - Apare în /WHOIS: 'is an UnderChat Staff Member'" echo " - Hostname: username.Staff.UnderChat.org" echo " - Vizibil în /STATS o" echo "" echo " ${ALBASTRU}2) INVIZIBIL${NC} (stealth mode)" echo " - NU apare mesaj staff în /WHOIS" echo " - Hostname NORMAL ca un user obișnuit" echo " - Ascuns din /STATS o" echo " - Păstrezi TOATE privilegiile de oper!" echo "" read -p " Alege [1-2] [1]: " oper_mode_choice oper_mode_choice=${oper_mode_choice:-1} if [ "$oper_mode_choice" = "2" ]; then OPER_STEALTH_MODE="yes" log_info "Mod INVIZIBIL activat - Vei fi oper stealth!" else OPER_STEALTH_MODE="no" log_info "Mod VIZIBIL activat - Staff clasic" fi # Configurare HUB echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE HUB${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" read -p " Este aceasta un server HUB? (y/n) [n]: " is_hub is_hub=${is_hub:-n} # Configurare LINK server-to-server (independent de HUB/LEAF) echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE LINK SERVER-TO-SERVER${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo "" echo " Doriți să configurați un link către alt server IRC?" echo " (Necesar pentru rețele cu multiple servere)" echo "" read -p " Configurare link server-to-server? (y/n) [n]: " configure_link configure_link=${configure_link:-n} if [ "$configure_link" = "y" ] || [ "$configure_link" = "Y" ]; then echo "" log_info "Configurare conexiune server-to-server" echo "" read -p " Nume server remote [hub.${network_name}]: " hub_name hub_name=${hub_name:-hub.${network_name}} read -p " IP/Host server remote [10.0.0.100]: " hub_host hub_host=${hub_host:-10.0.0.100} read -p " Port server-to-server [4400]: " hub_port hub_port=${hub_port:-4400} read -s -p " Parola link server: " hub_password echo "" HUB_CONFIG="yes" else HUB_CONFIG="no" hub_name="" hub_host="" hub_port="" hub_password="" fi # Configurare CRULE (Connection Rules pentru rețele multi-server) echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE CRULE (Reguli Conexiune)${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo "" echo " CRULE permite optimizarea topologiei rețelei IRC." echo " Previne link-uri redundante între servere." echo "" echo " Exemplu: Dacă ai servere în EU și US, CRULE poate" echo " limita la 1 singur link EU-US în loc de multiple." echo "" read -p " Configurare CRULE pentru optimizare rețea? (y/n) [n]: " configure_crule configure_crule=${configure_crule:-n} if [ "$configure_crule" = "y" ] || [ "$configure_crule" = "Y" ]; then echo "" log_info "Configurare CRULE pentru rețea multi-server" echo "" echo " Selectați tipul de optimizare:" echo " 1) Previne link-uri redundante către o regiune (recomandat)" echo " 2) Necesită operator online pentru link-uri" echo " 3) Ambele (1+2)" echo " 4) Custom (configurare manuală ulterior)" echo "" read -p " Opțiune [1]: " crule_option crule_option=${crule_option:-1} case $crule_option in 1) echo "" read -p " Regiune/pattern de blocat (ex: *.eu.*, *.us.*, *.asia.*) [*.eu.*]: " crule_pattern crule_pattern=${crule_pattern:-*.eu.*} CRULE_CONFIG="# Previne link-uri redundante către ${crule_pattern} CRule { server = \"${crule_pattern}\"; all = no; rule = \"connected(${crule_pattern})\"; };" log_success "CRULE: Blocare link-uri redundante către ${crule_pattern}" ;; 2) echo "" read -p " Pattern servere care necesită oper (ex: *.test.*, *.risky.*) [*.test.*]: " crule_pattern crule_pattern=${crule_pattern:-*.test.*} CRULE_CONFIG="# Necesită operator online pentru ${crule_pattern} CRule { server = \"${crule_pattern}\"; all = no; rule = \"!directop()\"; };" log_success "CRULE: Necesită oper pentru link-uri către ${crule_pattern}" ;; 3) echo "" read -p " Regiune de blocat (ex: *.eu.*, *.us.*) [*.eu.*]: " crule_pattern1 crule_pattern1=${crule_pattern1:-*.eu.*} read -p " Pattern servere care necesită oper [*.test.*]: " crule_pattern2 crule_pattern2=${crule_pattern2:-*.test.*} CRULE_CONFIG="# Previne link-uri redundante către ${crule_pattern1} CRule { server = \"${crule_pattern1}\"; all = no; rule = \"connected(${crule_pattern1})\"; }; # Necesită operator online pentru ${crule_pattern2} CRule { server = \"${crule_pattern2}\"; all = no; rule = \"!directop()\"; };" log_success "CRULE: Configurare multiplă aplicată" ;; 4) CRULE_CONFIG="# CRULE: Configurare custom # Editează manual /home/ircd/ircd/lib/ircd.conf # Vezi documentația: CRULE_EXPLAINED.md # Exemplu: # CRule { # server = \"*.eu.underchat.org\"; # all = no; # rule = \"connected(*.eu.underchat.org)\"; # };" log_info "CRULE: Placeholder pentru configurare manuală" ;; *) CRULE_CONFIG="# CRULE neactivat" log_warn "Opțiune invalidă, CRULE dezactivat" ;; esac else CRULE_CONFIG="# CRULE: Neconfigurata # Pentru rețele cu multiple servere, CRULE poate optimiza topologia. # Vezi documentația: CRULE_EXPLAINED.md" log_info "CRULE: Neconfigurata (opțional pentru rețele mari)" fi # Configurare PSEUDO (Alias-uri pentru servicii) echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE PSEUDO (Alias-uri Servicii)${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo "" echo " PSEUDO permite utilizatorilor să folosească comenzi simple" echo " pentru servicii IRC (ex: /NICKSERV în loc de /MSG NickServ@...)" echo "" echo " Necesar DOAR dacă ai instalat servicii IRC (Anope/Atheme)." echo "" read -p " Configurare PSEUDO pentru servicii? (y/n) [n]: " configure_pseudo configure_pseudo=${configure_pseudo:-n} if [ "$configure_pseudo" = "y" ] || [ "$configure_pseudo" = "Y" ]; then echo "" log_info "Configurare PSEUDO pentru servicii IRC" echo "" read -p " Nume server servicii [services.${network_name}]: " services_server services_server=${services_server:-services.${network_name}} PSEUDO_CONFIG="# Alias-uri pentru servicii IRC # Serviciile trebuie să fie active pe: ${services_server} # NickServ - Management nickname-uri Pseudo \"NICKSERV\" { name = \"NickServ\"; nick = \"NickServ@${services_server}\"; }; # LOGIN - Management nickname-uri Pseudo \"LOGIN\" { name = \"X\"; nick = \"X@${services_server}\"; }; # Alias scurt NS pentru NickServ Pseudo \"NS\" { name = \"NickServ\"; nick = \"NickServ@${services_server}\"; }; # ChanServ - Management canale Pseudo \"CHANSERV\" { name = \"ChanServ\"; nick = \"ChanServ@${services_server}\"; }; # Alias scurt CS pentru ChanServ Pseudo \"CS\" { name = \"ChanServ\"; nick = \"ChanServ@${services_server}\"; }; # MemoServ - Mesaje offline Pseudo \"MEMOSERV\" { name = \"MemoServ\"; nick = \"MemoServ@${services_server}\"; }; # Alias scurt MS pentru MemoServ Pseudo \"MS\" { name = \"MemoServ\"; nick = \"MemoServ@${services_server}\"; }; # OperServ - Comenzi operatori Pseudo \"OPERSERV\" { name = \"OperServ\"; nick = \"OperServ@${services_server}\"; }; # Alias scurt OS pentru OperServ Pseudo \"OS\" { name = \"OperServ\"; nick = \"OperServ@${services_server}\"; };" log_success "PSEUDO: Configurat pentru ${services_server}" else PSEUDO_CONFIG="# PSEUDO: Neconfigurata # Adaugă manual Pseudo blocks dacă ai servicii IRC (Anope/Atheme). # Vezi documentația: PSEUDO_EXPLAINED.md" log_info "PSEUDO: Neconfigurata (opțional pentru servicii)" fi # Configurare SPOOFHOST (Mascarea hostname-urilor) echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE SPOOFHOST (Mascare Hostname)${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo "" echo " SPOOFHOST permite mascarea hostname-urilor utilizatorilor" echo " pentru protecție identitate și brandind custom." echo "" echo " Exemplu: user@203.0.113.45 → user@staff.${network_name}" echo "" read -p " Configurare SPOOFHOST pentru protecție? (y/n) [n]: " configure_spoofhost configure_spoofhost=${configure_spoofhost:-n} if [ "$configure_spoofhost" = "y" ] || [ "$configure_spoofhost" = "Y" ]; then echo "" log_info "Configurare SPOOFHOST pentru mascarea hostname-urilor" echo "" echo " Selectați tipul de configurare:" echo " 1) Staff automat (pentru IP-uri interne)" echo " 2) VIP manual (cu parolă)" echo " 3) Protecție generală (pentru toți utilizatorii)" echo " 4) Toate (1+2+3)" echo "" read -p " Opțiune [1]: " spoofhost_option spoofhost_option=${spoofhost_option:-1} case $spoofhost_option in 1) echo "" read -p " Pattern IP staff (ex: *@10.0.0.*) [*@10.0.0.*]: " staff_pattern staff_pattern=${staff_pattern:-*@10.0.0.*} SPOOFHOST_CONFIG="# Staff automat pentru ${staff_pattern} Spoofhost \"staff.${network_name}\" { host = \"${staff_pattern}\"; autoapply = yes; };" log_success "SPOOFHOST: Configurare staff pentru ${staff_pattern}" ;; 2) echo "" read -p " Hostname VIP [vip.${network_name}]: " vip_hostname vip_hostname=${vip_hostname:-vip.${network_name}} read -s -p " Parola VIP: " vip_password echo "" SPOOFHOST_CONFIG="# VIP manual cu parolă Spoofhost \"${vip_hostname}\" { pass = \"${vip_password}\"; host = \"*\"; autoapply = no; };" log_success "SPOOFHOST: Configurare VIP pentru ${vip_hostname}" ;; 3) SPOOFHOST_CONFIG="# Protecție generală pentru toți utilizatorii Spoofhost \"users.${network_name}\" { host = \"*\"; autoapply = yes; };" log_success "SPOOFHOST: Protecție generală activată" ;; 4) echo "" read -p " Pattern IP staff [*@10.0.0.*]: " staff_pattern staff_pattern=${staff_pattern:-*@10.0.0.*} read -p " Hostname VIP [vip.${network_name}]: " vip_hostname vip_hostname=${vip_hostname:-vip.${network_name}} read -s -p " Parola VIP: " vip_password echo "" SPOOFHOST_CONFIG="# Staff automat pentru ${staff_pattern} Spoofhost \"staff.${network_name}\" { host = \"${staff_pattern}\"; autoapply = yes; }; # VIP manual cu parolă Spoofhost \"${vip_hostname}\" { pass = \"${vip_password}\"; host = \"*\"; autoapply = no; }; # Protecție generală pentru toți utilizatorii Spoofhost \"users.${network_name}\" { host = \"*\"; autoapply = yes; };" log_success "SPOOFHOST: Configurare completă aplicată" ;; *) SPOOFHOST_CONFIG="# SPOOFHOST neactivat" log_warn "Opțiune invalidă, SPOOFHOST dezactivat" ;; esac else SPOOFHOST_CONFIG="# SPOOFHOST: Neconfigurata # Adaugă manual Spoofhost blocks pentru mascarea hostname-urilor. # Vezi documentația: SPOOFHOST_EXPLAINED.md" log_info "SPOOFHOST: Neconfigurata (opțional pentru protecție)" fi # Configurare WEBIRC (Gateway Web-to-IRC) echo "" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo -e "${GALBEN}CONFIGURARE WEBIRC (Gateway Web-to-IRC)${NC}" echo -e "${GALBEN}═══════════════════════════════════════${NC}" echo "" echo " WEBIRC permite clienților IRC web (Kiwi IRC, TheLounge)" echo " să transmită IP-ul REAL al utilizatorilor către server." echo "" echo " FĂRĂ WebIRC: Toți web users apar cu IP-ul serverului web" echo " CU WebIRC: Fiecare user are IP-ul său real vizibil" echo "" echo " Necesar DOAR dacă ai un client IRC web (ex: Kiwi IRC)." echo "" read -p " Configurare WEBIRC pentru web gateway? (y/n) [n]: " configure_webirc configure_webirc=${configure_webirc:-n} if [ "$configure_webirc" = "y" ] || [ "$configure_webirc" = "Y" ]; then echo "" log_info "Configurare WEBIRC pentru gateway web-to-IRC" echo "" read -p " IP/Host server web (ex: 203.0.113.50, chat.domain.org) [127.0.0.1]: " webirc_host webirc_host=${webirc_host:-127.0.0.1} read -s -p " Parola WebIRC (shared secret): " webirc_password echo "" if [ -z "$webirc_password" ]; then webirc_password="webirc_$(openssl rand -hex 8 2>/dev/null || date +%s)" log_warn "Parola generată automat: ${webirc_password}" fi read -p " Descriere gateway (ex: Kiwi IRC, TheLounge) [Web Gateway]: " webirc_description webirc_description=${webirc_description:-Web Gateway} echo "" read -p " Setări avansate? (y/n) [n]: " webirc_advanced webirc_advanced=${webirc_advanced:-n} if [ "$webirc_advanced" = "y" ] || [ "$webirc_advanced" = "Y" ]; then read -p " Ident fix pentru web users (ex: webchat) [webchat]: " webirc_ident webirc_ident=${webirc_ident:-webchat} WEBIRC_CONFIG="# Gateway Web-to-IRC pentru ${webirc_host} WebIRC { host = \"*@${webirc_host}\"; password = \"\$PLAIN\$${webirc_password}\"; description = \"${webirc_description}\"; ident = \"${webirc_ident}\"; userident = no; ignoreident = yes; stripsslfp = yes; enableoptions = yes; };" log_success "WEBIRC: Configurare avansată pentru ${webirc_host}" else WEBIRC_CONFIG="# Gateway Web-to-IRC pentru ${webirc_host} WebIRC { host = \"*@${webirc_host}\"; password = \"\$PLAIN\$${webirc_password}\"; description = \"${webirc_description}\"; };" log_success "WEBIRC: Configurare simplă pentru ${webirc_host}" fi echo "" echo -e "${VERDE}═══════════════════════════════════════${NC}" echo -e "${VERDE}IMPORTANT - Configurare Web Client${NC}" echo -e "${VERDE}═══════════════════════════════════════${NC}" echo "" echo " În Kiwi IRC (config.ini):" echo " [webirc]" echo " password = ${webirc_password}" echo "" echo " În TheLounge (config.js):" echo " webirc: {" echo " \"${network_name}\": {" echo " password: \"${webirc_password}\"" echo " }" echo " }" echo "" log_warn "SALVEAZĂ această parolă pentru configurarea web client-ului!" else WEBIRC_CONFIG="# WEBIRC: Neconfigurata # Adaugă manual WebIRC blocks pentru gateway-uri web-to-IRC. # Vezi documentația: WEBIRC_EXPLAINED.md" log_info "WEBIRC: Neconfigurata (opțional pentru web gateways)" fi else server_name=$(grep 'name = "' "$CONFIG_FILE" 2>/dev/null | head -1 | cut -d'"' -f2) server_name=${server_name:-localhost.localdomain} vhost_ipv4="127.0.0.1" vhost_ipv6="" SERVER_PORT=4400 client_ports_list="6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 7000" ssl_ports_list="" network_name="underchat.org" oper_username="AdminRoot" oper_hash="\$PLAIN\$password" is_hub="n" HUB_CONFIG="no" OPER_STEALTH_MODE="no" # Default: oper vizibil pentru non-interactive CRULE_CONFIG="# CRULE: Neconfigurata (mod non-interactiv)" PSEUDO_CONFIG="# PSEUDO: Neconfigurata (mod non-interactiv)" SPOOFHOST_CONFIG="# SPOOFHOST: Neconfigurata (mod non-interactiv)" WEBIRC_CONFIG="# WEBIRC: Neconfigurata (mod non-interactiv)" fi # Directorul pentru configurația funcțională - TREBUIE să fie în lib/, nu etc/ conf_file="$PREFIX/lib/ircd.conf" generate_config "$conf_file" "$server_name" "$server_desc" "$server_numeric" "$admin_location" "$admin_contact" "$vhost_ipv4" "$vhost_ipv6" "$network_name" "$oper_username" "$oper_hash" "$is_hub" "$HUB_CONFIG" "$hub_name" "$hub_host" "$hub_port" "$hub_password" "$client_ports_list" "$SERVER_PORT" "$ssl_ports_list" "$OPER_STEALTH_MODE" if [ $? -ne 0 ]; then exit 1 fi # Verifica dacă fișierul de config a fost creat if [ ! -f "$conf_file" ]; then log_error "Fișierul de configurare nu a fost creat!" exit 1 fi # Setează permisiuni pe config chmod 600 "$conf_file" log_success "Permisiuni setate pe configurare: 600" # ====================================================================== # REMEDIERE COMPLETĂ INTEGRATĂ - NU MAI SUNT NECESARE SCRIPTURI DE FIX # ====================================================================== log_info "Aplicare remedieri COMPLETE integrate - NU mai sunt necesare scripturi de fix..." # 1. REMEDIERE COMPLETĂ placeholder-uri EOFCONFIG log_warn "Aplicare remediere COMPLETĂ pentru TOATE placeholder-urile..." # Detectare IP pentru porturi VHOST_FOR_PORTS="$vhost_ipv4" log_info "Folosesc IP-ul pentru toate porturile: $VHOST_FOR_PORTS" # Înlocuire FORȚATĂ EOFCONFIG_CLIENT_PORTS cu porturile EXACT specificate if grep -q "EOFCONFIG_CLIENT_PORTS" "$conf_file"; then log_warn "EOFCONFIG_CLIENT_PORTS găsit - îl înlocuiesc FORȚAT..." # Generează blocul de porturi DOAR pentru cele specificate CLIENT_PORTS_REPLACEMENT="# Porturi publice pentru clienți - generate automat la instalare" for port in $client_ports_list; do CLIENT_PORTS_REPLACEMENT+="\nPort {\n vhost = \"$VHOST_FOR_PORTS\" $port;\n hidden = yes;\n};\n" done # Înlocuire directă cu awk awk -v replacement="$CLIENT_PORTS_REPLACEMENT" ' /EOFCONFIG_CLIENT_PORTS/ { print replacement next } {print} ' "$conf_file" > "$conf_file.tmp" && mv "$conf_file.tmp" "$conf_file" log_success "EOFCONFIG_CLIENT_PORTS înlocuit cu porturile specificate: $client_ports_list" fi # Înlocuire FORȚATĂ EOFCONFIG_SSL_PORTS cu porturile SSL specificate if grep -q "EOFCONFIG_SSL_PORTS" "$conf_file"; then log_warn "EOFCONFIG_SSL_PORTS găsit - îl înlocuiesc FORȚAT..." if [ -n "$ssl_ports_list" ]; then SSL_PORTS_REPLACEMENT="# Porturi SSL/TLS pentru clienți - generate automat la instalare" for port in $ssl_ports_list; do SSL_PORTS_REPLACEMENT+="\nPort {\n vhost = \"$VHOST_FOR_PORTS\" $port;\n ssl = yes;\n hidden = yes;\n};\n" done else SSL_PORTS_REPLACEMENT="# Porturi SSL/TLS pentru clienți - nu au fost configurate" fi # Înlocuire directă cu awk awk -v replacement="$SSL_PORTS_REPLACEMENT" ' /EOFCONFIG_SSL_PORTS/ { print replacement next } {print} ' "$conf_file" > "$conf_file.tmp" && mv "$conf_file.tmp" "$conf_file" log_success "EOFCONFIG_SSL_PORTS înlocuit cu porturile SSL: ${ssl_ports_list:-'none'}" fi # Înlocuire FORȚATĂ orice alt EOFCONFIG rămas sed -i "s|EOFCONFIG_PREFIX|$PREFIX|g" "$conf_file" sed -i "s|EOFCONFIG_NETWORK|$network_name|g" "$conf_file" sed -i "s|\\.EOFCONFIG_NETWORK|.$network_name|g" "$conf_file" sed -i "s|\\*\\.EOFCONFIG_NETWORK|*.$network_name|g" "$conf_file" # 2. REMEDIERE COMPLETĂ pentru HOST_HIDING log_warn "Aplicare remediere COMPLETĂ pentru HOST_HIDING..." # Forțează HOST_HIDING_STYLE = 3 sed -i 's/"HOST_HIDING_STYLE" = "[^"]*"/"HOST_HIDING_STYLE" = "3"/' "$conf_file" if ! grep -q '"HOST_HIDING_STYLE"' "$conf_file"; then sed -i '/"HOST_HIDING" = "TRUE"/a\ "HOST_HIDING_STYLE" = "3";' "$conf_file" fi # 3. REMEDIERE COMPLETĂ pentru probleme de sintaxă log_warn "Aplicare remediere COMPLETĂ pentru probleme de sintaxă..." # Corectează snomask problematic if grep -q 'snomask = ".*HACK.*"' "$conf_file"; then sed -i 's/snomask = ".*HACK.*"/snomask = "+s";/' "$conf_file" log_success "Snomask corectat pentru a evita erori de sintaxă" fi # 5. VERIFICARE și REPARARE FINALĂ COMPLETĂ log_info "Verificare și reparare FINALĂ COMPLETĂ..." # Verificare orice EOFCONFIG rămas și înlocuire de urgență if grep -q "EOFCONFIG" "$conf_file"; then log_error "ÎNCĂ există placeholder-uri EOFCONFIG - aplicare reparare de URGENȚĂ..." sed -i 's/EOFCONFIG_CLIENT_PORTS/# Porturi client - configurare manuală necesară/g' "$conf_file" sed -i 's/EOFCONFIG_SSL_PORTS/# Porturi SSL - configurare manuală necesară/g' "$conf_file" sed -i "s/EOFCONFIG_NETWORK/$network_name/g" "$conf_file" sed -i "s/EOFCONFIG_PREFIX/$PREFIX/g" "$conf_file" sed -i 's/EOFCONFIG[_A-Z]*/# PLACEHOLDER - configurare manuală necesară/g' "$conf_file" log_warn "Reparare de urgență aplicată - verifică configurația manual" fi # 6. TEST FINAL COMPLET și REPARARE AUTOMATĂ log_info "Test final COMPLET cu reparare automată..." if [ -x "$PREFIX/bin/ircd" ]; then FINAL_TEST_OUTPUT=$("$PREFIX/bin/ircd" -c -f "$conf_file" 2>&1) FINAL_TEST_EXIT=$? if [ $FINAL_TEST_EXIT -eq 0 ]; then log_success "✓ CONFIGURAȚIA ESTE COMPLETĂ ȘI VALIDĂ - gata de folosire!" else log_error "Încă sunt erori - aplicare reparare AUTOMATĂ..." echo "$FINAL_TEST_OUTPUT" | head -5 # Reparare automată pentru erori comune if echo "$FINAL_TEST_OUTPUT" | grep -q "line [0-9]*.*syntax error"; then ERROR_LINE=$(echo "$FINAL_TEST_OUTPUT" | grep -o "line [0-9]*" | grep -o "[0-9]*") log_warn "Eroare pe linia $ERROR_LINE - aplicare fix automat..." # Comentează linia problematică sed -i "${ERROR_LINE}s/^/# EROARE REPARATĂ AUTOMAT: /" "$conf_file" # Adaugă port de rezervă dacă e vorba de porturi if echo "$FINAL_TEST_OUTPUT" | grep -qi "port"; then sed -i "${ERROR_LINE}a\\nPort {\n vhost = \"$VHOST_FOR_PORTS\" 6667;\n hidden = no;\n};" "$conf_file" fi log_success "Reparare automată aplicată pentru linia $ERROR_LINE" fi fi else log_warn "Nu pot testa configurația - ircd nu găsit, se continuă" fi log_success "REMEDIERI COMPLETE INTEGRATE aplicate cu SUCCES - NU mai sunt necesare scripturi de fix!" # Creare directoare - ambele etc și lib pentru compatibilitate log_info "Creare structură de directoare..." mkdir -p "$PREFIX/log" mkdir -p "$PREFIX/etc" mkdir -p "$PREFIX/lib" mkdir -p "$PREFIX/var" # IMPORTANT: Copiază configurația și în etc/ pentru compatibilitate cu unele scripturi cp "$conf_file" "$PREFIX/etc/ircd.conf" log_success "Configurația copiată în ambele locații: etc/ și lib/" # Creare fișiere MOTD în ambele locații if [ ! -f "$PREFIX/lib/ircd.motd" ]; then cat > "$PREFIX/lib/ircd.motd" << 'EOFMOTD' ╔═══════════════════════════════════════╗ ║ Bine venit pe UnderChat IRCd! ║ ║ ║ ║ Server: %-30s ║ ║ Versiune: 1.0.3 ║ ║ ║ ║ Pentru suport: #support ║ ║ Website: https://underchat.org ║ ╚═══════════════════════════════════════╝ 🌟 Caracteristici server: • Host hiding pentru protecția utilizatorilor • SSL/TLS encryption disponibil • Anti-spam și anti-flood protection • Canale cu diverse moduri și opțiuni 📋 Comenzi utile: • /LIST - Listează canalele disponibile • /WHOIS nick - Informații despre utilizatori • /JOIN #canal - Intră într-un canal • /HELP - Lista comenzilor disponibile 🔒 Acest server respectă politica de confidențialitate și regulile rețelei UnderChat. Comportamentul abuziv poate duce la restricții sau banuri. Distracție plăcută pe UnderChat! 🎉 EOFMOTD # Copiază și în etc/ cp "$PREFIX/lib/ircd.motd" "$PREFIX/etc/ircd.motd" log_success "MOTD creat în lib/ și copiat în etc/" fi # Creare OPERMOTD pentru operatori (întotdeauna, chiar dacă există) log_info "Generare OPERMOTD pentru operatori..." cat > "$PREFIX/lib/ircd.opermotd" << 'EOFOPERMOTD' ╔═══════════════════════════════════════════════════════════╗ ║ WELCOME TO UNDERCHAT IRC STAFF ║ ║ ║ ║ You are now logged in as an IRC Operator. ║ ║ ║ ║ RESPONSIBILITIES: ║ ║ • Help users with problems ║ ║ • Monitor for abuse and spam ║ ║ • Enforce network rules ║ ║ • Maintain network security ║ ║ ║ ║ COMMANDS: ║ ║ • /GLINE user@host :reason - Global ban ║ ║ • /REHASH - Reload config ║ ║ • /CHECK nickname - Check user info ║ ║ • /WHOIS nickname - Extended user info ║ ║ • /SETHOST hostname - Change your hostname ║ ║ • /OPERMOTD - View this message again ║ ║ ║ ║ CHANNELS: ║ ║ • #opers - Staff discussion channel ║ ║ • #support - User support channel ║ ║ ║ ║ 📚 Staff Documentation: https://docs.underchat.org ║ ║ 🔒 Privacy Policy: Keep user data confidential ║ ║ ║ ║ Remember: With great power comes great responsibility! ║ ╚═══════════════════════════════════════════════════════════╝ EOFOPERMOTD # Copiază și în etc/ cp "$PREFIX/lib/ircd.opermotd" "$PREFIX/etc/ircd.opermotd" chmod 644 "$PREFIX/lib/ircd.opermotd" chmod 644 "$PREFIX/etc/ircd.opermotd" log_success "OPERMOTD creat în lib/ și copiat în etc/" # Rezumat instalare echo "" echo -e "${VERDE}" echo "=========================================" echo " ✓ Instalare completă!" echo "=========================================" echo -e "${NC}" echo "" echo -e "${GALBEN}Informații de instalare:${NC}" echo " Calea de instalare: $PREFIX" echo " Fișier configurare: $conf_file" echo " Fișier log: $PREFIX/log/ircd.log" echo " Maxim conexiuni: $MAXCON" echo " Debug: $([ $ENABLE_DEBUG -eq 1 ] && echo 'Activat' || echo 'Dezactivat')" echo " SSL/TLS: $([ $ENABLE_SSL -eq 1 ] && echo 'Activat' || echo 'Dezactivat')" echo "" echo -e "${GALBEN}Pași următori:${NC}" echo " 1. Editează configurarea: nano $conf_file" echo " 2. Generează parola operator: $PREFIX/bin/umkpasswd" echo " 3. Pornește serverul: $PREFIX/bin/ircd -f $conf_file" echo " 4. Conectează-te: irc://localhost:6667" echo "" } # Apelează funcția principală main "$@"