Fix: permissions and ACLs for www-data on /etc/asterisk, fail2ban filters and logs, and AMI diagnostics loading
This commit is contained in:
1 parent
563a01e3c3
commit
cbc9fe7f29
4 files changed
+93
-20
No files matched your search
+67
-16
@@ -57,7 +57,8 @@ apt-get install -y --no-install-recommends \
|
|||||||
openssl \
|
openssl \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
iptables \
|
iptables \
|
||||||
iptables-persistent
|
iptables-persistent \
|
||||||
|
acl
|
||||||
|
|
||||||
# Vérification et installation d'Asterisk
|
# Vérification et installation d'Asterisk
|
||||||
echo -e "${C_GREEN} -> Installation du moteur Asterisk PBX...${C_RESET}"
|
echo -e "${C_GREEN} -> Installation du moteur Asterisk PBX...${C_RESET}"
|
||||||
@@ -156,8 +157,13 @@ mkdir -p /var/spool/asterisk/voicemail/default
|
|||||||
mkdir -p /var/log/asterisk
|
mkdir -p /var/log/asterisk
|
||||||
mkdir -p /var/log/nexus-pbx
|
mkdir -p /var/log/nexus-pbx
|
||||||
|
|
||||||
touch /var/log/asterisk/messages
|
touch /var/log/asterisk/messages /var/log/asterisk/security.log
|
||||||
chown asterisk:asterisk /var/log/asterisk/messages 2>/dev/null || true
|
chown asterisk:asterisk /var/log/asterisk/messages /var/log/asterisk/security.log 2>/dev/null || true
|
||||||
|
chmod 0664 /var/log/asterisk/messages /var/log/asterisk/security.log 2>/dev/null || true
|
||||||
|
|
||||||
|
touch /var/log/nexus_security.log
|
||||||
|
chown www-data:asterisk /var/log/nexus_security.log 2>/dev/null || true
|
||||||
|
chmod 0664 /var/log/nexus_security.log 2>/dev/null || true
|
||||||
|
|
||||||
# Droits applicatifs stricts
|
# Droits applicatifs stricts
|
||||||
chown -R www-data:asterisk "$TARGET_DIR"
|
chown -R www-data:asterisk "$TARGET_DIR"
|
||||||
@@ -168,8 +174,11 @@ chmod 2775 "$TARGET_DIR/storage" \
|
|||||||
"$TARGET_DIR/public/avatars"
|
"$TARGET_DIR/public/avatars"
|
||||||
|
|
||||||
chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk /var/spool/asterisk /var/log/asterisk
|
chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk /var/spool/asterisk /var/log/asterisk
|
||||||
|
chmod -R 775 /etc/asterisk
|
||||||
chmod 2775 /etc/asterisk
|
chmod 2775 /etc/asterisk
|
||||||
chmod 2750 /etc/asterisk/keys
|
chmod 2750 /etc/asterisk/keys
|
||||||
|
setfacl -R -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk 2>/dev/null || true
|
||||||
|
setfacl -R -d -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk 2>/dev/null || true
|
||||||
|
|
||||||
# Droits sudoers pour l'interface web (www-data)
|
# Droits sudoers pour l'interface web (www-data)
|
||||||
cat << 'EOF' > /etc/sudoers.d/nexus-pbx
|
cat << 'EOF' > /etc/sudoers.d/nexus-pbx
|
||||||
@@ -194,6 +203,8 @@ timestampevents = yes
|
|||||||
secret = AsteriskAmi2026!
|
secret = AsteriskAmi2026!
|
||||||
deny = 0.0.0.0/0.0.0.0
|
deny = 0.0.0.0/0.0.0.0
|
||||||
permit = 127.0.0.1/255.255.255.0
|
permit = 127.0.0.1/255.255.255.0
|
||||||
|
permit = 127.0.0.1/32
|
||||||
|
permit = ::1/128
|
||||||
read = all
|
read = all
|
||||||
write = all
|
write = all
|
||||||
EOF
|
EOF
|
||||||
@@ -201,7 +212,6 @@ chown asterisk:asterisk /etc/asterisk/manager.conf
|
|||||||
chmod 0640 /etc/asterisk/manager.conf
|
chmod 0640 /etc/asterisk/manager.conf
|
||||||
|
|
||||||
# Fichier de logs pour Fail2ban
|
# Fichier de logs pour Fail2ban
|
||||||
if [ ! -f /etc/asterisk/logger.conf ] || ! grep -q 'security' /etc/asterisk/logger.conf 2>/dev/null; then
|
|
||||||
cat << 'EOF' > /etc/asterisk/logger.conf
|
cat << 'EOF' > /etc/asterisk/logger.conf
|
||||||
[general]
|
[general]
|
||||||
dateformat=%F %T
|
dateformat=%F %T
|
||||||
@@ -209,10 +219,10 @@ dateformat=%F %T
|
|||||||
[logfiles]
|
[logfiles]
|
||||||
console => notice,warning,error
|
console => notice,warning,error
|
||||||
messages => notice,warning,error,security
|
messages => notice,warning,error,security
|
||||||
|
security.log => security
|
||||||
EOF
|
EOF
|
||||||
chown asterisk:asterisk /etc/asterisk/logger.conf 2>/dev/null || true
|
chown asterisk:asterisk /etc/asterisk/logger.conf 2>/dev/null || true
|
||||||
chmod 0644 /etc/asterisk/logger.conf 2>/dev/null || true
|
chmod 0664 /etc/asterisk/logger.conf 2>/dev/null || true
|
||||||
fi
|
|
||||||
|
|
||||||
# Certificat TLS auto-signé initial pour PJSIP TLS (port 5061) et Nginx HTTPS (port 8443)
|
# Certificat TLS auto-signé initial pour PJSIP TLS (port 5061) et Nginx HTTPS (port 8443)
|
||||||
if [ ! -f /etc/asterisk/keys/asterisk.crt ] || [ ! -f /etc/asterisk/keys/asterisk.key ]; then
|
if [ ! -f /etc/asterisk/keys/asterisk.crt ] || [ ! -f /etc/asterisk/keys/asterisk.key ]; then
|
||||||
@@ -230,18 +240,32 @@ fi
|
|||||||
chown asterisk:asterisk /etc/asterisk/keys/* 2>/dev/null || true
|
chown asterisk:asterisk /etc/asterisk/keys/* 2>/dev/null || true
|
||||||
chmod 0640 /etc/asterisk/keys/* 2>/dev/null || true
|
chmod 0640 /etc/asterisk/keys/* 2>/dev/null || true
|
||||||
|
|
||||||
# Inclusions custom dans Asterisk
|
# Inclusions custom dans Asterisk & initialisation des fichiers cibles
|
||||||
touch /etc/asterisk/pjsip.conf /etc/asterisk/extensions.conf
|
touch /etc/asterisk/pjsip.conf \
|
||||||
touch /etc/asterisk/pjsip.custom.conf /etc/asterisk/extensions.custom.conf
|
/etc/asterisk/pjsip.custom.conf \
|
||||||
|
/etc/asterisk/extensions.conf \
|
||||||
|
/etc/asterisk/extensions.custom.conf \
|
||||||
|
/etc/asterisk/musiconhold.custom.conf \
|
||||||
|
/etc/asterisk/voicemail.custom.conf \
|
||||||
|
/etc/asterisk/rtp.conf \
|
||||||
|
/etc/asterisk/features.conf
|
||||||
|
|
||||||
if ! grep -q 'pjsip.custom.conf' /etc/asterisk/pjsip.conf 2>/dev/null; then
|
if ! grep -q 'pjsip.custom.conf' /etc/asterisk/pjsip.conf 2>/dev/null; then
|
||||||
printf '\n#tryinclude "pjsip.custom.conf"\n' >> /etc/asterisk/pjsip.conf
|
printf '\n#tryinclude "pjsip.custom.conf"\n' >> /etc/asterisk/pjsip.conf
|
||||||
fi
|
fi
|
||||||
if ! grep -q 'extensions.custom.conf' /etc/asterisk/extensions.conf 2>/dev/null; then
|
if ! grep -q 'extensions.custom.conf' /etc/asterisk/extensions.conf 2>/dev/null; then
|
||||||
printf '\n#tryinclude "extensions.custom.conf"\n' >> /etc/asterisk/extensions.conf
|
printf '\n#tryinclude "extensions.custom.conf"\n' >> /etc/asterisk/extensions.conf
|
||||||
fi
|
fi
|
||||||
chown asterisk:asterisk /etc/asterisk/pjsip* /etc/asterisk/extensions* 2>/dev/null || true
|
chown -R asterisk:asterisk /etc/asterisk
|
||||||
chmod 0664 /etc/asterisk/pjsip.conf /etc/asterisk/extensions.conf 2>/dev/null || true
|
chmod 0664 /etc/asterisk/*.conf /etc/asterisk/*.custom.conf 2>/dev/null || true
|
||||||
chmod 0660 /etc/asterisk/*.custom.conf 2>/dev/null || true
|
chmod 2750 /etc/asterisk/keys
|
||||||
|
chmod 2775 /etc/asterisk
|
||||||
|
setfacl -R -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk 2>/dev/null || true
|
||||||
|
setfacl -R -d -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk 2>/dev/null || true
|
||||||
|
|
||||||
|
# Rechargement Asterisk immédiat pour appliquer AMI et Logger
|
||||||
|
asterisk -rx "core reload" 2>/dev/null || true
|
||||||
|
asterisk -rx "manager reload" 2>/dev/null || true
|
||||||
|
|
||||||
# 6. Initialisation de la Base de données SQLite & Configuration initiale
|
# 6. Initialisation de la Base de données SQLite & Configuration initiale
|
||||||
echo -e "${C_GREEN}[5/8] Initialisation de la base SQLite et configuration NexusPBX...${C_RESET}"
|
echo -e "${C_GREEN}[5/8] Initialisation de la base SQLite et configuration NexusPBX...${C_RESET}"
|
||||||
@@ -318,13 +342,21 @@ $st = $db->query("SELECT admin_https_port, certbot_strict_port80 FROM settings W
|
|||||||
App\FirewallManager::applyNginxConfig((int)($st["admin_https_port"] ?? 8443), (int)($st["certbot_strict_port80"] ?? 0));
|
App\FirewallManager::applyNginxConfig((int)($st["admin_https_port"] ?? 8443), (int)($st["certbot_strict_port80"] ?? 0));
|
||||||
'
|
'
|
||||||
|
|
||||||
# Filtre Fail2ban Asterisk
|
# Filtre Fail2ban Asterisk & Nexus-Web
|
||||||
cat << 'EOF' > /etc/fail2ban/filter.d/asterisk.conf
|
cat << 'EOF' > /etc/fail2ban/filter.d/asterisk.conf
|
||||||
[Definition]
|
[Definition]
|
||||||
failregex = ^(%(__prefix_line)s|\[\]\s*)*(?:NOTICE|SECURITY)\[\d+\]:? (?:\S+: )?(?:Registration from |Call from |Invalid password for |Sending fake auth challenge to |No matching endpoint found for )?'?<HOST>(?::\d+)?'?
|
failregex = ^(%(__prefix_line)s|\[\]\s*)*(?:NOTICE|SECURITY)\[\d+\]:? (?:\S+: )?(?:Registration from |Call from |Invalid password for |Sending fake auth challenge to |No matching endpoint found for )?'?<HOST>(?::\d+)?'?
|
||||||
^(%(__prefix_line)s|\[\]\s*)*SECURITY\[\d+\]:? (?:\S+: )?SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword|AuthFailed)"(?:.*?)RemoteAddress="IPV[46]/(?:UDP|TCP|TLS)/<HOST>/\d+"
|
^(%(__prefix_line)s|\[\]\s*)*SECURITY\[\d+\]:? (?:\S+: )?SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword|AuthFailed)"(?:.*?)RemoteAddress="IPV[46]/(?:UDP|TCP|TLS)/<HOST>/\d+"
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
EOF
|
EOF
|
||||||
|
chmod 0644 /etc/fail2ban/filter.d/asterisk.conf
|
||||||
|
|
||||||
|
cat << 'EOF' > /etc/fail2ban/filter.d/nexus-web.conf
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*\[NEXUS-WEB-AUTH-FAIL\]:\s*<HOST>.*$
|
||||||
|
ignoreregex =
|
||||||
|
EOF
|
||||||
|
chmod 0644 /etc/fail2ban/filter.d/nexus-web.conf
|
||||||
|
|
||||||
# Jails Fail2ban
|
# Jails Fail2ban
|
||||||
cat << 'EOF' > /etc/fail2ban/jail.local
|
cat << 'EOF' > /etc/fail2ban/jail.local
|
||||||
@@ -350,8 +382,25 @@ port = http,https,8443
|
|||||||
logpath = /var/log/nginx/*error.log
|
logpath = /var/log/nginx/*error.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
bantime = 3600
|
bantime = 3600
|
||||||
|
|
||||||
|
[nexus-web]
|
||||||
|
enabled = true
|
||||||
|
port = http,https,8443
|
||||||
|
filter = nexus-web
|
||||||
|
logpath = /var/log/nexus_security.log
|
||||||
|
maxretry = 3
|
||||||
|
findtime = 600
|
||||||
|
bantime = 3600
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
chown root:asterisk /etc/fail2ban/jail.local
|
||||||
|
chmod 0664 /etc/fail2ban/jail.local
|
||||||
|
setfacl -m u:www-data:rw /etc/fail2ban/jail.local 2>/dev/null || true
|
||||||
|
|
||||||
|
chown root:asterisk /etc/nginx/sites-available/nexus-pbx
|
||||||
|
chmod 0664 /etc/nginx/sites-available/nexus-pbx
|
||||||
|
setfacl -m u:www-data:rw /etc/nginx/sites-available/nexus-pbx 2>/dev/null || true
|
||||||
|
|
||||||
# 8. Crontab & Bannière d'accueil Console (Style FreePBX)
|
# 8. Crontab & Bannière d'accueil Console (Style FreePBX)
|
||||||
echo -e "${C_GREEN}[7/8] Mise en place des tâches programmées et de la bannière console...${C_RESET}"
|
echo -e "${C_GREEN}[7/8] Mise en place des tâches programmées et de la bannière console...${C_RESET}"
|
||||||
|
|
||||||
@@ -381,14 +430,16 @@ chmod +x /etc/profile.d/nexus-motd.sh
|
|||||||
echo -e "${C_GREEN}[8/8] Démarrage et activation des services système...${C_RESET}"
|
echo -e "${C_GREEN}[8/8] Démarrage et activation des services système...${C_RESET}"
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
||||||
# Redémarrage PHP-FPM
|
# Redémarrage PHP-FPM (rechargement de l'appartenance au groupe asterisk)
|
||||||
|
systemctl restart php*-fpm 2>/dev/null || true
|
||||||
PHP_SVC=$(systemctl list-unit-files --type=service 2>/dev/null | grep -E "php.*-fpm" | awk '{print $1}' | head -n 1 || echo "php8.4-fpm")
|
PHP_SVC=$(systemctl list-unit-files --type=service 2>/dev/null | grep -E "php.*-fpm" | awk '{print $1}' | head -n 1 || echo "php8.4-fpm")
|
||||||
systemctl restart "$PHP_SVC" && systemctl enable "$PHP_SVC"
|
systemctl restart "$PHP_SVC" 2>/dev/null || true
|
||||||
|
systemctl enable "$PHP_SVC" 2>/dev/null || true
|
||||||
|
|
||||||
# Redémarrage Asterisk, Nginx, Fail2ban, Cron
|
# Redémarrage Asterisk, Nginx, Fail2ban, Cron
|
||||||
systemctl restart asterisk && systemctl enable asterisk
|
systemctl restart asterisk && systemctl enable asterisk
|
||||||
nginx -t && systemctl restart nginx && systemctl enable nginx
|
|
||||||
systemctl restart fail2ban && systemctl enable fail2ban
|
systemctl restart fail2ban && systemctl enable fail2ban
|
||||||
|
nginx -t && systemctl restart nginx && systemctl enable nginx
|
||||||
systemctl restart cron && systemctl enable cron
|
systemctl restart cron && systemctl enable cron
|
||||||
|
|
||||||
# Exécution immédiate de la bannière console
|
# Exécution immédiate de la bannière console
|
||||||
|
|||||||
+18
-1
@@ -1729,16 +1729,33 @@ class ConfigGenerator
|
|||||||
|
|
||||||
$tmpPath = $targetPath . '.tmp.' . getmypid();
|
$tmpPath = $targetPath . '.tmp.' . getmypid();
|
||||||
if (@file_put_contents($tmpPath, $content, LOCK_EX) === false) {
|
if (@file_put_contents($tmpPath, $content, LOCK_EX) === false) {
|
||||||
|
// Repli en écriture directe si le fichier existe déjà et est accessible
|
||||||
|
if (file_exists($targetPath) && is_writable($targetPath)) {
|
||||||
|
if (@file_put_contents($targetPath, $content, LOCK_EX) !== false) {
|
||||||
|
@chgrp($targetPath, 'asterisk');
|
||||||
|
@chmod($targetPath, 0664);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
throw new RuntimeException("Impossible d'écrire dans {$targetPath}. Vérifiez que www-data fait partie du groupe asterisk et que /etc/asterisk est accessible en écriture de groupe (chmod 2775).");
|
throw new RuntimeException("Impossible d'écrire dans {$targetPath}. Vérifiez que www-data fait partie du groupe asterisk et que /etc/asterisk est accessible en écriture de groupe (chmod 2775).");
|
||||||
}
|
}
|
||||||
|
|
||||||
@chgrp($tmpPath, 'asterisk');
|
@chgrp($tmpPath, 'asterisk');
|
||||||
@chmod($tmpPath, 0660);
|
@chmod($tmpPath, 0664);
|
||||||
|
|
||||||
if (!@rename($tmpPath, $targetPath)) {
|
if (!@rename($tmpPath, $targetPath)) {
|
||||||
@unlink($tmpPath);
|
@unlink($tmpPath);
|
||||||
|
// Repli en écriture directe si le renommage échoue
|
||||||
|
if (@file_put_contents($targetPath, $content, LOCK_EX) !== false) {
|
||||||
|
@chgrp($targetPath, 'asterisk');
|
||||||
|
@chmod($targetPath, 0664);
|
||||||
|
return;
|
||||||
|
}
|
||||||
throw new RuntimeException("Échec du remplacement atomique de {$targetPath}.");
|
throw new RuntimeException("Échec du remplacement atomique de {$targetPath}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@chgrp($targetPath, 'asterisk');
|
||||||
|
@chmod($targetPath, 0664);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function normalizeInboundRoutes(string $json): array
|
public static function normalizeInboundRoutes(string $json): array
|
||||||
|
|||||||
@@ -291,8 +291,6 @@ ignoreip = {$whitelist}
|
|||||||
findtime = {$sipFindTime}
|
findtime = {$sipFindTime}
|
||||||
bantime = {$sipBanTime}
|
bantime = {$sipBanTime}
|
||||||
maxretry = {$sipMaxRetry}
|
maxretry = {$sipMaxRetry}
|
||||||
banaction = nftables-multiport
|
|
||||||
banaction_allports = nftables-allports
|
|
||||||
|
|
||||||
[sshd]
|
[sshd]
|
||||||
enabled = true
|
enabled = true
|
||||||
@@ -306,7 +304,7 @@ bantime = 3600
|
|||||||
[asterisk]
|
[asterisk]
|
||||||
enabled = true
|
enabled = true
|
||||||
filter = asterisk
|
filter = asterisk
|
||||||
logpath = /var/log/asterisk/security.log
|
logpath = /var/log/asterisk/messages
|
||||||
maxretry = {$sipMaxRetry}
|
maxretry = {$sipMaxRetry}
|
||||||
findtime = {$sipFindTime}
|
findtime = {$sipFindTime}
|
||||||
bantime = {$sipBanTime}
|
bantime = {$sipBanTime}
|
||||||
@@ -326,6 +324,8 @@ protocol = tcp
|
|||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
file_put_contents(self::JAIL_LOCAL_PATH, $conf);
|
file_put_contents(self::JAIL_LOCAL_PATH, $conf);
|
||||||
|
@chgrp(self::JAIL_LOCAL_PATH, 'asterisk');
|
||||||
|
@chmod(self::JAIL_LOCAL_PATH, 0664);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -477,6 +477,8 @@ EOF;
|
|||||||
|
|
||||||
$fullNginxConfig = $port80Block . "\n\n" . $phonebookBlock . "\n\n" . $httpsBlock . "\n";
|
$fullNginxConfig = $port80Block . "\n\n" . $phonebookBlock . "\n\n" . $httpsBlock . "\n";
|
||||||
file_put_contents(self::NGINX_CONF_PATH, $fullNginxConfig);
|
file_put_contents(self::NGINX_CONF_PATH, $fullNginxConfig);
|
||||||
|
@chgrp(self::NGINX_CONF_PATH, 'asterisk');
|
||||||
|
@chmod(self::NGINX_CONF_PATH, 0664);
|
||||||
|
|
||||||
// Test de syntaxe
|
// Test de syntaxe
|
||||||
exec('sudo /usr/sbin/nginx -t 2>&1', $tOut, $tCode);
|
exec('sudo /usr/sbin/nginx -t 2>&1', $tOut, $tCode);
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ namespace App;
|
|||||||
use PDO;
|
use PDO;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/ConfigGenerator.php';
|
||||||
|
require_once __DIR__ . '/AmiClient.php';
|
||||||
|
|
||||||
class SystemChecker
|
class SystemChecker
|
||||||
{
|
{
|
||||||
public static function runDiagnostics(PDO $db): array
|
public static function runDiagnostics(PDO $db): array
|
||||||
|
|||||||
Reference in new issue
Block a user