#!/usr/bin/env bash
# =============================================================================
# install_tech_tools.sh
# Installation d'outils Tech sur Debian / Ubuntu
#
# Usage :
# chmod +x install_tech_tools.sh
# sudo ./install_tech_tools.sh [--dry-run] [--section SECTION]
#
# Options :
# --dry-run Affiche les commandes sans les exécuter
# --section SECTION N'installe qu'une section (ex: network, forensics, devops…)
# --help Affiche cette aide
#
# Sections disponibles :
# maintenance | network | devops | filesystems | misc
# password | forensics| backup | remote | virtualization
# anonymization| ai | osint
# =============================================================================
set -euo pipefail
# ─── Couleurs ────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GRN='\033[0;32m'; YLW='\033[1;33m'
BLU='\033[0;34m'; CYN='\033[0;36m'; BOLD='\033[1m'; RST='\033[0m'
DRY_RUN=false
SECTION_FILTER=""
LOG_FILE="/var/log/tech_tools_install_$(date +%Y%m%d_%H%M%S).log"
# ─── Détection de la distribution ────────────────────────────────────────────
DISTRO_ID=$(. /etc/os-release && echo "${ID}")
DISTRO_ID_LIKE=$(. /etc/os-release && echo "${ID_LIKE:-}")
DISTRO_CODENAME=$(. /etc/os-release && echo "${VERSION_CODENAME:-${UBUNTU_CODENAME:-}}")
IS_DEBIAN=false
IS_UBUNTU=false
if [[ "$DISTRO_ID" == "debian" ]]; then
IS_DEBIAN=true
elif [[ "$DISTRO_ID" == "ubuntu" || "$DISTRO_ID" == "pop" || "$DISTRO_ID_LIKE" == *"ubuntu"* ]]; then
IS_UBUNTU=true
DISTRO_CODENAME=$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$DISTRO_CODENAME}")
fi
# ─── Parsing arguments ───────────────────────────────────────────────────────
usage() {
grep '^# ' "$0" | sed 's/# //'
exit 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=true; shift ;;
--section) SECTION_FILTER="$2"; shift 2 ;;
--help|-h) usage ;;
*) echo "Option inconnue : $1"; usage ;;
esac
done
# ─── Helpers ─────────────────────────────────────────────────────────────────
info() { echo -e "${BLU}[INFO]${RST} $*" | tee -a "$LOG_FILE"; }
success() { echo -e "${GRN}[OK]${RST} $*" | tee -a "$LOG_FILE"; }
warn() { echo -e "${YLW}[WARN]${RST} $*" | tee -a "$LOG_FILE"; }
error() { echo -e "${RED}[ERR]${RST} $*" | tee -a "$LOG_FILE"; }
title() { echo -e "\n${BOLD}${CYN}══════════ $* ══════════${RST}" | tee -a "$LOG_FILE"; }
apt_install() {
local section="$1"; shift
local pkgs=("$@")
if [[ -n "$SECTION_FILTER" && "$section" != "$SECTION_FILTER" ]]; then return; fi
info "Installation section : ${BOLD}${section}${RST} (${#pkgs[@]} paquets)"
local available=()
local missing=()
for pkg in "${pkgs[@]}"; do
if apt-cache show "$pkg" &>/dev/null 2>&1; then
available+=("$pkg")
else
missing+=("$pkg")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
warn "Paquets non trouvés dans les dépôts (ignorés) : ${missing[*]}"
fi
if [[ ${#available[@]} -eq 0 ]]; then
warn "Aucun paquet disponible pour la section $section."
return
fi
if $DRY_RUN; then
echo -e "${YLW}[DRY-RUN]${RST} apt-get install -y ${available[*]}"
else
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
"${available[@]}" 2>&1 | tee -a "$LOG_FILE" || warn "Certains paquets ont échoué dans $section"
success "Section $section terminée."
fi
}
# ─── Vérifications ───────────────────────────────────────────────────────────
if [[ $EUID -ne 0 ]] && ! $DRY_RUN; then
error "Ce script doit être exécuté en root (sudo)."
exit 1
fi
title "Tech Tools Installer"
info "Distribution : $DISTRO_ID ($DISTRO_CODENAME)"
info "Log : $LOG_FILE"
info "Mode dry-run : $DRY_RUN"
[[ -n "$SECTION_FILTER" ]] && info "Filtre section : $SECTION_FILTER"
# ─── Mise à jour des dépôts ──────────────────────────────────────────────────
if [[ -z "$SECTION_FILTER" ]] || [[ "$SECTION_FILTER" == "update" ]]; then
title "Mise à jour des dépôts APT"
if ! $DRY_RUN; then
apt-get update -qq | tee -a "$LOG_FILE"
else
echo "[DRY-RUN] apt-get update"
fi
fi
# ─── Ajout des dépôts tiers nécessaires ─────────────────────────────────────
setup_repos() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "repos" ]]; then return; fi
title "Configuration des dépôts tiers"
# Docker
if ! command -v docker &>/dev/null; then
local docker_distro="debian"
local docker_codename="$DISTRO_CODENAME"
if $IS_UBUNTU; then
docker_distro="ubuntu"
fi
info "Ajout dépôt Docker ($docker_distro/$docker_codename)..."
if ! $DRY_RUN; then
curl -fsSL "https://download.docker.com/linux/${docker_distro}/gpg" \
| gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/${docker_distro} ${docker_codename} stable" \
> /etc/apt/sources.list.d/docker.list
else
echo "[DRY-RUN] Ajout dépôt Docker ($docker_distro)"
fi
fi
# Ansible PPA (Ubuntu uniquement) / paquet Debian standard
if ! command -v ansible &>/dev/null; then
if $IS_UBUNTU; then
info "Ajout PPA Ansible..."
if ! $DRY_RUN; then
add-apt-repository -y ppa:ansible/ansible 2>&1 | tee -a "$LOG_FILE" || true
else
echo "[DRY-RUN] add-apt-repository ppa:ansible/ansible"
fi
else
info "Ansible sera installé depuis les dépôts Debian standard."
fi
fi
# WireGuard (inclus dans le kernel 5.6+)
info "WireGuard est inclus dans le kernel 5.6+ — aucun dépôt nécessaire."
# Dépôts supplémentaires selon la distribution
if $IS_UBUNTU; then
info "Activation dépôts universe + multiverse..."
if ! $DRY_RUN; then
add-apt-repository -y universe 2>&1 | tee -a "$LOG_FILE" || true
add-apt-repository -y multiverse 2>&1 | tee -a "$LOG_FILE" || true
else
echo "[DRY-RUN] activation universe + multiverse"
fi
elif $IS_DEBIAN; then
info "Activation dépôts contrib + non-free..."
if ! $DRY_RUN; then
if ! grep -qE "contrib|non-free" /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null; then
sed -i 's/^deb \(.*\) main$/deb \1 main contrib non-free non-free-firmware/' /etc/apt/sources.list 2>/dev/null || true
fi
else
echo "[DRY-RUN] activation contrib + non-free"
fi
fi
if ! $DRY_RUN; then apt-get update -qq | tee -a "$LOG_FILE"; fi
success "Dépôts configurés."
}
setup_repos
# ═══════════════════════════════════════════════════════════════════════════════
# 1. MAINTENANCE — DISKS & HARDWARE
# ═══════════════════════════════════════════════════════════════════════════════
title "1. Maintenance — Disques & Hardware"
apt_install "maintenance" \
e2fsprogs baobab diskscan disktype gpart gsmartcontrol hdparm ioping testdisk \
ncdu smartmontools di util-linux iotop iozone3 nvme-cli \
cpulimit dmidecode fio hardinfo lshw pcp stress stress-ng \
memtester inxi sysstat hwdata \
chkrootkit clamtk rkhunter clamav clamav-daemon clamav-freshclam \
xsensors lm-sensors psensor
# ═══════════════════════════════════════════════════════════════════════════════
# 2. CLONAGE & SAUVEGARDE DISQUE
# ═══════════════════════════════════════════════════════════════════════════════
title "2. Clonage & Sauvegarde disque"
apt_install "backup_disk" \
clonezilla dcfldd dc3dd fsarchiver partclone partimage guymager
# ═══════════════════════════════════════════════════════════════════════════════
# 3. OUTILS DE MOT DE PASSE & CRYPTOGRAPHIE
# ═══════════════════════════════════════════════════════════════════════════════
title "3. Password Tools"
apt_install "password" \
bruteforce-luks chntpw cmospwd fcrackzip hashcat hydra \
john ophcrack ophcrack-cli pdfcrack rarcrack samdump2 crunch
# ═══════════════════════════════════════════════════════════════════════════════
# 4. PARTITIONNEMENT & EFFACEMENT
# ═══════════════════════════════════════════════════════════════════════════════
title "4. Partitionnement & Effacement sécurisé"
apt_install "partitioning" \
fatresize fdisk gdisk gparted nwipe parted secure-delete wipe \
zerofree bleachbit scrub util-linux
# ═══════════════════════════════════════════════════════════════════════════════
# 5. PROTECTION DES DONNÉES
# ═══════════════════════════════════════════════════════════════════════════════
title "5. Protection des données"
apt_install "data_protection" \
fscrypt lockfile-progs zulucrypt-cli zulucrypt-gui \
zulumount-cli zulumount-gui cryptsetup
# ═══════════════════════════════════════════════════════════════════════════════
# 6. RÉCUPÉRATION DE DONNÉES (FORENSICS)
# ═══════════════════════════════════════════════════════════════════════════════
title "6. Récupération de données & Forensics"
apt_install "forensics" \
gddrescue ddrescueview ext4magic extundelete foremost testdisk \
magicrescue myrescue recoverdm recoverjpeg safecopy scalpel \
sleuthkit autopsy
# ═══════════════════════════════════════════════════════════════════════════════
# 7. FICHIERS DUPLIQUÉS
# ═══════════════════════════════════════════════════════════════════════════════
title "7. Fichiers dupliqués"
apt_install "duplicates" \
dupeguru fdupes rdfind
# ═══════════════════════════════════════════════════════════════════════════════
# 8. RÉSEAU — DHCP / DNS / IP / Ethernet
# ═══════════════════════════════════════════════════════════════════════════════
title "8. Réseau — DHCP / DNS / IP / Ethernet"
apt_install "network_base" \
dhcpdump dhcping \
dnsenum mdns-scan whois bind9-dnsutils \
ethstatus ethtool \
net-tools ipcalc sipcalc iproute2 iptraf-ng ipv6calc \
traceroute iputils-tracepath ndisc6
# ═══════════════════════════════════════════════════════════════════════════════
# 9. RÉSEAU — Monitoring & Capture
# ═══════════════════════════════════════════════════════════════════════════════
title "9. Réseau — Monitoring & Capture réseau"
apt_install "network_monitoring" \
cbm etherape ifstat iftop iperf iperf3 nethogs sockstat tcpstat \
darkstat ngrep pcapfix scapy python3-scapy tcpdump tcpreplay \
tcpxtract tshark wireshark
# ═══════════════════════════════════════════════════════════════════════════════
# 10. RÉSEAU — Scanners & Pentest réseau
# ═══════════════════════════════════════════════════════════════════════════════
title "10. Réseau — Scanners & Outils pentest"
apt_install "network_scan" \
arp-scan arpalert iputils-arping arptables arpwatch macchanger \
bettercap driftnet dsniff ettercap-graphical lft masscan \
mitmproxy mtr-tiny netdiscover netsniff-ng ncat nmap telnet \
traceroute netcat-openbsd tcpflow tcptrace tcptraceroute
# ═══════════════════════════════════════════════════════════════════════════════
# 11. SSL/TLS
# ═══════════════════════════════════════════════════════════════════════════════
title "11. SSL/TLS Analysis"
apt_install "ssl_tls" \
ssldump sslsplit sslscan
# ═══════════════════════════════════════════════════════════════════════════════
# 12. WI-FI
# ═══════════════════════════════════════════════════════════════════════════════
title "12. Wi-Fi"
apt_install "wifi" \
aircrack-ng iw rfkill linssid
# ═══════════════════════════════════════════════════════════════════════════════
# 13. VPN
# ═══════════════════════════════════════════════════════════════════════════════
title "13. VPN"
apt_install "vpn" \
openvpn wireguard openfortivpn \
network-manager-openvpn network-manager-openconnect \
network-manager-openvpn-gnome network-manager-openconnect-gnome
# ═══════════════════════════════════════════════════════════════════════════════
# 14. ANONYMISATION — TOR & ANONSURF
# ═══════════════════════════════════════════════════════════════════════════════
title "14. Anonymisation — Tor & AnonSurf"
apt_install "anonymization" \
tor torsocks torbrowser-launcher obfs4proxy nyx macchanger iptables
# ─── AnonSurf (transparent proxy via Tor) ────────────────────────────────────
install_anonsurf() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "anonymization" ]]; then return; fi
if command -v anonsurf &>/dev/null; then
info "AnonSurf déjà installé — passage."
return
fi
info "Installation d'AnonSurf (transparent Tor proxy)..."
if $DRY_RUN; then
echo "[DRY-RUN] Clone + compilation + installation AnonSurf"
return
fi
local ANONSURF_SRC="/opt/anonsurf"
# Cloner si pas déjà présent
if [[ ! -d "$ANONSURF_SRC/.git" ]]; then
info "Clonage du dépôt AnonSurf..."
git clone https://github.com/ParrotSec/anonsurf.git "$ANONSURF_SRC" 2>&1 | tee -a "$LOG_FILE" || {
warn "AnonSurf : clonage échoué"; return
}
else
info "Sources AnonSurf trouvées dans $ANONSURF_SRC"
fi
# Installer Nim si nécessaire (pour compiler dnstool et make-torrc)
if ! command -v nim &>/dev/null; then
info "Installation du compilateur Nim..."
DEBIAN_FRONTEND=noninteractive apt-get install -y nim 2>&1 | tee -a "$LOG_FILE" || {
warn "Nim : installation échouée — AnonSurf ne peut pas être compilé"; return
}
fi
# Compiler les binaires essentiels
local BUILD_DIR
BUILD_DIR=$(mktemp -d /tmp/anonsurf-build.XXXXX)
info "Compilation de dnstool..."
if ! nim c --out:"$BUILD_DIR/dnstool" -d:release "$ANONSURF_SRC/src/nim/dnstool/dnstool.nim" 2>&1 | tee -a "$LOG_FILE"; then
warn "AnonSurf : compilation dnstool échouée"; rm -rf "$BUILD_DIR"; return
fi
info "Compilation de make-torrc..."
if ! nim c --out:"$BUILD_DIR/make-torrc" -d:release "$ANONSURF_SRC/src/nim/anonsurf/make_torrc.nim" 2>&1 | tee -a "$LOG_FILE"; then
warn "AnonSurf : compilation make-torrc échouée"; rm -rf "$BUILD_DIR"; return
fi
# Créer les répertoires
mkdir -p /etc/anonsurf /usr/lib/anonsurf /etc/network
# Installer les binaires compilés
install -m 755 "$BUILD_DIR/dnstool" /usr/bin/dnstool
install -m 755 "$BUILD_DIR/make-torrc" /usr/lib/anonsurf/make-torrc
rm -rf "$BUILD_DIR"
# Installer les scripts daemon
install -m 755 "$ANONSURF_SRC/scripts/anondaemon" /usr/lib/anonsurf/anondaemon
install -m 755 "$ANONSURF_SRC/scripts/safekill" /usr/lib/anonsurf/safekill
# Installer les configs
cp "$ANONSURF_SRC/configs/bridges.txt" /etc/anonsurf/
cp "$ANONSURF_SRC/configs/onion.pac" /etc/anonsurf/
cp "$ANONSURF_SRC/configs/torrc.base" /etc/anonsurf/
# Installer le service systemd
cp "$ANONSURF_SRC/sys-units/anonsurfd.service" /lib/systemd/system/anonsurfd.service
systemctl daemon-reload
# Créer le CLI wrapper (le binaire Nim CLI nécessite gintro/GTK non dispo facilement)
cat > /usr/bin/anonsurf << 'EOFCLI'
#!/bin/bash
# AnonSurf CLI — wrapper bash (remplace le binaire Nim pour systèmes non-ParrotOS)
RED='\033[0;31m'; GRN='\033[0;32m'; YLW='\033[1;33m'
BLU='\033[0;34m'; CYN='\033[0;36m'; BOLD='\033[1m'; RST='\033[0m'
show_help() {
echo -e "\n${BOLD}${CYN}AnonSurf — Transparent proxy through Tor${RST}\n"
echo -e " ${BLU}Usage:${RST} sudo anonsurf {start|stop|restart|changeid|status|myip|help}\n"
echo -e " ${GRN}start${RST} Démarrer AnonSurf (routage Tor transparent)"
echo -e " ${GRN}stop${RST} Arrêter AnonSurf (trafic normal)"
echo -e " ${GRN}restart${RST} Redémarrer AnonSurf"
echo -e " ${GRN}changeid${RST} Changer d'identité Tor (nouveau circuit)"
echo -e " ${GRN}status${RST} État d'AnonSurf et Tor"
echo -e " ${GRN}myip${RST} Afficher l'IP publique actuelle"
echo -e " ${GRN}enable-boot${RST} Activer AnonSurf au démarrage"
echo -e " ${GRN}disable-boot${RST} Désactiver AnonSurf au démarrage"
echo ""
}
check_root() {
if [[ $(id -u) -ne 0 ]]; then
echo -e "[${RED}!${RST}] Droits root requis. Utilisez sudo."; exit 1
fi
}
do_start() {
check_root
if systemctl is-active --quiet anonsurfd 2>/dev/null; then
echo -e "[${YLW}!${RST}] AnonSurf est déjà actif."; return; fi
echo -e "[${GRN}*${RST}]${BLU} Démarrage d'AnonSurf...${RST}"
systemctl start anonsurfd
if systemctl is-active --quiet anonsurfd 2>/dev/null; then
echo -e "[${GRN}*${RST}] AnonSurf démarré."; sleep 2; do_myip
else
echo -e "[${RED}!${RST}] Échec du démarrage."; journalctl -u anonsurfd --no-pager -n 10; fi
}
do_stop() {
check_root
if ! systemctl is-active --quiet anonsurfd 2>/dev/null; then
echo -e "[${YLW}!${RST}] AnonSurf n'est pas actif."; return; fi
echo -e "[${GRN}*${RST}]${BLU} Arrêt d'AnonSurf...${RST}"
systemctl stop anonsurfd
echo -e "[${GRN}*${RST}] AnonSurf arrêté."
}
do_restart() {
check_root
echo -e "[${GRN}*${RST}]${BLU} Redémarrage d'AnonSurf...${RST}"
systemctl restart anonsurfd; sleep 2
if systemctl is-active --quiet anonsurfd 2>/dev/null; then
echo -e "[${GRN}*${RST}] AnonSurf redémarré."; do_myip
else echo -e "[${RED}!${RST}] Échec du redémarrage."; fi
}
do_changeid() {
if ! systemctl is-active --quiet anonsurfd 2>/dev/null; then
echo -e "[${RED}!${RST}] AnonSurf n'est pas actif."; return; fi
echo -e "[${GRN}*${RST}]${BLU} Nouvelle identité Tor...${RST}"
killall -HUP tor 2>/dev/null; sleep 3; do_myip
}
do_status() {
echo -e "\n${BOLD}${CYN}=== État AnonSurf ===${RST}"
if systemctl is-active --quiet anonsurfd 2>/dev/null; then
echo -e "[${GRN}*${RST}] AnonSurf : ${GRN}ACTIF${RST}"
else echo -e "[${RED}*${RST}] AnonSurf : ${RED}INACTIF${RST}"; fi
if systemctl is-active --quiet tor 2>/dev/null || systemctl is-active --quiet tor@default 2>/dev/null; then
echo -e "[${GRN}*${RST}] Tor : ${GRN}ACTIF${RST}"
else echo -e "[${RED}*${RST}] Tor : ${RED}INACTIF${RST}"; fi
if systemctl is-enabled --quiet anonsurfd 2>/dev/null; then
echo -e "[${GRN}*${RST}] Boot : ${GRN}ACTIVÉ${RST}"
else echo -e "[${YLW}*${RST}] Boot : ${YLW}DÉSACTIVÉ${RST}"; fi
echo ""; do_myip
}
do_myip() {
echo -e "[${GRN}*${RST}]${BLU} Vérification de l'IP publique...${RST}"
local resp; resp=$(curl -s --max-time 10 https://check.torproject.org/api/ip 2>/dev/null)
if [[ -n "$resp" ]]; then
local is_tor; is_tor=$(echo "$resp" | grep -o '"IsTor":[a-z]*' | cut -d: -f2)
local addr; addr=$(echo "$resp" | grep -o '"IP":"[^"]*"' | cut -d'"' -f4)
if [[ "$is_tor" == "true" ]]; then
echo -e "[${GRN}*${RST}] IP : ${GRN}$addr${RST} (via Tor)"
else
echo -e "[${YLW}!${RST}] IP : ${YLW}$addr${RST} (${RED}PAS via Tor${RST})"
fi
else echo -e "[${RED}!${RST}] Impossible de déterminer l'IP publique."; fi
}
case "${1:-help}" in
start) do_start ;;
stop) do_stop ;;
restart) do_restart ;;
changeid) do_changeid ;;
status) do_status ;;
myip) do_myip ;;
enable-boot) check_root; systemctl enable anonsurfd 2>/dev/null; echo -e "[${GRN}*${RST}] AnonSurf activé au boot." ;;
disable-boot) check_root; systemctl disable anonsurfd 2>/dev/null; echo -e "[${GRN}*${RST}] AnonSurf désactivé au boot." ;;
help) show_help ;;
*) echo -e "[${RED}!${RST}] Option invalide : $1"; show_help; exit 1 ;;
esac
EOFCLI
chmod +x /usr/bin/anonsurf
success "AnonSurf installé. Usage : sudo anonsurf start|stop|status|myip"
}
install_anonsurf
# ═══════════════════════════════════════════════════════════════════════════════
# 15. PORT CONSOLE & DIVERS RÉSEAU
# ═══════════════════════════════════════════════════════════════════════════════
title "15. Console série & divers réseau"
apt_install "serial_misc" \
cu minicom picocom screen setserial gtkterm \
socat wakeonlan bridge-utils tftp-hpa tftpd-hpa
# ═══════════════════════════════════════════════════════════════════════════════
# 16. ADMINISTRATION À DISTANCE
# ═══════════════════════════════════════════════════════════════════════════════
title "16. Administration à distance"
apt_install "remote" \
rdesktop freerdp2-x11 openssh-client sshfs pssh clusterssh tmux \
remmina remmina-plugin-rdp remmina-plugin-vnc remmina-plugin-secret \
smbclient sshpass
# ═══════════════════════════════════════════════════════════════════════════════
# 17. SAUVEGARDES
# ═══════════════════════════════════════════════════════════════════════════════
title "17. Sauvegardes"
apt_install "backup" \
dirvish automysqlbackup bacula-client bacula-console dump \
duplicity restic rsync rdiff-backup borgbackup rclone grsync zsync
# ═══════════════════════════════════════════════════════════════════════════════
# 18. FTP
# ═══════════════════════════════════════════════════════════════════════════════
title "18. FTP"
apt_install "ftp" \
filezilla gftp lftp
# ═══════════════════════════════════════════════════════════════════════════════
# 19. VIRTUALISATION
# ═══════════════════════════════════════════════════════════════════════════════
title "19. Virtualisation"
apt_install "virtualization" \
virt-manager qemu-system qemu-system-x86 qemu-utils \
libvirt-clients libvirt-daemon libvirt-daemon-system \
virtinst virt-viewer \
lxc
# ─── VirtualBox (via dépôt Oracle) ───────────────────────────────────────────
install_virtualbox() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "virtualization" ]]; then return; fi
info "Installation VirtualBox via dépôt Oracle..."
if $DRY_RUN; then
echo "[DRY-RUN] Installation VirtualBox (Oracle repo)"
return
fi
wget -qO- https://www.virtualbox.org/download/oracle_vbox_2016.asc \
| gpg --yes --dearmor -o /usr/share/keyrings/oracle-virtualbox-2016.gpg 2>/dev/null || true
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/oracle-virtualbox-2016.gpg] \
https://download.virtualbox.org/virtualbox/debian ${DISTRO_CODENAME} contrib" \
> /etc/apt/sources.list.d/virtualbox.list
apt-get update -qq && apt-get install -y virtualbox-7.0 || warn "VirtualBox : installation échouée"
}
install_virtualbox
# ═══════════════════════════════════════════════════════════════════════════════
# 20. SYSTÈME DIVERS (Administration)
# ═══════════════════════════════════════════════════════════════════════════════
title "20. Divers système & Administration"
apt_install "sysadmin_misc" \
xca krb5-config krb5-pkinit krb5-user \
apache2-utils chrony python3-ldap3 \
apparmor apparmor-profiles apparmor-utils
apt_install "db_clients" \
mariadb-client postgresql-client
# ═══════════════════════════════════════════════════════════════════════════════
# 21. DEVOPS & CLOUD
# ═══════════════════════════════════════════════════════════════════════════════
title "21. DevOps & Cloud"
# Docker
apt_install "docker" \
docker.io docker-compose containerd
# Ansible
apt_install "ansible" \
ansible ansible-lint
# Outils DevOps dans les dépôts standard
apt_install "devops_std" \
podman buildah
# ─── Outils DevOps via installation directe ─────────────────────────────────
install_devops_extras() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "devops" ]]; then return; fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation outils DevOps extras (kubectl, k9s, minikube, lazydocker)"
return
fi
local ARCH; ARCH=$(dpkg --print-architecture)
# kubectl
if ! command -v kubectl &>/dev/null; then
info "Installation kubectl..."
curl -fsSL "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/${ARCH}/kubectl" \
-o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl || warn "kubectl : échec"
fi
# minikube
if ! command -v minikube &>/dev/null; then
info "Installation minikube..."
curl -fsSLo /usr/local/bin/minikube \
"https://storage.googleapis.com/minikube/releases/latest/minikube-linux-${ARCH}" \
&& chmod +x /usr/local/bin/minikube || warn "minikube : échec"
fi
# lazydocker
if ! command -v lazydocker &>/dev/null; then
info "Installation lazydocker..."
local LD_VERSION
LD_VERSION=$(curl -s https://api.github.com/repos/jesseduffield/lazydocker/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4 | tr -d 'v')
curl -fsSL "https://github.com/jesseduffield/lazydocker/releases/latest/download/lazydocker_${LD_VERSION}_Linux_x86_64.tar.gz" \
| tar xz -C /usr/local/bin lazydocker && chmod +x /usr/local/bin/lazydocker || warn "lazydocker : échec"
fi
success "DevOps extras installés."
}
install_devops_extras
# ═══════════════════════════════════════════════════════════════════════════════
# 22. SYSTÈMES DE FICHIERS
# ═══════════════════════════════════════════════════════════════════════════════
title "22. Systèmes de fichiers"
apt_install "filesystems" \
cryptsetup cryptsetup-initramfs dmsetup mdadm lvm2 \
dosfstools f2fs-tools nilfs-tools \
btrfs-progs \
hfsplus hfsprogs hfsutils \
jfsutils \
xfsdump xfsprogs \
zfsutils-linux zfs-zed \
exfatprogs fuse3 udftools \
cifs-utils ntfs-3g wimtools \
dislocker
# ═══════════════════════════════════════════════════════════════════════════════
# 23. SNAPSHOTS SYSTÈME
# ═══════════════════════════════════════════════════════════════════════════════
title "23. Snapshots système"
apt_install "snapshots" \
snapper timeshift btrbk
# ═══════════════════════════════════════════════════════════════════════════════
# 24. OUTILS DIVERS / MISCELLANEOUS
# ═══════════════════════════════════════════════════════════════════════════════
title "24. Outils divers"
apt_install "misc" \
progress pv less plocate dirmngr gpa gpg gnupg2 curl wget git \
gpg-agent img2pdf mc strace ltrace tree vim cups hexedit file \
psmisc htop lsof lzop p7zip-full pigz unp unar unrar-free unzip \
zip bzip2 tar unrar zstd gtkhash keepassxc apg pwgen \
cabextract btop jq yq yamllint simple-scan
# ═══════════════════════════════════════════════════════════════════════════════
# 25. GNS3 (réseau lab)
# ═══════════════════════════════════════════════════════════════════════════════
install_gns3() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "network" ]]; then return; fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation GNS3"
return
fi
if $IS_UBUNTU; then
info "Installation GNS3 via PPA..."
add-apt-repository -y ppa:gns3/ppa 2>&1 | tee -a "$LOG_FILE" || true
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y gns3-gui gns3-server dynamips vpcs || \
warn "GNS3 : installation incomplète"
else
info "Installation GNS3 depuis les dépôts Debian..."
DEBIAN_FRONTEND=noninteractive apt-get install -y gns3-gui gns3-server dynamips vpcs 2>&1 | tee -a "$LOG_FILE" || \
warn "GNS3 : non disponible dans les dépôts Debian — installer via pip : pip3 install gns3-gui gns3-server"
fi
}
install_gns3
# ═══════════════════════════════════════════════════════════════════════════════
# 26. POWERSHELL
# ═══════════════════════════════════════════════════════════════════════════════
install_powershell() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "misc" ]]; then return; fi
if command -v pwsh &>/dev/null; then
info "PowerShell déjà installé."; return
fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation PowerShell"
return
fi
local ARCH; ARCH=$(dpkg --print-architecture)
if [[ "$ARCH" != "amd64" ]]; then
warn "PowerShell : architecture $ARCH non supportée"; return
fi
info "Installation PowerShell via packages.microsoft.com..."
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --yes --dearmor -o /usr/share/keyrings/microsoft-prod.gpg 2>/dev/null || true
local ms_codename="$DISTRO_CODENAME"
if $IS_UBUNTU || [[ "$DISTRO_ID" == "pop" ]]; then
local ubuntu_codename
ubuntu_codename=$(. /etc/os-release && echo "${UBUNTU_CODENAME:-}")
if [[ -n "$ubuntu_codename" ]]; then
ms_codename="$ubuntu_codename"
fi
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/${ms_codename}/prod ${ms_codename} main" \
> /etc/apt/sources.list.d/microsoft-prod.list 2>/dev/null || true
else
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/debian/${DISTRO_CODENAME}/prod ${DISTRO_CODENAME} main" \
> /etc/apt/sources.list.d/microsoft-prod.list 2>/dev/null || true
fi
if apt-get update -qq && apt-get install -y powershell 2>&1 | tee -a "$LOG_FILE"; then
success "PowerShell installé."
else
warn "PowerShell : dépôt Microsoft indisponible pour ${ms_codename} — installation via .deb..."
local PS_VERSION
PS_VERSION=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4 | tr -d 'v')
if [[ -n "$PS_VERSION" ]]; then
local DEB_FILE="/tmp/powershell_${PS_VERSION}_amd64.deb"
curl -fsSL "https://github.com/PowerShell/PowerShell/releases/download/v${PS_VERSION}/powershell_${PS_VERSION}-1.deb_amd64.deb" \
-o "$DEB_FILE" && dpkg -i "$DEB_FILE" && apt-get install -f -y 2>&1 | tee -a "$LOG_FILE" \
&& rm -f "$DEB_FILE" \
|| warn "PowerShell : installation via .deb échouée — voir https://learn.microsoft.com/powershell/scripting/install/installing-powershell-on-linux"
else
warn "PowerShell : impossible de déterminer la dernière version"
fi
fi
}
install_powershell
# ═══════════════════════════════════════════════════════════════════════════════
# 27. OUTILS IA
# ═══════════════════════════════════════════════════════════════════════════════
title "27. Outils IA"
apt_install "ai_base" \
python3-pip python3-venv python3-full nodejs npm
# ─── Ollama (LLM local) ─────────────────────────────────────────────────────
install_ollama() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "ai" ]]; then return; fi
if command -v ollama &>/dev/null; then
info "Ollama déjà installé."; return
fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation Ollama"
return
fi
info "Installation Ollama..."
curl -fsSL https://ollama.com/install.sh | sh 2>&1 | tee -a "$LOG_FILE" || warn "Ollama : installation échouée"
if command -v ollama &>/dev/null; then
success "Ollama installé."
fi
}
install_ollama
# ─── Claude Code (CLI Anthropic) ─────────────────────────────────────────────
install_claude_code() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "ai" ]]; then return; fi
if command -v claude &>/dev/null; then
info "Claude Code déjà installé."; return
fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation Claude Code (npm)"
return
fi
if ! command -v npm &>/dev/null; then
warn "Claude Code : npm non disponible — installation impossible"
return
fi
info "Installation Claude Code..."
npm install -g @anthropic-ai/claude-code 2>&1 | tee -a "$LOG_FILE" || warn "Claude Code : installation échouée"
if command -v claude &>/dev/null; then
success "Claude Code installé."
fi
}
install_claude_code
# ─── Open WebUI (interface web pour Ollama) ──────────────────────────────────
install_open_webui() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "ai" ]]; then return; fi
if $DRY_RUN; then
echo "[DRY-RUN] Pull Docker open-webui"
return
fi
if ! command -v docker &>/dev/null; then
warn "Open WebUI : Docker non disponible — installation ignorée"
return
fi
if docker image inspect ghcr.io/open-webui/open-webui:main &>/dev/null 2>&1; then
info "Open WebUI : image Docker déjà présente."
return
fi
info "Téléchargement de l'image Open WebUI..."
docker pull ghcr.io/open-webui/open-webui:main 2>&1 | tee -a "$LOG_FILE" || warn "Open WebUI : pull échoué"
success "Open WebUI prêt. Lancer avec : docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui ghcr.io/open-webui/open-webui:main"
}
install_open_webui
# ═══════════════════════════════════════════════════════════════════════════════
# 28. OSINT (Open Source Intelligence)
# ═══════════════════════════════════════════════════════════════════════════════
title "28. OSINT — Open Source Intelligence"
apt_install "osint_base" \
libimage-exiftool-perl mat2 mediainfo sublist3r
# ─── Outils OSINT via pip ────────────────────────────────────────────────────
install_osint_pip() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "osint" ]]; then return; fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation outils OSINT via pip (sherlock, holehe, maigret, recon-ng, theHarvester, spiderfoot)"
return
fi
if ! command -v pip3 &>/dev/null; then
warn "OSINT pip : pip3 non disponible — installation ignorée"
return
fi
local pip_tools=("sherlock-project" "holehe" "maigret" "recon-ng" "theHarvester" "spiderfoot")
for tool in "${pip_tools[@]}"; do
if pip3 show "$tool" &>/dev/null 2>&1; then
skip "$tool déjà installé (pip)"
else
info "Installation $tool via pip..."
pip3 install --break-system-packages "$tool" 2>&1 | tee -a "$LOG_FILE" || warn "$tool : installation pip échouée"
fi
done
success "Outils OSINT pip installés."
}
install_osint_pip
# ─── Amass (énumération DNS / sous-domaines) ─────────────────────────────────
install_amass() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "osint" ]]; then return; fi
if command -v amass &>/dev/null; then
info "Amass déjà installé."; return
fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation Amass"
return
fi
local ARCH; ARCH=$(dpkg --print-architecture)
info "Installation Amass..."
local AMASS_VERSION
AMASS_VERSION=$(curl -s https://api.github.com/repos/owasp-amass/amass/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4 | tr -d 'v')
if [[ -n "$AMASS_VERSION" ]]; then
local amass_arch="amd64"
[[ "$ARCH" == "arm64" ]] && amass_arch="arm64"
curl -fsSL "https://github.com/owasp-amass/amass/releases/download/v${AMASS_VERSION}/amass_Linux_${amass_arch}.zip" \
-o /tmp/amass.zip \
&& unzip -o /tmp/amass.zip -d /tmp/amass_extract \
&& install -m 755 /tmp/amass_extract/amass_Linux_${amass_arch}/amass /usr/local/bin/amass \
&& rm -rf /tmp/amass.zip /tmp/amass_extract \
|| warn "Amass : installation échouée"
else
warn "Amass : impossible de déterminer la dernière version"
fi
if command -v amass &>/dev/null; then
success "Amass installé."
fi
}
install_amass
# ─── PhoneInfoga (OSINT téléphone) ───────────────────────────────────────────
install_phoneinfoga() {
if [[ -n "$SECTION_FILTER" ]] && [[ "$SECTION_FILTER" != "osint" ]]; then return; fi
if command -v phoneinfoga &>/dev/null; then
info "PhoneInfoga déjà installé."; return
fi
if $DRY_RUN; then
echo "[DRY-RUN] Installation PhoneInfoga"
return
fi
info "Installation PhoneInfoga..."
curl -fsSL "https://raw.githubusercontent.com/sundowndev/phoneinfoga/master/support/scripts/install" | bash 2>&1 | tee -a "$LOG_FILE" \
&& mv ./phoneinfoga /usr/local/bin/phoneinfoga 2>/dev/null \
|| warn "PhoneInfoga : installation échouée"
if command -v phoneinfoga &>/dev/null; then
success "PhoneInfoga installé."
fi
}
install_phoneinfoga
# ═══════════════════════════════════════════════════════════════════════════════
# RÉSUMÉ FINAL
# ═══════════════════════════════════════════════════════════════════════════════
title "Installation terminée"
echo -e "${GRN}${BOLD}"
echo " ╔══════════════════════════════════════════════════════╗"
echo " ║ Tech Tools : Installation terminée ! ║"
echo " ╚══════════════════════════════════════════════════════╝"
echo -e "${RST}"
info "Log complet : $LOG_FILE"
warn "Certains paquets spécifiques (exegol, etc.) n'existent"
warn "pas dans les dépôts Ubuntu et ont été ignorés intentionnellement."
warn "Pour Exegol, consulter : https://exegol.readthedocs.io/en/latest/getting-started/install.html"
echo ""
echo -e "${BLU}Outils nécessitant une action manuelle supplémentaire :${RST}"
echo " • VeraCrypt → https://www.veracrypt.fr/en/Downloads.html"
echo " • Exegol → https://exegol.readthedocs.io"
echo " • Azure CLI → https://learn.microsoft.com/cli/azure/install-azure-cli-linux"
echo " • Terraform → https://developer.hashicorp.com/terraform/downloads"
echo " • Helm → https://helm.sh/docs/intro/install/"
echo " • Vagrant → https://developer.hashicorp.com/vagrant/downloads"
echo " • Packer → https://developer.hashicorp.com/packer/downloads"
echo " • AWS CLI → https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"
echo " • SSLyze → pip3 install sslyze"
echo " • LazyGit → https://github.com/jesseduffield/lazygit#installation"
echo " • VSCodium → https://vscodium.com/#install"
echo " • Cursor → https://www.cursor.com/downloads"
echo " • LM Studio → https://lmstudio.ai/"
echo " • Maltego → https://www.maltego.com/downloads/"
echo " • MalTrail → https://github.com/stamparm/maltrail (git clone)"
echo ""
if command -v ollama &>/dev/null || command -v claude &>/dev/null; then
echo -e "${BLU}Outils IA :${RST}"
command -v ollama &>/dev/null && echo " • ollama run llama3 → Lancer un modèle local"
command -v ollama &>/dev/null && echo " • ollama list → Lister les modèles installés"
command -v claude &>/dev/null && echo " • claude → Lancer Claude Code (CLI)"
if docker image inspect ghcr.io/open-webui/open-webui:main &>/dev/null 2>&1; then
echo " • Open WebUI → docker start open-webui (port 3000)"
fi
echo ""
fi
if command -v sherlock &>/dev/null || command -v holehe &>/dev/null || command -v amass &>/dev/null; then
echo -e "${BLU}OSINT :${RST}"
command -v sherlock &>/dev/null && echo " • sherlock <username> → Recherche de comptes sur les réseaux sociaux"
command -v holehe &>/dev/null && echo " • holehe <email> → Vérifier sur quels sites un email est inscrit"
command -v maigret &>/dev/null && echo " • maigret <username> → Profiling avancé de comptes"
command -v amass &>/dev/null && echo " • amass enum -d <domain> → Énumération DNS / sous-domaines"
command -v phoneinfoga &>/dev/null && echo " • phoneinfoga scan -n <num> → OSINT sur numéro de téléphone"
command -v exiftool &>/dev/null && echo " • exiftool <fichier> → Extraction de métadonnées"
command -v mat2 &>/dev/null && echo " • mat2 <fichier> → Nettoyage de métadonnées"
command -v theharvester &>/dev/null && echo " • theHarvester -d <domain> → Collecte emails/sous-domaines"
echo ""
fi
if command -v anonsurf &>/dev/null; then
echo -e "${BLU}Anonymisation (Tor & AnonSurf) :${RST}"
echo " • sudo anonsurf start → Démarrer le proxy Tor transparent"
echo " • sudo anonsurf stop → Arrêter et restaurer le trafic normal"
echo " • sudo anonsurf status → Vérifier l'état"
echo " • sudo anonsurf myip → Vérifier l'IP publique"
echo ""
fi