|
#!/data/data/com.termux/files/usr/bin/bash |
|
# ============================================================ |
|
# SecFerro · RouterOS Lab Installer |
|
# Uruchomienie jedną komendą: |
|
# curl -fsSL https://gist.githubusercontent.com/anonymousik/11c364db0b16568382b3dc9009ad37de/raw/23c3e79412da0a634168e98c9177491ec71d458d/install.sh | bash |
|
# ============================================================ |
|
|
|
set -euo pipefail |
|
|
|
# ── Wersja ────────────────────────────────────────────────── |
|
VERSION="2.0.0" |
|
GIST_RAW="curl -fsSL https://gist.githubusercontent.com/anonymousik/11c364db0b16568382b3dc9009ad37de/raw" |
|
|
|
# ── Katalogi ──────────────────────────────────────────────── |
|
BASE_DIR="$HOME/secferro" |
|
LOG_DIR="$BASE_DIR/logs" |
|
CONF_DIR="$BASE_DIR/config" |
|
SECRETS_DIR="$BASE_DIR/.secrets" |
|
VM_DIR="$BASE_DIR/vm" |
|
BACKUP_DIR="$BASE_DIR/backups" |
|
SCRIPTS_DIR="$BASE_DIR/scripts" |
|
|
|
# ── Sieć / Hosty ──────────────────────────────────────────── |
|
TERMUX_HOSTNAME="secferro.lan" |
|
EMU_HOSTNAME="emu.secferro.lan" |
|
EMU_IP="192.168.168.168" |
|
EMU_LO="127.0.0.1" |
|
MAIL_DOMAIN="secferro.lan" |
|
MAIL_USER="test" |
|
MAIL_LOGIN="${MAIL_USER}@${MAIL_DOMAIN}" |
|
|
|
# ── RouterOS ──────────────────────────────────────────────── |
|
ROS_VERSION="6.49.13" # ostatnia stabilna 6.x LTS |
|
ROS_IMAGE_URL="https://download.mikrotik.com/routeros/${ROS_VERSION}/chr-${ROS_VERSION}.img.zip" |
|
ROS_MAC="D4:CA:6D:18:16:28" |
|
ROS_MEMORY=256 |
|
ROS_CPUS=1 |
|
|
|
# ── Kolory ANSI ───────────────────────────────────────────── |
|
R='\033[0;31m' G='\033[0;32m' Y='\033[1;33m' |
|
B='\033[0;34m' C='\033[0;36m' W='\033[1;37m' |
|
DIM='\033[2m' BOLD='\033[1m' NC='\033[0m' |
|
|
|
# ── Ikony statusu ──────────────────────────────────────────── |
|
OK="${G}[✓]${NC}" FAIL="${R}[✗]${NC}" |
|
WARN="${Y}[!]${NC}" INFO="${B}[i]${NC}" |
|
STEP="${C}[→]${NC}" ARROW="${W}[»]${NC}" |
|
|
|
# ── Log ───────────────────────────────────────────────────── |
|
mkdir -p "$LOG_DIR" |
|
LOGFILE="$LOG_DIR/install_$(date +%Y%m%d_%H%M%S).log" |
|
exec > >(tee -a "$LOGFILE") 2>&1 |
|
|
|
# ── Pomocnicze funkcje ─────────────────────────────────────── |
|
banner() { |
|
clear |
|
echo -e "${C}" |
|
cat << 'ART' |
|
╔══════════════════════════════════════════════════════════════╗ |
|
║ ███████╗███████╗ ██████╗███████╗███████╗██████╗ ██████╗ ║ |
|
║ ██╔════╝██╔════╝██╔════╝██╔════╝██╔════╝██╔══██╗██╔═══██╗ ║ |
|
║ ███████╗█████╗ ██║ █████╗ █████╗ ██████╔╝██║ ██║ ║ |
|
║ ╚════██║██╔══╝ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║ ██║ ║ |
|
║ ███████║███████╗╚██████╗██║ ███████╗██║ ██║╚██████╔╝ ║ |
|
║ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝ ║ |
|
║ ║ |
|
║ RouterOS Lab Environment · v2.0.0 ║ |
|
║ Termux · QEMU · Postfix · MikroTik CHR ║ |
|
╚══════════════════════════════════════════════════════════════╝ |
|
ART |
|
echo -e "${NC}" |
|
echo -e " ${DIM}Host: ${TERMUX_HOSTNAME} VM: ${EMU_HOSTNAME} (${EMU_IP})${NC}" |
|
echo -e " ${DIM}Log: ${LOGFILE}${NC}" |
|
echo "" |
|
} |
|
|
|
section() { |
|
echo "" |
|
echo -e "${BOLD}${Y}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
echo -e "${BOLD}${Y} $1${NC}" |
|
echo -e "${BOLD}${Y}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
echo "" |
|
} |
|
|
|
step() { echo -e " ${STEP} ${W}$*${NC}"; } |
|
ok() { echo -e " ${OK} $*"; } |
|
fail() { echo -e " ${FAIL} ${R}$*${NC}"; } |
|
warn() { echo -e " ${WARN} ${Y}$*${NC}"; } |
|
info() { echo -e " ${INFO} ${DIM}$*${NC}"; } |
|
|
|
confirm() { |
|
local msg="$1" |
|
echo -e "\n ${ARROW} ${W}${msg}${NC} ${DIM}[T/n]${NC} \c" |
|
read -r ans |
|
[[ -z "$ans" || "$ans" =~ ^[TtYy]$ ]] |
|
} |
|
|
|
progress() { |
|
local msg="$1"; shift |
|
echo -ne " ${STEP} ${W}${msg}...${NC} " |
|
if "$@" >> "$LOGFILE" 2>&1; then |
|
echo -e "${OK}" |
|
return 0 |
|
else |
|
echo -e "${FAIL}" |
|
warn "Szczegóły: tail -n30 $LOGFILE" |
|
return 1 |
|
fi |
|
} |
|
|
|
# ── Generator bezpiecznych haseł ───────────────────────────── |
|
# Używa /dev/urandom + openssl fallback + python3 fallback |
|
gen_password() { |
|
local length="${1:-32}" |
|
local charset='A-Za-z0-9!@#%^&*()-_=+[]{}|;:,.<>?' |
|
|
|
if command -v openssl &>/dev/null; then |
|
openssl rand -base64 48 | tr -dc "$charset" | head -c "$length" |
|
elif [ -r /dev/urandom ]; then |
|
tr -dc "$charset" < /dev/urandom | head -c "$length" |
|
elif command -v python3 &>/dev/null; then |
|
python3 -c " |
|
import secrets, string |
|
alphabet = string.ascii_letters + string.digits + '!@#%^&*()-_=+[]{}|;:,.<>?' |
|
print(''.join(secrets.choice(alphabet) for _ in range($length)), end='') |
|
" |
|
else |
|
# ostateczny fallback – sha256 z entropii systemowej |
|
echo -n "$(date +%N)$$RANDOM" | sha256sum | tr -dc 'A-Za-z0-9' | head -c "$length" |
|
fi |
|
} |
|
|
|
# ── Zapisz/odczytaj sekrety ────────────────────────────────── |
|
save_secret() { |
|
local key="$1" val="$2" |
|
mkdir -p "$SECRETS_DIR" |
|
chmod 700 "$SECRETS_DIR" |
|
echo "$val" > "$SECRETS_DIR/${key}" |
|
chmod 600 "$SECRETS_DIR/${key}" |
|
} |
|
|
|
get_secret() { |
|
local key="$1" |
|
[[ -f "$SECRETS_DIR/${key}" ]] && cat "$SECRETS_DIR/${key}" || echo "" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 0 · Diagnoza systemu |
|
# ───────────────────────────────────────────────────────────── |
|
diag_system() { |
|
section "KROK 0 · Diagnostyka systemu" |
|
|
|
local errors=0 |
|
|
|
# Architektura |
|
ARCH=$(uname -m) |
|
step "Architektura: ${ARCH}" |
|
case "$ARCH" in |
|
aarch64|arm64) ok "ARM64 – pełne wsparcie QEMU" ;; |
|
x86_64) ok "x86_64 – wsparcie QEMU + KVM" ;; |
|
*) warn "Nieobsługiwana architektura: ${ARCH}"; ((errors++)) ;; |
|
esac |
|
|
|
# Pamięć RAM |
|
local mem_kb mem_mb |
|
mem_kb=$(grep MemAvailable /proc/meminfo | awk '{print $2}') |
|
mem_mb=$((mem_kb / 1024)) |
|
step "Dostępna pamięć RAM: ${mem_mb} MB" |
|
if [[ $mem_mb -ge 512 ]]; then ok "${mem_mb} MB – wystarczające" |
|
elif [[ $mem_mb -ge 256 ]]; then warn "${mem_mb} MB – minimum (zalecane 512+)" |
|
else fail "${mem_mb} MB – za mało!"; ((errors++)); fi |
|
|
|
# Miejsce na dysku |
|
local free_mb |
|
free_mb=$(df "$HOME" | tail -1 | awk '{print int($4/1024)}') |
|
step "Wolne miejsce: ${free_mb} MB" |
|
if [[ $free_mb -ge 1024 ]]; then ok "${free_mb} MB – wystarczające" |
|
else warn "${free_mb} MB – zalecane min. 1 GB"; fi |
|
|
|
# Termux API / środowisko |
|
step "Środowisko Termux" |
|
if [[ -d /data/data/com.termux ]]; then |
|
ok "Termux wykryty" |
|
else |
|
warn "Nie wygląda jak Termux – kontynuuję ostrożnie" |
|
fi |
|
|
|
# Połączenie sieciowe |
|
step "Połączenie sieciowe" |
|
if ping -c1 -W3 8.8.8.8 &>/dev/null || curl -sf --connect-timeout 5 https://cloudflare.com &>/dev/null; then |
|
ok "Internet dostępny" |
|
else |
|
fail "Brak połączenia z internetem!"; ((errors++)) |
|
fi |
|
|
|
# Python3 |
|
step "Python3" |
|
if command -v python3 &>/dev/null; then |
|
ok "$(python3 --version)" |
|
else |
|
warn "Brak python3 – zostanie zainstalowany" |
|
fi |
|
|
|
if [[ $errors -gt 0 ]]; then |
|
fail "Znaleziono $errors krytycznych problemów." |
|
confirm "Kontynuować mimo to?" || { fail "Instalacja przerwana."; exit 1; } |
|
else |
|
ok "Diagnostyka zakończona – system gotowy" |
|
fi |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 1 · Pakiety systemowe |
|
# ───────────────────────────────────────────────────────────── |
|
install_packages() { |
|
section "KROK 1 · Instalacja pakietów" |
|
|
|
step "Aktualizacja repozytoriów" |
|
progress "pkg update" pkg update -y |
|
progress "pkg upgrade" pkg upgrade -y |
|
|
|
local PKGS=( |
|
# Wirtualizacja |
|
qemu-utils qemu-system-x86-64 |
|
# Sieć |
|
curl wget iproute2 netcat-openbsd nmap dnsutils |
|
# Poczta |
|
postfix msmtp msmtp-mta ca-certificates |
|
# Narzędzia |
|
python3 openssl jq unzip tar gzip bc |
|
# Deweloperskie |
|
git nano vim tmux screen |
|
# Monitoring |
|
htop net-tools procps |
|
) |
|
|
|
local failed_pkgs=() |
|
for pkg in "${PKGS[@]}"; do |
|
if pkg install -y "$pkg" >> "$LOGFILE" 2>&1; then |
|
ok "Zainstalowano: ${pkg}" |
|
else |
|
warn "Nie udało się zainstalować: ${pkg}" |
|
failed_pkgs+=("$pkg") |
|
fi |
|
done |
|
|
|
if [[ ${#failed_pkgs[@]} -gt 0 ]]; then |
|
warn "Pominięte pakiety: ${failed_pkgs[*]}" |
|
warn "Niektóre funkcje mogą być niedostępne" |
|
fi |
|
|
|
ok "Pakiety zainstalowane" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 2 · Generowanie sekretów |
|
# ───────────────────────────────────────────────────────────── |
|
generate_secrets() { |
|
section "KROK 2 · Generowanie bezpiecznych haseł" |
|
|
|
# Sprawdź czy sekrety już istnieją |
|
if [[ -f "$SECRETS_DIR/mail_password" ]] && [[ -f "$SECRETS_DIR/ros_password" ]]; then |
|
if ! confirm "Sekrety już istnieją. Wygenerować nowe?"; then |
|
ok "Używam istniejących sekretów" |
|
return 0 |
|
fi |
|
fi |
|
|
|
step "Generowanie hasła SMTP/mail (64 znaki)" |
|
MAIL_PASS=$(gen_password 64) |
|
save_secret "mail_password" "$MAIL_PASS" |
|
ok "Hasło mail wygenerowane" |
|
|
|
step "Generowanie hasła RouterOS admin (32 znaki)" |
|
ROS_PASS=$(gen_password 32) |
|
save_secret "ros_password" "$ROS_PASS" |
|
ok "Hasło RouterOS wygenerowane" |
|
|
|
step "Generowanie klucza DKIM (2048-bit RSA)" |
|
if command -v openssl &>/dev/null; then |
|
openssl genrsa -out "$SECRETS_DIR/dkim_private.pem" 2048 >> "$LOGFILE" 2>&1 |
|
openssl rsa -in "$SECRETS_DIR/dkim_private.pem" \ |
|
-pubout -out "$SECRETS_DIR/dkim_public.pem" >> "$LOGFILE" 2>&1 |
|
chmod 600 "$SECRETS_DIR/dkim_private.pem" |
|
ok "Klucz DKIM wygenerowany" |
|
else |
|
warn "openssl niedostępny – pomijam DKIM" |
|
fi |
|
|
|
step "Generowanie hasła Winbox (20 znaków alfanumerycznych)" |
|
WINBOX_PASS=$(gen_password 20 | tr -dc 'A-Za-z0-9' | head -c 20) |
|
save_secret "winbox_password" "$WINBOX_PASS" |
|
ok "Hasło Winbox wygenerowane" |
|
|
|
# Token API (do skryptów automatyzacji) |
|
step "Generowanie tokenu API (hex 128-bit)" |
|
API_TOKEN=$(openssl rand -hex 16 2>/dev/null || gen_password 32 | tr -dc 'a-f0-9' | head -c 32) |
|
save_secret "api_token" "$API_TOKEN" |
|
ok "Token API wygenerowany" |
|
|
|
ok "Wszystkie sekrety zapisane w: $SECRETS_DIR" |
|
info "Uprawnienia katalogu sekretów: 700 / pliki: 600" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 3 · Konfiguracja serwera pocztowego (Postfix) |
|
# ───────────────────────────────────────────────────────────── |
|
setup_mail_server() { |
|
section "KROK 3 · Serwer SMTP (Postfix)" |
|
|
|
MAIL_PASS=$(get_secret "mail_password") |
|
|
|
mkdir -p "$CONF_DIR/postfix" |
|
|
|
# main.cf |
|
cat > "$CONF_DIR/postfix/main.cf" << POSTFIX_MAIN |
|
# ── SecFerro · Postfix main.cf ────────────────────────────── |
|
myhostname = ${EMU_HOSTNAME} |
|
mydomain = ${MAIL_DOMAIN} |
|
myorigin = \$mydomain |
|
|
|
# Interfejsy nasłuchiwania |
|
inet_interfaces = loopback-only |
|
inet_protocols = ipv4 |
|
|
|
# Lokalne dostarczanie |
|
mydestination = \$myhostname, localhost.\$mydomain, localhost, \$mydomain |
|
mynetworks = 127.0.0.0/8, ${EMU_IP}/32 |
|
|
|
# TLS |
|
smtpd_tls_security_level = may |
|
smtpd_tls_cert_file = /etc/ssl/certs/ca-certificates.crt |
|
smtp_tls_security_level = may |
|
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt |
|
|
|
# Limity |
|
message_size_limit = 10240000 |
|
mailbox_size_limit = 51200000 |
|
recipient_delimiter = + |
|
|
|
# Uwierzytelnianie SASL |
|
smtpd_sasl_auth_enable = yes |
|
smtpd_sasl_security_options = noanonymous |
|
smtpd_sasl_local_domain = \$myhostname |
|
broken_sasl_auth_clients = yes |
|
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination |
|
|
|
# Kolejkowanie |
|
queue_run_delay = 300s |
|
minimal_backoff_time = 300s |
|
maximal_backoff_time = 4000s |
|
|
|
# Alias |
|
alias_maps = hash:/etc/aliases |
|
alias_database = hash:/etc/aliases |
|
POSTFIX_MAIN |
|
|
|
ok "Postfix main.cf przygotowany" |
|
|
|
# Plik haseł SASL |
|
mkdir -p "$CONF_DIR/postfix/sasl" |
|
cat > "$CONF_DIR/postfix/sasl/passwd" << SASL_PASSWD |
|
# format: hostname:port user:password |
|
[${EMU_IP}]:25 ${MAIL_LOGIN}:${MAIL_PASS} |
|
[${EMU_LO}]:25 ${MAIL_LOGIN}:${MAIL_PASS} |
|
localhost:25 ${MAIL_LOGIN}:${MAIL_PASS} |
|
SASL_PASSWD |
|
chmod 600 "$CONF_DIR/postfix/sasl/passwd" |
|
ok "Plik haseł SASL zapisany" |
|
|
|
# Aliases |
|
cat > "$CONF_DIR/postfix/aliases" << ALIASES |
|
# SecFerro mail aliases |
|
postmaster: ${MAIL_LOGIN} |
|
root: ${MAIL_LOGIN} |
|
admin: ${MAIL_LOGIN} |
|
mailer-daemon: ${MAIL_LOGIN} |
|
ALIASES |
|
|
|
# Skrypt wdrożeniowy Postfix |
|
cat > "$SCRIPTS_DIR/deploy_postfix.sh" << 'DEPLOY_POST' |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
# Wdróż konfigurację Postfix (wymaga PREFIX=/data/data/com.termux/files/usr) |
|
BASE="${HOME}/secferro" |
|
CONF="${BASE}/config/postfix" |
|
|
|
cp "$CONF/main.cf" "$PREFIX/etc/postfix/main.cf" |
|
cp "$CONF/aliases" "$PREFIX/etc/postfix/aliases" |
|
mkdir -p "$PREFIX/etc/postfix/sasl" |
|
cp "$CONF/sasl/passwd" "$PREFIX/etc/postfix/sasl/passwd" |
|
|
|
# Hashowanie pliku haseł |
|
if command -v postmap &>/dev/null; then |
|
postmap "$PREFIX/etc/postfix/sasl/passwd" |
|
newaliases 2>/dev/null || true |
|
echo "[✓] Postfix skonfigurowany" |
|
postfix check && echo "[✓] Konfiguracja poprawna" |
|
else |
|
echo "[!] postmap niedostępny – Postfix może nie być zainstalowany" |
|
fi |
|
DEPLOY_POST |
|
chmod +x "$SCRIPTS_DIR/deploy_postfix.sh" |
|
|
|
ok "Konfiguracja serwera SMTP (Postfix) gotowa" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 4 · Konfiguracja klienta pocztowego (msmtp) |
|
# ───────────────────────────────────────────────────────────── |
|
setup_mail_client() { |
|
section "KROK 4 · Klient SMTP (msmtp)" |
|
|
|
MAIL_PASS=$(get_secret "mail_password") |
|
|
|
mkdir -p "$CONF_DIR/msmtp" |
|
|
|
cat > "$CONF_DIR/msmtp/msmtprc" << MSMTP_CONF |
|
# ── SecFerro · msmtp konfiguracja ─────────────────────────── |
|
# Domyślne wartości dla wszystkich kont |
|
defaults |
|
auth on |
|
tls on |
|
tls_trust_file /etc/ssl/certs/ca-certificates.crt |
|
logfile ${LOG_DIR}/msmtp.log |
|
syslog off |
|
|
|
# Konto lokalne – połączenie z emulatorem RouterOS |
|
account secferro-local |
|
host ${EMU_IP} |
|
port 25 |
|
from ${MAIL_LOGIN} |
|
user ${MAIL_LOGIN} |
|
password ${MAIL_PASS} |
|
tls off |
|
tls_starttls off |
|
auth login |
|
|
|
# Konto loopback |
|
account secferro-lo |
|
host 127.0.0.1 |
|
port 25 |
|
from ${MAIL_LOGIN} |
|
user ${MAIL_LOGIN} |
|
password ${MAIL_PASS} |
|
tls off |
|
tls_starttls off |
|
auth login |
|
|
|
# Konto domyślne |
|
account default : secferro-local |
|
MSMTP_CONF |
|
|
|
chmod 600 "$CONF_DIR/msmtp/msmtprc" |
|
|
|
# Skrypt wdrożeniowy msmtp |
|
cat > "$SCRIPTS_DIR/deploy_msmtp.sh" << DEPLOY_MSMTP |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
BASE="\${HOME}/secferro" |
|
CONF="\${BASE}/config/msmtp" |
|
|
|
# Wdroż globalnie |
|
cp "\${CONF}/msmtprc" "\${HOME}/.msmtprc" |
|
chmod 600 "\${HOME}/.msmtprc" |
|
|
|
# Ustaw jako sendmail alias jeśli możliwe |
|
if [ -d "\${PREFIX}/lib/sendmail" ] 2>/dev/null || true; then |
|
echo "[✓] msmtp skonfigurowany jako klient SMTP" |
|
fi |
|
|
|
# Test konfiguracji |
|
if command -v msmtp &>/dev/null; then |
|
msmtp --serverinfo --account=secferro-local 2>&1 | head -5 || true |
|
fi |
|
|
|
echo "[✓] Klient SMTP (msmtp) wdrożony" |
|
DEPLOY_MSMTP |
|
chmod +x "$SCRIPTS_DIR/deploy_msmtp.sh" |
|
|
|
ok "Konfiguracja klienta SMTP (msmtp) gotowa" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 5 · Pobieranie obrazu RouterOS CHR |
|
# ───────────────────────────────────────────────────────────── |
|
download_routeros() { |
|
section "KROK 5 · Pobieranie RouterOS CHR ${ROS_VERSION}" |
|
|
|
mkdir -p "$VM_DIR" |
|
local img_zip="$VM_DIR/chr-${ROS_VERSION}.img.zip" |
|
local img_raw="$VM_DIR/chr-${ROS_VERSION}.img" |
|
local img_qcow="$VM_DIR/routeros.qcow2" |
|
|
|
if [[ -f "$img_qcow" ]]; then |
|
ok "Obraz qcow2 już istnieje – pomijam pobieranie" |
|
return 0 |
|
fi |
|
|
|
step "Pobieranie RouterOS CHR ${ROS_VERSION}" |
|
info "URL: ${ROS_IMAGE_URL}" |
|
|
|
if wget -c --progress=bar:force \ |
|
--timeout=120 \ |
|
-O "$img_zip" \ |
|
"$ROS_IMAGE_URL" 2>&1 | tail -5; then |
|
ok "Pobrano obraz" |
|
else |
|
fail "Błąd pobierania! Sprawdź URL lub połączenie." |
|
info "URL: $ROS_IMAGE_URL" |
|
exit 1 |
|
fi |
|
|
|
step "Rozpakowywanie archiwum ZIP" |
|
progress "unzip" unzip -o "$img_zip" -d "$VM_DIR" |
|
|
|
step "Konwersja RAW → QCOW2" |
|
if command -v qemu-img &>/dev/null; then |
|
progress "qemu-img convert" \ |
|
qemu-img convert -f raw -O qcow2 "$img_raw" "$img_qcow" |
|
qemu-img resize "$img_qcow" 512M >> "$LOGFILE" 2>&1 || true |
|
ok "Obraz QCOW2 gotowy: $(du -sh "$img_qcow" | cut -f1)" |
|
else |
|
fail "qemu-img niedostępny" |
|
exit 1 |
|
fi |
|
|
|
# Sprzątanie |
|
rm -f "$img_zip" "$img_raw" |
|
ok "Obraz RouterOS przygotowany" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 6 · Konfiguracja RouterOS (skrypt RSC) |
|
# ───────────────────────────────────────────────────────────── |
|
generate_ros_config() { |
|
section "KROK 6 · Konfiguracja RouterOS" |
|
|
|
MAIL_PASS=$(get_secret "mail_password") |
|
ROS_PASS=$(get_secret "ros_password") |
|
|
|
mkdir -p "$CONF_DIR/routeros" |
|
|
|
cat > "$CONF_DIR/routeros/init.rsc" << RSC_CONF |
|
# ============================================================ |
|
# SecFerro · RouterOS Initial Configuration |
|
# Host: ${EMU_HOSTNAME} (${EMU_IP}) |
|
# Generated: $(date -u +"%Y-%m-%dT%H:%M:%SZ") |
|
# ============================================================ |
|
|
|
# Identyfikacja systemu |
|
/system identity |
|
set name="${EMU_HOSTNAME}" |
|
|
|
# Hasło administratora (wygenerowane losowo) |
|
/user set [find name=admin] password="${ROS_PASS}" |
|
|
|
# ── Interfejsy ─────────────────────────────────────────────── |
|
/interface ethernet |
|
set [find] auto-negotiation=yes |
|
|
|
/interface wireless |
|
set [ find ] band=2ghz-b/g/n \\ |
|
channel-width=20mhz \\ |
|
frequency=2472 \\ |
|
mode=ap-bridge \\ |
|
ssid="${MAIL_DOMAIN}_AP" \\ |
|
wireless-protocol=802.11 \\ |
|
disabled=no |
|
|
|
# ── Bridge ─────────────────────────────────────────────────── |
|
/interface bridge |
|
add name=bridge-local \\ |
|
admin-mac=${ROS_MAC} \\ |
|
auto-mac=no \\ |
|
comment="SecFerro main bridge" |
|
|
|
/interface bridge port |
|
add bridge=bridge-local interface=ether1 |
|
|
|
# ── Adresacja IP ───────────────────────────────────────────── |
|
/ip address |
|
add address=${EMU_IP}/24 interface=ether1 comment="Management" |
|
add address=${EMU_LO}/8 interface=lo comment="Loopback" |
|
|
|
# ── DNS ────────────────────────────────────────────────────── |
|
/ip dns |
|
set servers=1.1.1.1,8.8.8.8 \\ |
|
allow-remote-requests=no |
|
|
|
# ── Konfiguracja e-mail (SMTP) ─────────────────────────────── |
|
/tool e-mail |
|
set address=${EMU_LO} \\ |
|
from=${MAIL_LOGIN} \\ |
|
password=${MAIL_PASS} \\ |
|
port=25 \\ |
|
user=${MAIL_LOGIN} \\ |
|
tls=no |
|
|
|
# ── Firewall (hardened) ────────────────────────────────────── |
|
/ip firewall filter |
|
|
|
# INPUT chain |
|
add chain=input action=accept \\ |
|
connection-state=established,related \\ |
|
comment="Accept established" |
|
|
|
add chain=input action=drop \\ |
|
connection-state=invalid \\ |
|
comment="Drop invalid" |
|
|
|
add chain=input action=accept \\ |
|
protocol=icmp \\ |
|
comment="Accept ICMP" |
|
|
|
add chain=input action=accept \\ |
|
src-address=192.168.168.0/24 \\ |
|
dst-port=22 protocol=tcp \\ |
|
comment="SSH from management" |
|
|
|
add chain=input action=accept \\ |
|
src-address=192.168.168.0/24 \\ |
|
dst-port=8291 protocol=tcp \\ |
|
comment="Winbox from management" |
|
|
|
add chain=input action=accept \\ |
|
dst-port=25 protocol=tcp \\ |
|
comment="SMTP" |
|
|
|
add chain=input action=drop \\ |
|
comment="Drop all other INPUT" |
|
|
|
# FORWARD chain |
|
add chain=forward action=accept \\ |
|
connection-state=established,related \\ |
|
comment="Accept established forward" |
|
|
|
add chain=forward action=drop \\ |
|
connection-state=invalid \\ |
|
comment="Drop invalid forward" |
|
|
|
# ── Usługi (hardened) ──────────────────────────────────────── |
|
/ip service |
|
disable [find name~"telnet|ftp|www|api|api-ssl"] |
|
set ssh address=192.168.168.0/24 port=22 |
|
set winbox address=192.168.168.0/24 port=8291 |
|
|
|
# ── NTP ────────────────────────────────────────────────────── |
|
/system ntp client |
|
set enabled=yes primary-ntp=216.239.35.0 |
|
|
|
# ── Scheduler: cotygodniowy backup ─────────────────────────── |
|
/system scheduler |
|
add interval=1w \\ |
|
name=weekly-backup \\ |
|
on-event="/system backup save name=secferro_weekly" \\ |
|
start-date=jan/01/2024 \\ |
|
start-time=04:00:00 \\ |
|
comment="Auto backup" |
|
|
|
# ── Scheduler: powiadomienie e-mail ────────────────────────── |
|
/system scheduler |
|
add interval=1d \\ |
|
name=daily-health-mail \\ |
|
on-event="/tool e-mail send to=${MAIL_LOGIN} subject=(\$[/system identity get name].\\" health\\" ) body=(\\"RouterOS OK: \\".[\$:tostr [\$/system clock get time]])" \\ |
|
start-time=08:00:00 \\ |
|
comment="Daily health email" |
|
|
|
# ── Logi ───────────────────────────────────────────────────── |
|
/system logging |
|
add topics=firewall action=memory |
|
add topics=warning action=memory |
|
add topics=error action=memory |
|
|
|
# Wyślij potwierdzenie konfiguracji |
|
/tool e-mail send \\ |
|
to="${MAIL_LOGIN}" \\ |
|
subject="[SecFerro] RouterOS configured - $(date +%Y-%m-%d)" \\ |
|
body="Konfiguracja RouterOS zakonczona pomyslnie.\\nHost: ${EMU_HOSTNAME}\\nIP: ${EMU_IP}" |
|
|
|
RSC_CONF |
|
|
|
ok "Skrypt RSC wygenerowany: $CONF_DIR/routeros/init.rsc" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 7 · Skrypty uruchomieniowe |
|
# ───────────────────────────────────────────────────────────── |
|
create_runtime_scripts() { |
|
section "KROK 7 · Skrypty runtime" |
|
|
|
# ── Start VM ────────────────────────────────────────────── |
|
cat > "$SCRIPTS_DIR/start_vm.sh" << STARTVM |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
# ── SecFerro · Start RouterOS VM ──────────────────────────── |
|
set -e |
|
|
|
VM_DIR="\${HOME}/secferro/vm" |
|
LOG_DIR="\${HOME}/secferro/logs" |
|
PID_FILE="\${VM_DIR}/qemu.pid" |
|
|
|
# Sprawdź czy VM już działa |
|
if [[ -f "\$PID_FILE" ]] && kill -0 "\$(cat "\$PID_FILE")" 2>/dev/null; then |
|
echo "[!] VM już działa (PID: \$(cat "\$PID_FILE"))" |
|
exit 0 |
|
fi |
|
|
|
echo "[→] Uruchamianie RouterOS VM..." |
|
echo "[i] Host: ${EMU_HOSTNAME} | IP: ${EMU_IP}" |
|
echo "[i] Pamięć: ${ROS_MEMORY}MB | CPU: ${ROS_CPUS} vCPU" |
|
|
|
qemu-system-x86_64 \\ |
|
-name "${EMU_HOSTNAME}" \\ |
|
-m ${ROS_MEMORY} \\ |
|
-smp ${ROS_CPUS} \\ |
|
-nographic \\ |
|
-serial mon:stdio \\ |
|
-drive file="\${VM_DIR}/routeros.qcow2",format=qcow2,if=ide,cache=writeback \\ |
|
-netdev user,id=net0,net=${EMU_IP}/24,host=192.168.168.1,hostfwd=tcp::2222-:22,hostfwd=tcp::8291-:8291,hostfwd=tcp::2525-:25 \\ |
|
-device e1000,netdev=net0,mac=${ROS_MAC} \\ |
|
-cpu qemu64 \\ |
|
-machine type=q35 \\ |
|
-rtc base=utc \\ |
|
-boot c \\ |
|
-daemonize \\ |
|
-pidfile "\$PID_FILE" \\ |
|
-D "\${LOG_DIR}/qemu.log" |
|
|
|
sleep 2 |
|
if [[ -f "\$PID_FILE" ]] && kill -0 "\$(cat "\$PID_FILE")" 2>/dev/null; then |
|
echo "[✓] VM uruchomiona (PID: \$(cat "\$PID_FILE"))" |
|
echo "[i] SSH: ssh -p 2222 admin@127.0.0.1" |
|
echo "[i] SMTP: 127.0.0.1:2525" |
|
echo "[i] Winbox: 127.0.0.1:8291" |
|
else |
|
echo "[✗] Błąd uruchamiania VM. Sprawdź: \${LOG_DIR}/qemu.log" |
|
exit 1 |
|
fi |
|
STARTVM |
|
chmod +x "$SCRIPTS_DIR/start_vm.sh" |
|
|
|
# ── Stop VM ─────────────────────────────────────────────── |
|
cat > "$SCRIPTS_DIR/stop_vm.sh" << 'STOPVM' |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
PID_FILE="${HOME}/secferro/vm/qemu.pid" |
|
if [[ -f "$PID_FILE" ]]; then |
|
PID=$(cat "$PID_FILE") |
|
kill "$PID" 2>/dev/null && echo "[✓] VM zatrzymana (PID: $PID)" || echo "[!] VM nie działa" |
|
rm -f "$PID_FILE" |
|
else |
|
echo "[!] Brak pliku PID – VM nie jest uruchomiona" |
|
fi |
|
STOPVM |
|
chmod +x "$SCRIPTS_DIR/stop_vm.sh" |
|
|
|
# ── Status ──────────────────────────────────────────────── |
|
cat > "$SCRIPTS_DIR/status.sh" << STATUS_SH |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
# ── SecFerro · Status Dashboard ───────────────────────────── |
|
C='\033[0;36m' G='\033[0;32m' R='\033[0;31m' Y='\033[1;33m' NC='\033[0m' |
|
|
|
echo -e "\${C}╔══════════════════════════════════════════╗\${NC}" |
|
echo -e "\${C}║ SecFerro · Status Dashboard ║\${NC}" |
|
echo -e "\${C}╚══════════════════════════════════════════╝\${NC}" |
|
echo "" |
|
|
|
# VM Status |
|
PID_FILE="\${HOME}/secferro/vm/qemu.pid" |
|
if [[ -f "\$PID_FILE" ]] && kill -0 "\$(cat "\$PID_FILE")" 2>/dev/null; then |
|
echo -e " RouterOS VM: \${G}● RUNNING\${NC} (PID: \$(cat "\$PID_FILE"))" |
|
else |
|
echo -e " RouterOS VM: \${R}● STOPPED\${NC}" |
|
fi |
|
|
|
# Postfix |
|
if pgrep -x postfix &>/dev/null; then |
|
echo -e " Postfix SMTP: \${G}● RUNNING\${NC}" |
|
else |
|
echo -e " Postfix SMTP: \${Y}● NOT RUNNING\${NC}" |
|
fi |
|
|
|
echo "" |
|
echo -e " \${C}Porty (localhost): \${NC}" |
|
for PORT_DESC in "2222:SSH (VM forward)" "2525:SMTP (VM forward)" "8291:Winbox" "25:Postfix"; do |
|
PORT=\${PORT_DESC%%:*}; DESC=\${PORT_DESC#*:} |
|
nc -z 127.0.0.1 "\$PORT" 2>/dev/null \\ |
|
&& echo -e " \${G}●\${NC} \${PORT} – \${DESC}" \\ |
|
|| echo -e " \${R}○\${NC} \${PORT} – \${DESC} [zamknięty]" |
|
done |
|
|
|
echo "" |
|
echo -e " \${C}Zasoby:\${NC}" |
|
echo -e " RAM free: \$(free -m | awk '/Mem/{print \$4}') MB" |
|
echo -e " Disk free: \$(df -m ~ | tail -1 | awk '{print \$4}') MB" |
|
echo "" |
|
echo -e " \${C}Logi:\${NC}" |
|
echo -e " Główny: ~/secferro/logs/" |
|
echo -e " QEMU: ~/secferro/logs/qemu.log" |
|
echo -e " msmtp: ~/secferro/logs/msmtp.log" |
|
STATUS_SH |
|
chmod +x "$SCRIPTS_DIR/status.sh" |
|
|
|
# ── Test poczty ─────────────────────────────────────────── |
|
cat > "$SCRIPTS_DIR/test_mail.sh" << MAILTEST |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
# ── SecFerro · Test wysyłki e-mail ────────────────────────── |
|
MAIL_LOGIN="${MAIL_LOGIN}" |
|
LOG_DIR="\${HOME}/secferro/logs" |
|
CONF="\${HOME}/.msmtprc" |
|
|
|
SUBJECT="[SecFerro] Test mail \$(date +%Y-%m-%d_%H:%M)" |
|
BODY="Test wiadomosci z SecFerro Lab |
|
Host: ${TERMUX_HOSTNAME} |
|
VM: ${EMU_HOSTNAME} (${EMU_IP}) |
|
Czas: \$(date)" |
|
|
|
echo "Wysyłanie testu do: \${MAIL_LOGIN}..." |
|
|
|
if command -v msmtp &>/dev/null && [[ -f "\$CONF" ]]; then |
|
printf "To: %s\nFrom: %s\nSubject: %s\n\n%s\n" \\ |
|
"\$MAIL_LOGIN" "\$MAIL_LOGIN" "\$SUBJECT" "\$BODY" | \\ |
|
msmtp --file="\$CONF" "\$MAIL_LOGIN" && \\ |
|
echo "[✓] Wiadomość wysłana" || echo "[✗] Błąd wysyłki – sprawdź \${LOG_DIR}/msmtp.log" |
|
else |
|
echo "[!] msmtp lub .msmtprc niedostępny" |
|
echo "[i] Uruchom: ~/secferro/scripts/deploy_msmtp.sh" |
|
fi |
|
MAILTEST |
|
chmod +x "$SCRIPTS_DIR/test_mail.sh" |
|
|
|
# ── Security test ───────────────────────────────────────── |
|
cat > "$SCRIPTS_DIR/security_test.sh" << 'SECTEST' |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
# ── SecFerro · Security Audit ──────────────────────────────── |
|
G='\033[0;32m' R='\033[0;31m' Y='\033[1;33m' NC='\033[0m' |
|
TARGET="127.0.0.1" |
|
|
|
echo "════════════════════════════════════════" |
|
echo " SecFerro · Security Test Suite" |
|
echo "════════════════════════════════════════" |
|
echo "" |
|
|
|
port_check() { |
|
local port=$1 name=$2 expected=$3 |
|
nc -z -w2 "$TARGET" "$port" 2>/dev/null |
|
local open=$? |
|
if [[ "$expected" == "open" && $open -eq 0 ]]; then |
|
echo -e " ${G}[✓]${NC} Port $port ($name) – OPEN [oczekiwane]" |
|
elif [[ "$expected" == "closed" && $open -ne 0 ]]; then |
|
echo -e " ${G}[✓]${NC} Port $port ($name) – CLOSED [oczekiwane]" |
|
elif [[ "$expected" == "open" && $open -ne 0 ]]; then |
|
echo -e " ${Y}[!]${NC} Port $port ($name) – CLOSED [oczekiwany open]" |
|
else |
|
echo -e " ${R}[✗]${NC} Port $port ($name) – OPEN [powinien być zamknięty!]" |
|
fi |
|
} |
|
|
|
echo "=== Porty zarządzania ===" |
|
port_check 2222 "SSH (forward VM)" open |
|
port_check 8291 "Winbox (forward VM)" open |
|
|
|
echo "" |
|
echo "=== Usługi pocztowe ===" |
|
port_check 25 "SMTP (Postfix)" open |
|
port_check 2525 "SMTP (VM forward)" open |
|
|
|
echo "" |
|
echo "=== Usługi NIE powinny być otwarte ===" |
|
port_check 21 "FTP" closed |
|
port_check 23 "Telnet" closed |
|
port_check 80 "HTTP" closed |
|
port_check 443 "HTTPS" closed |
|
port_check 8728 "RouterOS API" closed |
|
port_check 8729 "RouterOS API-SSL" closed |
|
|
|
echo "" |
|
echo "=== CVE Check (Winbox CVE-2018-14847) ===" |
|
echo " [i] Test wymaga połączenia z VM na porcie 8291" |
|
if nc -z -w2 "$TARGET" 8291 2>/dev/null; then |
|
echo " [i] Winbox port dostępny – upewnij się że ROS >= 6.40.3" |
|
else |
|
echo " [i] Winbox port zamknięty (VM może nie działać)" |
|
fi |
|
|
|
echo "" |
|
echo "════════════════════════════════════════" |
|
SECTEST |
|
chmod +x "$SCRIPTS_DIR/security_test.sh" |
|
|
|
# ── Backup ──────────────────────────────────────────────── |
|
cat > "$SCRIPTS_DIR/backup.sh" << BACKUP_SH |
|
#!/data/data/com.termux/files/usr/bin/bash |
|
# ── SecFerro · Backup ──────────────────────────────────────── |
|
BACKUP_DIR="\${HOME}/secferro/backups" |
|
TIMESTAMP=\$(date +%Y%m%d_%H%M%S) |
|
DEST="\${BACKUP_DIR}/backup_\${TIMESTAMP}" |
|
mkdir -p "\$DEST" |
|
|
|
echo "[→] Backup sekretów..." |
|
cp -r "\${HOME}/secferro/.secrets" "\${DEST}/secrets" 2>/dev/null && echo "[✓] Sekrety" || echo "[!] Brak sekretów" |
|
|
|
echo "[→] Backup konfiguracji..." |
|
cp -r "\${HOME}/secferro/config" "\${DEST}/config" && echo "[✓] Konfiguracja" |
|
|
|
echo "[→] Backup obrazu VM (może chwilę potrwać)..." |
|
if [[ -f "\${HOME}/secferro/vm/routeros.qcow2" ]]; then |
|
cp "\${HOME}/secferro/vm/routeros.qcow2" "\${DEST}/routeros_\${TIMESTAMP}.qcow2" |
|
echo "[✓] Obraz VM: \$(du -sh "\${DEST}/routeros_\${TIMESTAMP}.qcow2" | cut -f1)" |
|
fi |
|
|
|
echo "[✓] Backup gotowy: \${DEST}" |
|
ls -lh "\${DEST}" |
|
BACKUP_SH |
|
chmod +x "$SCRIPTS_DIR/backup.sh" |
|
|
|
ok "Wszystkie skrypty runtime utworzone" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# KROK 8 · Podsumowanie i zapis danych dostępowych |
|
# ───────────────────────────────────────────────────────────── |
|
finalize() { |
|
section "KROK 8 · Finalizacja" |
|
|
|
MAIL_PASS=$(get_secret "mail_password") |
|
ROS_PASS=$(get_secret "ros_password") |
|
WINBOX_PASS=$(get_secret "winbox_password") |
|
API_TOKEN=$(get_secret "api_token") |
|
|
|
# Wdróż konfiguracje |
|
step "Wdrażanie Postfix..." |
|
bash "$SCRIPTS_DIR/deploy_postfix.sh" >> "$LOGFILE" 2>&1 && ok "Postfix wdrożony" || warn "Postfix – sprawdź log" |
|
|
|
step "Wdrażanie msmtp..." |
|
bash "$SCRIPTS_DIR/deploy_msmtp.sh" >> "$LOGFILE" 2>&1 && ok "msmtp wdrożony" || warn "msmtp – sprawdź log" |
|
|
|
# Plik z danymi dostępowymi (czytelny tylko przez właściciela) |
|
local ACCESS_FILE="$BASE_DIR/ACCESS_CREDENTIALS.txt" |
|
cat > "$ACCESS_FILE" << ACCESS |
|
════════════════════════════════════════════════════════════ |
|
SecFerro Lab · Dane dostępowe |
|
Wygenerowano: $(date) |
|
════════════════════════════════════════════════════════════ |
|
|
|
ŚRODOWISKO TERMUX |
|
───────────────── |
|
Hostname: ${TERMUX_HOSTNAME} |
|
|
|
EMULATOR RouterOS |
|
───────────────── |
|
Hostname: ${EMU_HOSTNAME} |
|
IP: ${EMU_IP} |
|
Loopback: ${EMU_LO} |
|
MAC: ${ROS_MAC} |
|
|
|
POCZTA (SMTP) |
|
───────────── |
|
Login: ${MAIL_LOGIN} |
|
Hasło: ${MAIL_PASS} |
|
Serwer SMTP: ${EMU_IP}:25 |
|
Serwer SMTP: ${EMU_LO}:25 |
|
Forward SSH: 127.0.0.1:2525 |
|
|
|
ROUTEROS |
|
──────── |
|
User: admin |
|
Hasło: ${ROS_PASS} |
|
SSH: ssh -p 2222 admin@127.0.0.1 |
|
Winbox port: 127.0.0.1:8291 |
|
|
|
API TOKEN |
|
───────── |
|
Token: ${API_TOKEN} |
|
|
|
LOKALIZACJA SEKRETÓW |
|
──────────────────── |
|
Katalog: ${SECRETS_DIR}/ |
|
Prawa: 700 (katalog) / 600 (pliki) |
|
|
|
SZYBKIE KOMENDY |
|
─────────────── |
|
Start VM: ~/secferro/scripts/start_vm.sh |
|
Stop VM: ~/secferro/scripts/stop_vm.sh |
|
Status: ~/secferro/scripts/status.sh |
|
Test mail: ~/secferro/scripts/test_mail.sh |
|
Security: ~/secferro/scripts/security_test.sh |
|
Backup: ~/secferro/scripts/backup.sh |
|
|
|
════════════════════════════════════════════════════════════ |
|
UWAGA: Ten plik zawiera hasła! Chroń dostęp. |
|
Lokalizacja: ${ACCESS_FILE} |
|
════════════════════════════════════════════════════════════ |
|
ACCESS |
|
chmod 600 "$ACCESS_FILE" |
|
|
|
# Utwórz alias startowy |
|
local ALIAS_LINE="alias secferro='bash ${SCRIPTS_DIR}/status.sh'" |
|
if ! grep -q "secferro" "$HOME/.bashrc" 2>/dev/null; then |
|
echo "$ALIAS_LINE" >> "$HOME/.bashrc" |
|
echo "alias sfstart='bash ${SCRIPTS_DIR}/start_vm.sh'" >> "$HOME/.bashrc" |
|
echo "alias sfstop='bash ${SCRIPTS_DIR}/stop_vm.sh'" >> "$HOME/.bashrc" |
|
echo "alias sftest='bash ${SCRIPTS_DIR}/security_test.sh'" >> "$HOME/.bashrc" |
|
fi |
|
|
|
# Finalne podsumowanie |
|
echo "" |
|
echo -e "${G}${BOLD}╔══════════════════════════════════════════════════════════╗${NC}" |
|
echo -e "${G}${BOLD}║ Instalacja zakończona pomyślnie! ║${NC}" |
|
echo -e "${G}${BOLD}╚══════════════════════════════════════════════════════════╝${NC}" |
|
echo "" |
|
echo -e " ${INFO} Dane dostępowe: ${W}${ACCESS_FILE}${NC}" |
|
echo -e " ${INFO} Log instalacji: ${W}${LOGFILE}${NC}" |
|
echo -e " ${INFO} Sekrety: ${W}${SECRETS_DIR}/${NC}" |
|
echo "" |
|
echo -e " ${STEP} ${W}Następne kroki:${NC}" |
|
echo -e " 1. ${C}source ~/.bashrc${NC} – załaduj aliasy" |
|
echo -e " 2. ${C}sfstart${NC} – uruchom VM" |
|
echo -e " 3. ${C}secferro${NC} – sprawdź status" |
|
echo -e " 4. ${C}~/secferro/scripts/test_mail.sh${NC} – testuj pocztę" |
|
echo "" |
|
echo -e " ${WARN} Uruchom: ${C}cat ${ACCESS_FILE}${NC} aby zobaczyć hasła" |
|
echo "" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────── |
|
# GŁÓWNY FLOW INSTALACJI |
|
# ───────────────────────────────────────────────────────────── |
|
main() { |
|
# Utwórz strukturę katalogów |
|
mkdir -p "$BASE_DIR" "$LOG_DIR" "$CONF_DIR" "$SECRETS_DIR" \ |
|
"$VM_DIR" "$BACKUP_DIR" "$SCRIPTS_DIR" |
|
chmod 700 "$SECRETS_DIR" |
|
|
|
banner |
|
|
|
echo -e " ${INFO} Instalator SecFerro v${VERSION}" |
|
echo -e " ${INFO} Log: ${LOGFILE}" |
|
echo "" |
|
|
|
if ! confirm "Rozpocząć interaktywną instalację środowiska SecFerro?"; then |
|
echo -e " ${WARN} Instalacja anulowana." |
|
exit 0 |
|
fi |
|
|
|
# Pytaj o kroki opcjonalne |
|
echo "" |
|
echo -e " ${STEP} ${W}Wybierz komponenty do instalacji:${NC}" |
|
echo "" |
|
|
|
DO_PKGS=true |
|
DO_MAIL=true |
|
DO_ROSVM=true |
|
|
|
confirm " Zainstalować/zaktualizować pakiety systemowe?" || DO_PKGS=false |
|
confirm " Skonfigurować serwer i klienta SMTP?" || DO_MAIL=false |
|
confirm " Pobrać i skonfigurować emulator RouterOS?" || DO_ROSVM=false |
|
|
|
echo "" |
|
|
|
# Wykonaj kroki |
|
diag_system |
|
$DO_PKGS && install_packages |
|
generate_secrets |
|
$DO_MAIL && setup_mail_server |
|
$DO_MAIL && setup_mail_client |
|
$DO_ROSVM && download_routeros |
|
$DO_ROSVM && generate_ros_config |
|
create_runtime_scripts |
|
finalize |
|
} |
|
|
|
# ── Entry point ────────────────────────────────────────────── |
|
main "$@" |