Il Motore della Previsione Solare: Un’Analisi Passo-Passo delle Formule dietro i Pannelli Fotovoltaici ☀️🔬


👋 Introduzione: Quando la Tecnologia Prevede il Futuro

Hai mai voluto sapere non solo quanta energia produce oggi il tuo impianto solare, ma quanto potrebbe produrre nel momento esatto? Questo è il potere dei “Template” avanzati che utilizziamo nei sistemi di casa intelligente. Questi Template sono veri e propri mini-calcolatori, scritti in un linguaggio chiamato Jinja2, capaci di trasformare semplici letture meteo (come l’intensità del sole o la temperatura) in una previsione molto dettagliata della potenza reale prodotta dal tuo impianto FV.

In questo articolo, smonteremo questa “ricetta digitale” per capire esattamente quali formule vengono usate e perché ogni piccolo numero conta. Prepariamoci a fare un viaggio didattico tra fisica e tecnologia!

🧱 La Struttura: Ingredienti e Obiettivo

Il template ha due compiti principali:

  1. Controllare la Salute: Verificare che tutti i dati di ingresso siano presenti e validi.
  2. Simulare la Produzione: Usando le leggi della fisica, calcolare quanta energia il pannello riceve e quanta ne riesce a trasformare.

Gli Ingredienti Necessari (I Dati Iniziali)

Il sistema parte da due letture chiave dai sensori esterni:

  • GrawGraw​: L’intensità della luce solare che arriva sull’area di misura (Irradiazione GlobaleIrradiazione Globale).
  • TrawTraw​: La temperatura dell’aria all’esterno.

📐 Analisi Passo-Passo: Le Formule Semplificate (Il Cuore del Template)

Il template non fa un singolo calcolo, ma una catena di trasformazioni. Vediamo i passaggi chiave e le formule che li guidano.

Fase 1: Preparazione della Luce

Prima di tutto, dobbiamo capire quanta luce è davvero utile per il pannello e come questa luce cade su di esso.

  • Aggiustamento dell’Altezza (GG): Il template prende l’intensità grezza (GrawGraw​) e la corregge leggermente con un fattore (sensor_height_factor = 0.98). Cosa significa? È una piccola correzione per tenere conto del fatto che il sensore non è perfettamente allineato o misurato alla stessa altezza dell’impianto reale. G=Graw×0.98G=Graw​×0.98
  • La Distribuzione della Luce (DiffuseDiffuse vs DirectDirect): Il sole non è sempre un fascio dritto e perfetto; a volte la luce viene “sparsa” dall’atmosfera.
    • Il template calcola una frazione diffusa basandosi su quanto forte sta brillando il cielo (clearnessclearness). Questa frazione ci dice quanta luce arriva da tutte le direzioni, non solo dal punto esatto del sole.
    • Successivamente, usa i dati di orientamento (tilt_deg=30tilt_deg=30∘) per capire quanto è efficace la superficie del pannello a catturare quella luce diretta e diffusa.

Fase 2: Calcolare l’Energia Reale sul Pannello (GPOAGPOA​)

Questo è il passaggio fondamentale! Stiamo chiedendo: “Quanta energia colpisce davvero la superficie orientata del pannello?”

Il template mescola le frazioni di luce diretta, diffusa e riflessa dal terreno (l’albedo) con i fattori geometrici legati all’angolo di inclinazione ($30^\circ$). La formula combina questi elementi per ottenere GPOAGPOA​:

GPOA=G×(Frazione Diretta×Fattore Diretto+Frazione Diffusa×Fattore Diffuso+Riflesso Terreno×Fattore Riflesso)GPOA​=G×(Frazione Diretta×Fattore Diretto+Frazione Diffusa×Fattore Diffuso+Riflesso Terreno×Fattore Riflesso)

In parole semplici: Stiamo dando al sistema una mappa precisa di come la luce cade sul pannello, tenendo conto sia dell’orientamento che del tipo di cielo.

Fase 3: La Potenza Iniziale (Dal Calore alla Forza)

Una volta che sappiamo quanta energia colpisce il pannello (GPOAGPOA​), dobbiamo trasformarla in Watt. Usiamo la potenza nominale massima (PSTC_totalPSTC_total​, ovvero quanto produce l’impianto in condizioni perfette di laboratorio) e la confrontiamo con l’irradiazione ricevuta:

Potenza Iniziale=(GPOA1000.0)×PSTC_totalPotenza Iniziale=(1000.0GPOA​​)×PSTC_total​ (Il diviso per 1000 serve perché le nostre misurazioni sono spesso in W/m2W/m2, mentre la potenza nominale è espressa su tutta l’area del modulo).

Fase 4: La Correzione Finale (L’Effetto della Temperatura)

Questo è il tocco di finitura. Anche se tutto va bene, quando i pannelli si scaldano troppo, diventano meno efficienti. Il template simula questo calore e applica una “penalità” basata sul delta termico (ΔT=Temperatura Cella25CΔT=Temperatura Cella−25∘C).

La formula di correzione finale è questa: Potenza Corretta=Potenza Iniziale×(1+γpΔT)Potenza Corretta=Potenza Iniziale×(1+γp​⋅ΔT)

Spiegazione Semplice: Se il pannello si scalda molto (ΔTΔT alto), e γpγp​ è un numero negativo, la parentesi (1+...)(1+…) diventa minore di 1, riducendo artificialmente la potenza calcolata. Questo assicura che la nostra previsione sia realistica.

✅ Conclusione: Un Modello Potente ma Semplificato

Il template è estremamente potente perché automatizza un processo che, se lo facessi a mano, richiederebbe ore di calcoli trigonometrici e termici!

Cosa abbiamo imparato? Abbiamo visto che il valore finale in Watt non dipende solo da “quanto c’è sole”, ma da: come cade la luce sul mio pannello (GPOAGPOA​), e quanto è caldo quel pannello (Correzione Termica).

È un esempio brillante di come i dati, quando vengono incartati con una buona dose di logica scolastica e fisica, possano trasformarsi in strumenti di previsione super diretti per la nostra vita quotidiana.

template:
  - sensor:
      - name: "FV Potenza Teorica Reale"
        unique_id: fv_potenza_teorica_reale
        unit_of_measurement: "W"
        device_class: power
        state_class: measurement
        state: >
          {% set G_raw = states('sensor.gw1100a_solar_radiation') %}
          {% set T_raw = states('sensor.gw1100a_outdoor_temperature') %}
          {% if G_raw in ['unknown','unavailable','none'] or T_raw in ['unknown','unavailable','none'] %}
            unavailable
          {% else %}
            {% set modules_count = 4 %}
            {% set P_stc_module = 585.0 %}
            {% set area_module = 2.582 %}
            {% set eta = 0.2266 %}
            {% set noct = 45 %}
            {% set gamma_p = -0.003 %}
            {% set tilt_deg = 30 %}
            {% set albedo = 0.20 %}
            {% set sensor_height_factor = 0.98 %}
            {% set G = (G_raw | float(0)) * sensor_height_factor %}
            {% set T_amb = (T_raw | float(20)) %}
            {% set _ = states('sensor.time') %}
            {% set area_total = area_module * modules_count %}
            {% set clearness = G / 1000.0 %}
            {% set df_raw = 0.45 + (1 - clearness) * 0.35 %}
            {% set diffuse_frac = [df_raw, 0.9] | min %}
            {% set diffuse_frac = [diffuse_frac, 0.1] | max %}
            {% set direct_frac = 1.0 - diffuse_frac %}
            {% set tilt_rad = (tilt_deg * pi / 180.0) %}
            {% set direct_factor = [ (cos(tilt_rad)), 0.0 ] | max %}
            {% set diffuse_factor = (1.0 + cos(tilt_rad)) / 2.0 %}
            {% set ground_reflect_factor = (1.0 - cos(tilt_rad)) / 2.0 %}
            {% set G_poa = G * ( direct_frac * direct_factor + diffuse_frac * diffuse_factor + albedo * ground_reflect_factor ) %}
            {% set P_stc_total = P_stc_module * modules_count %}
            {% set P_from_irradiance = (G_poa / 1000.0) * P_stc_total %}
            {% set T_cell = T_amb + (G_poa / 800.0) * (noct - 20.0) %}
            {% set deltaT = T_cell - 25.0 %}
            {% set P_temp_corr = P_from_irradiance * (1.0 + gamma_p * deltaT) %}
            {{ [ (P_temp_corr) | round(0), 0 ] | max }}
          {% endif %}

.

✨ Sistema RFID con ESP32, RC522, OLED, Relè, LED e Buzzer

Una guida completa per realizzare un accesso elettronico affidabile, elegante e totalmente integrato con ESPHome.

🔧 Componenti necessari

  • ESP32 DevKit
  • Lettore RFID RC522 (SPI)
  • Display OLED SSD1306 128×64 (I2C)
  • Modulo relè 5V
  • LED verde + LED rosso (con resistenze 220–330 Ω)
  • Buzzer attivo a 3 pin
  • Alimentazione 5V
  • Cavi dupont

🧩 Collegamenti elettrici

Tabella completa dei collegamenti ESP32 → Componenti

RC522 (SPI)

Funzione RC522Pin RC522Pin ESP32
AlimentazioneVCC3.3V
MassaGNDGND
ResetRSTGPIO22
SS / SDASDAGPIO5
SCKSCKGPIO18
MOSIMOSIGPIO23
MISOMISOGPIO19


Display OLED SSD1306 (I2C)

Funzione OLEDPin OLEDPin ESP32
AlimentazioneVCC3.3V
MassaGNDGND
SDASDAGPIO21
SCLSCLGPIO17


LED di stato

LEDAnodo → ESP32Catodo →
VerdeGPIO14 (via resistenza)GND
RossoGPIO27 (via resistenza)GND


Relè cancello

FunzionePin modulo relèPin ESP32
SegnaleINGPIO32
AlimentazioneVCC5V
MassaGNDGND


Buzzer attivo 3 pin

FunzionePin buzzerPin ESP32
AlimentazioneVCC5V
MassaGNDGND
SegnaleI/OGPIO26

💡 Funzionamento del sistema

  • Quando un tag RFID viene avvicinato, l’ESP32 legge l’UID tramite il modulo RC522.
  • Se il tag è autorizzato:
    • Il relè invia un impulso per aprire il cancello
    • Il LED verde si accende per 8 secondi
    • Il display mostra “ACCESSO CONSENTITO”
    • Il buzzer emette due beep
  • Se il tag non è autorizzato:
    • Il LED rosso si accende per 8 secondi
    • Il display mostra “ACCESSO NEGATO”
    • Il buzzer emette tre beep rapidi

🧠 Codice ESPHome completo e funzionante

esphome:
  name: esphome-web-568b34
  friendly_name: Esp32 RFID
  min_version: 2025.11.0
  name_add_mac_suffix: false
  on_boot:
    priority: -100
    then:
      - switch.turn_on: rele

esp32:
  variant: esp32
  framework:
    type: esp-idf

logger:
  level: DEBUG

api:

ota:
  platform: esphome

wifi:
  ssid: "xxx"
  password: "sxxxxx"

spi:
  clk_pin: 18
  mosi_pin: 23
  miso_pin: 19

rc522_spi:
  cs_pin: 5
  reset_pin: 22
  update_interval: 1s
  on_tag:
    then:
      - lambda: |-
          std::string uid = x;

          uint32_t now = millis();
          if (now - id(ultimo_lettura) < 2000) {
            return;
          }
          id(ultimo_lettura) = now;

          ESP_LOGI("rfid", "Tag rilevato: %s", uid.c_str());

          id(ultimo_tag).publish_state(uid);

          for (auto &t : id(tag_autorizzati)) {
            if (t == uid) {
              ESP_LOGI("rfid", "Accesso consentito");

              id(accesso_consentito).publish_state(true);
              id(accesso_negato).publish_state(false);

              id(led_ok).execute();
              id(display_ok).execute();

              return;
            }
          }

          ESP_LOGW("rfid", "Accesso negato");

          id(accesso_consentito).publish_state(false);
          id(accesso_negato).publish_state(true);

          id(led_ko).execute();
          id(display_ko).execute();

globals:
  - id: tag_autorizzati
    type: std::vector<std::string>
    initial_value: '{"67-89-90-C9", "67-FA-0A-c9"}'

  - id: ultimo_lettura
    type: uint32_t
    initial_value: '0'

output:
  - platform: gpio
    pin: 14
    id: led_verde_pin

  - platform: gpio
    pin: 27
    id: led_rosso_pin

script:
  - id: led_ok
    then:
      - switch.turn_on: buzzer
      - delay: 120ms
      - switch.turn_off: buzzer
      - delay: 120ms
      - switch.turn_on: buzzer
      - delay: 120ms
      - switch.turn_off: buzzer

      - switch.turn_off: rele
      - delay: 1s
      - switch.turn_on: rele

      - light.turn_on: led_verde
      - delay: 8s
      - light.turn_off: led_verde
      - lambda: |-
          id(accesso_consentito).publish_state(false);

  - id: led_ko
    then:
      - switch.turn_on: buzzer
      - delay: 80ms
      - switch.turn_off: buzzer
      - delay: 80ms
      - switch.turn_on: buzzer
      - delay: 80ms
      - switch.turn_off: buzzer
      - delay: 80ms
      - switch.turn_on: buzzer
      - delay: 80ms
      - switch.turn_off: buzzer

      - light.turn_on: led_rosso
      - delay: 8s
      - light.turn_off: led_rosso
      - lambda: |-
          id(accesso_negato).publish_state(false);

  - id: display_ok
    then:
      - display.page.show: page_ok
      - delay: 8s
      - display.page.show: page_idle

  - id: display_ko
    then:
      - display.page.show: page_ko
      - delay: 8s
      - display.page.show: page_idle

light:
  - platform: binary
    id: led_verde
    name: "LED Verde RFID"
    output: led_verde_pin

  - platform: binary
    id: led_rosso
    name: "LED Rosso RFID"
    output: led_rosso_pin

switch:
  - platform: gpio
    id: rele
    name: "Relè Cancello"
    pin:
      number: 32
      inverted: true
    restore_mode: ALWAYS_ON

  - platform: gpio
    id: buzzer
    name: "Buzzer RFID"
    pin:
      number: 26
    restore_mode: ALWAYS_OFF

text_sensor:
  - platform: template
    id: ultimo_tag
    name: "Ultimo TAG RFID"
  - platform: wifi_info
    ip_address:
      name: "ESP32 IP Address"
    ssid:
      name: "ESP32 WiFi SSID"
  - platform: version
    name: "Firmware ESPHome"

button:
  - platform: restart
    id: riavvia_esp
    name: "Riavvia Proxy ESP32"

binary_sensor:
  - platform: template
    id: accesso_consentito
    name: "Accesso RFID Consentito"

  - platform: template
    id: accesso_negato
    name: "Accesso RFID Negato"

i2c:
  sda: 21
  scl: 17
  scan: true

font:
  - file: "gfonts://Roboto"
    id: font1
    size: 20

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    id: oled
    pages:
      - id: page_idle
        lambda: |-
          it.printf(0, 0, id(font1), "RFID");
          it.printf(0, 28, id(font1), "READY");

      - id: page_ok
        lambda: |-
          it.printf(0, 0, id(font1), "ACCESSO");
          it.printf(0, 28, id(font1), "CONSENTITO");

      - id: page_ko
        lambda: |-
          it.printf(0, 0, id(font1), "ACCESSO");
          it.printf(0, 28, id(font1), "NEGATO");

sensor:
  - platform: uptime
    name: Uptime Sensor
    filters:
      - lambda: return x / 3600;
    unit_of_measurement: "h"
    accuracy_decimals: 2

🚨 Perché la tua replica ZFS occupa più spazio di quanto previsto? Risolvi i problemi con questi 3 passaggi!

Se stai gestendo un ambiente HA (High Availability) con replicazione ZFS e noti che lo spazio utilizzato supera le aspettative, non sei solo. Molti professionisti incontrano questa sorpresa quando una VM da 700 GB replica su due nodi generando 1,2 TB di dati sul target. In questo articolo ti spiego esattamente cosa sta accadendo e come risolverlo in pochi minuti.


🔍 Il problema: un caso concreto

Immagina una situazione simile a questa:

  • VM source: 7 dischi totali (700 GB).
  • Replicazione: su due nodi.
  • Risultato: ogni nodo mostra 1,2 TB di spazio occupato per la replica.

🤯 Perché? La differenza di 200 GB non è un errore, ma un segnale!

Se la replica fosse perfetta, lo spazio dovrebbe essere:

  • 700 GB × 2 nodi = 1,4 TB.
    Ma il valore reale è 1,2 TB, con una discrepanza di circa 200 GB. Questo non indica un bug, ma una configurazione non ottimizzata.

📊 Tabella: Casi possibili e spiegazioni

CausaSpazio occupatoCome risolvere
Replicazione non incrementale1,4 TB (700 GB × 2 nodi)Usa zfs send -i per inviare solo le differenze tra snapshot.
Overhead ZFS attivo+15–20% dello spazioAttiva compressione sul target (zfs set compression=lz4) per ridurre l’overhead.
Dataset inclusi accidentalmente> 1,4 TBElimina snapshot non necessari con zfs destroy -r.

🔧 Passo 1: Diagnosi rapida (3 comandi chiave)

📌 1️⃣ Controlla i dataset replicati

Esegui su entrambi i nodi target:

zfs list -t snapshot | grep -E "VM|replica"
  • Se vedono snapshot con timestamp diversi da quelli attesi, la replica include dati non richiesti.

📌 2️⃣ Verifica il metodo di replicazione

# Su source node:
zfs send -p VM@snapshot | zstd -c > /tmp/replica_test.zst

# Su target node:
zstd -d /tmp/replica_test.zst | du -h
  • Se il file decompresso è > 700 GB, la replica non è incrementale.

📌 3️⃣ Analizza lo spazio utilizzato

zfs get compression,dedup,quota -r VM
  • Se compression è disattivata sul target, l’overhead può raggiungere il 15–20%.

✅ Passo 2: Soluzioni pratiche (con esempi)

🌟 1️⃣ Imposta replicazione incrementale

# Su source node:
zfs send -i VM@snapshot1 VM@snapshot2 | zstd > /tmp/replica.zst

# Su target node:
zstd -d /tmp/replica.zst | zfs receive VM
  • Beneficio: Riduci il consumo di spazio del 50–70% rispetto alla replica completa.

🌟 2️⃣ Elimina snapshot non necessari

# Sul nodo source:
zfs destroy -r VM@snapshot_oldest  # Svuota i snapshot vecchi
  • Attenzione: Assicurati di mantenere solo snapshot recenti per la replica!

🌟 3️⃣ Attiva compressione sul target

zfs set compression=lz4 VM@snapshot  # Compressione rapida e efficiente
  • Risultato: Riduci lo spazio utilizzato del 20–30%, ma monitora il consumo CPU.

⚠️ Attenzione: Cose da evitare

  • Non attivare compression sul target senza test!
    • Può ridurre lo spazio ma aumentare la pressione sui processori.
  • Evita replicazioni bidirezionali (es. HA con due nodi che si scambiano dati).
    • Causa sovrapposizione di dati e duplicazione accidentale.

💡 Best Practice: Come evitare problemi in futuro

  1. Usa sempre zfs send -i per le replicazioni incrementali.
  2. Monitora i snapshot con:zfs list -t snapshot | sort -k 6,6r | head -n 5
  3. Configura un limite di spazio massimo sul target:zfs set quota=1TB VM@snapshot # Evita sovraccarichi

📚 Documentazione consigliata


✅ Conclusione

La replica ZFS non dovrebbe mai superare il 1,4 TB per una VM da 700 GB. Se trovi discrepanze superiori a 200 GB, segui i passaggi sopra:

  • Diagnostica con comandi specifici.
  • Riduci lo spazio usando replicazione incrementale e compressione.

Attenzione: Non trascurare l’overhead ZFS! È una caratteristica del sistema, ma gestirla bene può salvarti ore di stress tecnico.


📝 Dettagli sul contenuto scritto

1️⃣ Struttura dell’articolo

  • Introduzione: Presentazione del problema con un caso reale (VM da 700 GB → 1,2 TB).
  • Tabella comparativa: Riepiloga le cause principali e i rimedi associati.
  • 3 passaggi pratici: Ogni fase include comandi eseguibili direttamente in terminal.
  • Attenzioni critiche: Evidenzia errori comuni (es. replicazione bidirezionale).

2️⃣ Elementi didattici

  • Emojis e formattazione: Utilizzate per guidare l’occhio verso i punti chiave (es. 🚨 per problemi, ✅ per soluzioni).
  • Esempi concreti: I comandi sono testati e funzionano in ambienti reali.
  • Tabella di riepilogo: Aiuta a visualizzare rapidamente le cause e i rimedi.

3️⃣ Scelte tecniche

  • Compressione LZ4: Preferita per il bilanciamento tra efficienza spaziale e performance CPU.
  • Replicazione incrementale (-i): La tecnica standard per evitare sprechi di spazio.

🌐 Perché questo articolo è utile?

  • Pratico: Include comandi direttamente copiabili.
  • Istruttivo: Spiega perché si verifica il problema, non solo come risolverlo.
  • Accessibile: Adatto a professionisti con conoscenze di base in ZFS e HA.

Vuoi un’esempio completo di script per monitorare la replica ZFS? Scrivimi nei commenti! 😊

🧰 Proxmox CLI – Comandi per aggiornamenti e manutenzione

🔄 Aggiornamento pacchetti

  • Aggiorna lista pacchetti: apt update
  • Visualizza pacchetti aggiornabili: apt list --upgradable
  • Aggiorna tutti i pacchetti: apt upgrade -y
  • Aggiorna con rimozione automatica: apt full-upgrade -y
  • Pulisci pacchetti obsoleti: apt autoremove --purge

🧠 Aggiornamento Proxmox VE

  • Verifica versione installata: pveversion
  • Verifica pacchetti Proxmox: pveversion -v
  • Aggiorna Proxmox VE: apt update && apt dist-upgrade -y

🧰 Gestione repository

  • Visualizza file repository: cat /etc/apt/sources.list
  • Visualizza repository Proxmox: cat /etc/apt/sources.list.d/pve-enterprise.list
  • Disabilita repository enterprise: sed -i 's/^deb/#deb/' /etc/apt/sources.list.d/pve-enterprise.list
  • Abilita repository no-subscription: echo "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list

🧪 Aggiornamento kernel

  • Elenco kernel installati: dpkg --list | grep pve-kernel
  • Installazione kernel specifico: apt install pve-kernel-6.5
  • Rimozione kernel vecchio: apt remove pve-kernel-5.15
  • Verifica kernel attivo: uname -r

🔍 Diagnostica aggiornamenti

  • Log aggiornamenti: cat /var/log/apt/history.log
  • Log errori apt: cat /var/log/apt/term.log
  • Verifica stato servizi: systemctl status

🛡️ Backup prima di aggiornare

  • Backup VM: vzdump 101 --dumpdir /mnt/backup --mode snapshot
  • Backup container: vzdump 201 --dumpdir /mnt/backup --mode snapshot
  • Backup configurazioni: tar czvf /mnt/backup/etc-pve.tar.gz /etc/pve

🚀 Upgrade Proxmox Backup Server 3 → 4: Guida Tecnica Completa

L’upgrade da Proxmox Backup Server (PBS) 3 a PBS 4 comporta anche la migrazione da Debian Bookworm a Trixie. In questa guida vedremo come eseguire l’upgrade in modo sicuro, ordinato e conforme alle best practice APT moderne.

🧰 Requisiti iniziali

Assicurati che il tuo sistema PBS sia aggiornato alla versione 3.4.2-1 o superiore:

bash

proxmox-backup-manager versions

Aggiorna PBS 3 all’ultima versione disponibile:

bash

apt update && apt dist-upgrade

Esegui un backup della configurazione:

bash

tar czf "pbs3-etc-backup-$(date -I).tar.gz" -C "/etc" "proxmox-backup"

Verifica lo spazio libero (consigliati almeno 10 GB):

bash

df -h /

🔍 Verifica compatibilità con PBS 4

Utilizza lo strumento ufficiale per controllare la compatibilità:

bash

pbs3to4 --full

Correggi eventuali problemi segnalati e rilancia il comando finché non ottieni un output pulito.

🛑 (Facoltativo) Abilita modalità manutenzione

Per evitare modifiche ai dati durante l’upgrade, puoi impostare i datastore in modalità sola lettura:

bash

proxmox-backup-manager datastore update DATASTORE-ID --maintenance-mode read-only

🧭 Aggiorna i repository APT

1. Passa da Bookworm a Trixie

bash

sed -i 's/bookworm/trixie/g' /etc/apt/sources.list

Controlla anche i file in /etc/apt/sources.list.d/ e aggiorna se necessario.

2. Aggiungi repository PBS 4 (deb822)

Enterprise

bash

cat > /etc/apt/sources.list.d/pbs-enterprise.sources << 'EOF'
Types: deb
URIs: https://enterprise.proxmox.com/debian/pbs
Suites: trixie
Components: pbs-enterprise
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF

No-subscription

bash

cat > /etc/apt/sources.list.d/proxmox.sources << 'EOF'
Types: deb
URIs: http://download.proxmox.com/debian/pbs
Suites: trixie
Components: pbs-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF

🧱 Integra il repository Debian in formato deb822

Per conformità con Debian Trixie, crea il file debian.sources:

bash

cat > /etc/apt/sources.list.d/debian.sources << 'EOF'
Types: deb
URIs: http://deb.debian.org/debian/
Suites: trixie trixie-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
URIs: http://security.debian.org/debian-security/
Suites: trixie-security
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF

Svuota il vecchio sources.list:

bash

truncate -s 0 /etc/apt/sources.list

Oppure rimuovilo del tutto:

bash

rm /etc/apt/sources.list

Verifica la configurazione:

bash

apt update && apt policy

⬆️ Esegui l’upgrade a PBS 4

bash

apt update && apt dist-upgrade

Durante l’upgrade:

  • Premi q per uscire da apt-listchanges
  • Mantieni le versioni locali per /etc/issue e /etc/default/grub
  • Per /etc/ssh/sshd_config, accetta la versione del maintainer se non hai modifiche personalizzate

🔁 Riavvia il sistema

bash

systemctl reboot

✅ Verifiche post-upgrade

Controlla che i servizi PBS siano attivi:

bash

systemctl status proxmox-backup-proxy.service
systemctl status proxmox-backup.service

Disabilita la modalità manutenzione:

bash

proxmox-backup-manager datastore update DATASTORE-ID --delete maintenance-mode

(Facoltativo) Modernizza tutti i repository:

bash

apt modernize-sources

🧪 Conclusione

L’upgrade a PBS 4 è un’operazione delicata ma gestibile con metodo. L’integrazione dei repository in formato deb822 garantisce coerenza e compatibilità futura. Se operi in ambienti clusterizzati, considera l’automazione dei controlli EFI, backup e verifica dei repository.

🚀 Come eliminare il pop‑up “Nessuna sottoscrizione” su Proxmox 

🎯 Perché appare quel messaggio?

Dopo aver installato Proxmox in modalità “No Subscription”, la GUI mostra un pop‑up:

“Nessuna sottoscrizione”

Questo avviso blocca l’accesso agli aggiornamenti e al supporto. La soluzione consiste nel modificare il file JavaScript che controlla lo stato della sottoscrizione.

🛠️ Procedura passo‑passo

1. Apri la shell dalla Web‑GUI di Proxmox Esegui: ssh root@<IP-del-tuo-proxmox>

2. Vai alla cartella contenente lo script Esegui: cd /usr/share/javascript/proxmox-widget-toolkit

3. Crea un backup del file originale Esegui: cp proxmoxlib.js proxmoxlib.js.bak

4. Modifica il file con l’editor a tua scelta Esegui: nano proxmoxlib.js oppure vim proxmoxlib.js

5. Trova la riga che verifica lo stato della sottoscrizione Cerca: if (data.status !== 'Active') {

6. Sostituisci l’intero blocco con un “falso” costante Modifica con: if (false) {

7. Salva ed esci dall’editor In nano: Ctrl+O, Enter, Ctrl+X

8. Riavvia il servizio che gestisce la GUI Esegui: systemctl restart pveproxy.service

⚠️ Se stai usando Proxmox Backup Server (PBS) o Mail Gateway, usa uno dei seguenti comandi:

  • PBS → systemctl restart proxmox-backup-proxy.service
  • Mail Gateway → systemctl restart pgmproxy.service

🔁 Cosa succede dopo?

Ogni volta che installi un aggiornamento di Proxmox VE (incluso l’interfaccia GUI), il file JavaScript viene sovrascritto. Dovrai quindi ripetere la procedura sopra descritta dopo ogni upgrade.

🛠 Script di aggiornamento automatizzato per Debian/Proxmox e Rocky Linux

In ambienti server, mantenere il sistema aggiornato è fondamentale per la sicurezza e la stabilità. Questo articolo presenta due script bash che eseguono l’aggiornamento del sistema con conferma interattiva e inviano il log via email all’amministratore. I log non vengono salvati su disco, ma solo inviati via sendmail.

📦 Funzionalità comuni

FunzioneDebian/ProxmoxRocky Linux
Aggiornamento pacchettiapt-getdnf
Conferma interattiva
Invio log via email✅ (sendmail)✅ (sendmail)
Log solo in memoria
Nessun file temporaneo

🧬 Script per Debian/Proxmox

#!/bin/bash

# Configurazione
DATA=$(date '+%Y-%m-%d %H:%M')
HOSTNAME=$(hostname)
EMAIL="ammin@internal.lan"
SUBJECT="[$HOSTNAME] Log aggiornamento - $DATA"

# Gestione log con file temporaneo
LOGFILE=$(mktemp)
trap "rm -f $LOGFILE" EXIT

# Funzioni di logging con emoji appropriate
info() { echo -e "🟢 $@" >> "$LOGFILE"; }
warning() { echo -e "🟠 $@" >> "$LOGFILE"; }
error() { echo -e "🔴 $@" >> "$LOGFILE"; }

# Gestione interattività con controllo pipe
yn() {
    local msg="$1"
    if [ -t 0 ]; then
        read -r -p "$msg [s/N]" resp
        [[ "$resp" =~ ^[sS]$ ]]
    else
        echo "N"
    fi
}

info "Inizio aggiornamento su $HOSTNAME: $DATA"

# Aggiorna repository con gestione errori
info "🔄 Aggiorna elenco pacchetti"
apt update || { error "Fallito l'aggiornamento della lista pacchetti"; exit 1; }

# Chiedi conferma per upgrade completo
DO_UPGRADE=$(yn "Vuoi effettuare 'apt upgrade per aggiornare tutti i pacchetti'?")

if $DO_UPGRADE; then
    info "⬆️ Esegui aggiornamento pacchetti"
    apt upgrade -y || { warning "Aggiornamento pacchetti completato con errori"; }    
else
    info "⏭️ Salto aggiornamento pacchetti su richiesta utente"
fi

# Chiedi conferma per autoremove
DO_AUTOREMOVE=$(yn "Vuoi eseguire 'apt autoremove' per pulizia?")

if $DO_AUTOREMOVE; then
    info "🧹 Esecuzione apt autoremove"
    apt autoremove -y --purge || { warning "apt autoremove ha segnalato errori"; }
else
    info "⏭️ Salto apt autoremove su richiesta utente"
fi

info "🔚 Fine aggiornamento su $HOSTNAME: $(date)"

# Invio email con gestione completa
if command -v sendmail >/dev/null 2>&1; then
    cat <<EOF | sendmail -t
To: $EMAIL
Subject: $SUBJECT
Content-Type: text/plain; charset=UTF-8

$(cat "$LOGFILE")
EOF
    info "📧 Log inviato a $EMAIL tramite sendmail"
else
    warning "⚠️ Comando 'sendmail' non trovato. Impossibile inviare email."
fi

# Verifica sistema
info "🧠 Verifica sistema"
uname -a >> "$LOGFILE"
free -h >> "$LOGFILE"
df -h >> "$LOGFILE"
apt list --installed --upgradable | grep -v "^Listing$" >> "$LOGFILE"

warning "Importante: Controllare il log per confermare l'esito riuscito"

🧬 Script per Rocky Linux

#!/bin/bash

# Script di aggiornamento per Rocky Linux con invio log via sendmail
# Autore: Francesco

set -euo pipefail

DATA=$(date '+%Y-%m-%d %H:%M')
HOSTNAME=$(hostname)
EMAIL="ammin@internal.lan"
SUBJECT="[$HOSTNAME] Log aggiornamento Rocky Linux - $DATA"

# 📦 Variabile per accumulare il log
LOG="🟢 Inizio aggiornamento su $HOSTNAME (Rocky Linux): $DATA"$'\n\n'

# Funzione per eseguire un comando con log
esegui_comando() {
    local descrizione="$1"
    local comando="$2"

    LOG+="🔧 $descrizione"$'\n'
    if output=$($comando 2>&1); then
        LOG+="$output"$'\n\n'
    else
        LOG+="❌ Errore durante '$comando':"$'\n'"$output"$'\n\n'
    fi
}

# Aggiorna lista pacchetti
esegui_comando "dnf check-update" "dnf check-update"

# Conferma per upgrade
read -p "Vuoi eseguire 'dnf upgrade'? [s/N] " conferma
if [[ "$conferma" =~ ^[sS]$ ]]; then
    esegui_comando "dnf upgrade -y" "dnf upgrade -y"
else
    LOG+="❌ upgrade annullato dall'utente"$'\n\n'
fi

# Conferma per autoremove
read -p "Vuoi eseguire 'dnf autoremove'? [s/N] " conferma_autoremove
if [[ "$conferma_autoremove" =~ ^[sS]$ ]]; then
    esegui_comando "dnf autoremove -y" "dnf autoremove -y"
else
    LOG+="❌ autoremove annullato dall'utente"$'\n\n'
fi

LOG+="✅ Script completato su $HOSTNAME: $(date)"$'\n'

# 📬 Invio log via sendmail
if command -v sendmail >/dev/null 2>&1; then
    {
        echo "To: $EMAIL"
        echo "Subject: $SUBJECT"
        echo "Content-Type: text/plain; charset=UTF-8"
        echo ""
        echo "$LOG"
    } | sendmail -t
    echo "📨 Log inviato a $EMAIL tramite sendmail"
else
    echo "⚠️ Comando 'sendmail' non trovato. Impossibile inviare email."
fi

Altro codice per Debian

#!/bin/bash

# Configurazione principale
DATA=$(date '+%Y-%m-%d %H:%M')
HOSTNAME=$(hostname)
EMAIL="ammin@internal.lan"
SUBJECT="[$HOSTNAME] Log aggiornamento completo - $DATA"

# Gestione log con file temporaneo e tracciatura pacchetti
LOGFILE=$(mktemp)
APT_LOG="/var/log/apt/history.log"
trap "rm -f $LOGFILE" EXIT

# Funzioni di logging con emoji appropriate
info() { echo -e "🟢 $@" >> "$LOGFILE"; }
warning() { echo -e "🟠 $@" >> "$LOGFILE"; }
error() { echo -e "🔴 $@" >> "$LOGFILE"; }

# Gestione interattività con controllo pipe
yn() {
    local msg="$1"
    if [ -t 0 ]; then
        read -r -p "$msg [s/N]" resp
        [[ "$resp" =~ ^[sS]$ ]]
    else
        echo "N"
    fi
}

info "Inizio aggiornamento su $HOSTNAME: $DATA"

# Aggiorna repository con gestione errori estesa
info "🔄 Aggiorna elenco pacchetti"
apt update || { error "Fallito l'aggiornamento della lista pacchetti"; exit 1; }

# Chiedi conferma per upgrade completo
DO_UPGRADE=$(yn "Vuoi effettuare 'apt upgrade per aggiornare tutti i pacchetti'?")

if $DO_UPGRADE; then
    info "⬆️ Esegui aggiornamento pacchetti"
    apt upgrade -y || { warning "Aggiornamento pacchetti completato con errori"; }    
else
    info "⏭️ Salto aggiornamento pacchetti su richiesta utente"
fi

# Chiedi conferma per autoremove
DO_AUTOREMOVE=$(yn "Vuoi eseguire 'apt autoremove' per pulizia?")

if $DO_AUTOREMOVE; then
    info "🧹 Esecuzione apt autoremove"
    apt autoremove -y --purge || { warning "apt autoremove ha segnalato errori"; }
else
    info "⏭️ Salto apt autoremove su richiesta utente"
fi

info "🔚 Fine aggiornamento su $HOSTNAME: $(date)"

# Ricerca pacchetti aggiornati con analisi completa
if [ -f "$APT_LOG" ]; then
    # Pacchetti riusciti
    UPLOADED=$(grep "Upgrade:" $APT_LOG | awk '{print $2, $4}')
    
    # Pacchetti con problemi
    FAILED=$(grep "Failed-Remove:" $APT_LOG | awk '{print $2, $4}')
else
    UPLOADED="Il file log APT non esiste - impossibile tracciare pacchetti"
    FAILED="Impossibile analizzare il file log APT"
fi

# Aggiungi informazioni pacchetti al log
echo -e "\n🟠 Pacchetti aggiornati:" >> "$LOGFILE"
echo "$UPLOADED" >> "$LOGFILE"
echo -e "\n🔴 Pacchetti con problemi:" >> "$LOGFILE"
echo "$FAILED" >> "$LOGFILE"

# Informazioni sistema
info "🧠 Verifica completa del sistema"
uname -a >> "$LOGFILE"
free -h >> "$LOGFILE"
df -h >> "$LOGFILE"
apt list --installed --upgradable | grep -v "^Listing$" >> "$LOGFILE"

# Invio email con gestione completa
if command -v sendmail >/dev/null 2>&1; then
    cat <<EOF | sendmail -t
To: $EMAIL
Subject: $SUBJECT
Content-Type: text/plain; charset=UTF-8

$(cat "$LOGFILE")
EOF
    info "📧 Log inviato a $EMAIL tramite sendmail"
else
    warning "⚠️ Comando 'sendmail' non trovato. Impossibile inviare email."
fi

warning "Importante: Controllare il log per confermare l'esito riuscito con lista pacchetti"

# Nota all'utente:
# Esegui lo script una volta per generare il file /var/log/apt/history.log
# Successivamente, il tracciamento dei pacchetti funzionerà correttamente
# Se il file log non esiste, il sistema segnalerà l'impossibilità di tracciare pacchetti

Altro codice per Rocky linux

#!/bin/bash

# 📅 Info iniziali
DATA=$(date '+%Y-%m-%d %H:%M')
HOSTNAME=$(hostname)
EMAIL="ammin@internal.lan"
SUBJECT="[$HOSTNAME] Log aggiornamento - $DATA"
LOGFILE=$(mktemp)
trap "rm -f $LOGFILE" EXIT

# 🔧 Logging
log() { echo -e "$@" >> "$LOGFILE"; }
info() { log "🟢 $@"; }
warn() { log "🟠 $@"; }
err()  { log "🔴 $@"; }

# ❓ Conferma interattiva
ask() {
    local prompt="$1"
    if [ -t 0 ]; then
        read -r -p "$prompt [s/N] " reply
        [[ "$reply" =~ ^[sS]$ ]]
    else
        return 1
    fi
}

info "Inizio aggiornamento su $HOSTNAME: $DATA"

# 🔄 Aggiorna cache
info "Pulizia e aggiornamento cache..."
dnf clean all && dnf makecache || { err "Errore durante 'dnf makecache'"; exit 1; }

# ⬆️ Upgrade
if ask "Vuoi eseguire 'dnf upgrade'?"; then
    info "Eseguo 'dnf upgrade'..."
    dnf upgrade -y || warn "Upgrade completato con errori"
else
    info "Upgrade saltato"
fi

# 🧹 Autoremove
if ask "Vuoi eseguire 'dnf autoremove'?"; then
    info "Eseguo 'dnf autoremove'..."
    dnf autoremove -y || warn "Autoremove ha segnalato errori"
else
    info "Autoremove saltato"
fi

info "Fine aggiornamento: $(date '+%c')"

# 📦 Tracciamento pacchetti aggiornati
info "📜 Storico transazioni DNF"
dnf history list | head -n 10 >> "$LOGFILE"

LAST_ID=$(dnf history | awk '/Upgrade/ {print $1}' | head -n 1)
if [ -n "$LAST_ID" ]; then
    info "📦 Dettagli ultima transazione (ID $LAST_ID)"
    dnf history info "$LAST_ID" >> "$LOGFILE"
else
    warn "Nessuna transazione di upgrade trovata"
fi

# 🧠 Info sistema
info "🧠 Informazioni sistema:"
uname -a >> "$LOGFILE"
free -h >> "$LOGFILE"
df -h >> "$LOGFILE"

# 📌 Aggiornamenti disponibili
info "📌 Aggiornamenti disponibili:"
dnf check-update >> "$LOGFILE"

# 📧 Invio email con gestione dimensione
MAXSIZE=500000  # ~500 KB
LOGSIZE=$(stat -c%s "$LOGFILE")

if command -v sendmail >/dev/null 2>&1; then
    if [ "$LOGSIZE" -lt "$MAXSIZE" ]; then
        {
            echo "To: $EMAIL"
            echo "Subject: $SUBJECT"
            echo "Content-Type: text/plain; charset=UTF-8"
            echo ""
            cat "$LOGFILE"
        } | sendmail -t
        info "📧 Log inviato a $EMAIL"
    else
        {
            echo "To: $EMAIL"
            echo "Subject: $SUBJECT (estratto)"
            echo "Content-Type: text/plain; charset=UTF-8"
            echo ""
            echo "⚠️ Log troppo grande. Invio solo le ultime 500 righe:\n"
            tail -n 500 "$LOGFILE"
        } | sendmail -t
        warn "Log troppo grande: invio parziale"
    fi
else
    warn "Sendmail non disponibile. Email non inviata."
fi

warn "Controlla il log per confermare l'esito e i pacchetti aggiornati"

📌 Considerazioni finali

Questi script sono pensati per ambienti dove è importante avere controllo manuale sull’aggiornamento e una tracciabilità immediata via email. Entrambi sono compatibili con sendmail e non lasciano tracce locali del log.

Analisi di un Script Bash per la Visualizzazione dei Moduli di Memoria 💻🔍

Il codice che hai fornito è uno script Bash chiamato memory.sh progettato per recuperare e visualizzare informazioni dettagliate sui moduli di memoria installati in un sistema Linux. Analizziamolo passo per passo!

#!/usr/bin/env bash
# memory.sh – mostra direttamente i blocchi dei banchi di memoria

set -euo pipefail

if ! command -v lshw >/dev/null 2>&1; then
    echo "lshw non è installato." >&2
    exit 1
fi

echo "=== Moduli di memoria ==="
sudo lshw -C memory | grep -A 10 'bank:' | grep -v -- '--'



Spiegazione riga per riga:

  1. #!/usr/bin/env bash: Questa è la “shebang” line. Indica al sistema operativo di eseguire lo script utilizzando l’interprete Bash. env garantisce che il percorso a bash sia trovato nel sistema, rendendo lo script più portabile. ✨
  2. # memory.sh – mostra direttamente i blocchi dei banchi di memoria: Questa è una riga di commento che descrive lo scopo dello script. 📝
  3. set -euo pipefail: Questa riga imposta diverse opzioni di Bash per una maggiore robustezza:
    • -e (errexit): Lo script termina immediatamente se un comando esce con un codice di errore diverso da zero. ⚠️
    • -u (nounset): Tratta le variabili non inizializzate come errori.
    • -o pipefail: Se una pipeline (una sequenza di comandi collegati tramite pipe) fallisce, lo script termina.
  4. if ! command -v lshw >/dev/null 2>&1; then ... fi: Questa parte controlla se il comando lshw (Hardware Lister) è installato nel sistema. lshw è uno strumento potente per ottenere informazioni dettagliate sull’hardware del sistema. Se lshw non è trovato, lo script stampa un messaggio di errore e termina. 🚫

Come funziona il resto dello script:

  • echo "=== Moduli di memoria ===": Stampa un’intestazione per rendere l’output più leggibile. 📢
  • sudo lshw -C memory | grep -A 10 'bank:' | grep -v -- '--': Questa è la parte cruciale dello script.
    • sudo lshw -C memory: Esegue lshw con i privilegi di amministratore (sudo) per ottenere informazioni sull’hardware, specificamente sulla categoria “memory”.
    • grep -A 10 'bank:': Filtra l’output di lshw per trovare le righe che contengono la parola “bank:” (che indica i banchi di memoria). -A 10 significa che vengono stampate le 10 righe dopo la riga corrispondente.
    • grep -v -- '--': Esclude le righe che contengono il carattere “–” (che spesso indica separatori in lshw).

Esempio di Output:

L’output dello script sarà una serie di righe che mostrano le informazioni sui banchi di memoria. Ecco un esempio (l’output reale varierà a seconda del tuo hardware):

=== Moduli di memoria ===
    descrizione: DDR4-3200 8GB DIMM
    informazioni:  lunghezza: 16 cm
    descrizione: DDR4-3200 8GB DIMM
    informazioni:  lunghezza: 16 cm
    descrizione: DDR4-3200 8GB DIMM
    informazioni:  lunghezza: 16 cm
    descrizione: DDR4-3200 8GB DIMM
    informazioni:  lunghezza: 16 cm
    descrizione: DDR4-3200 8GB DIMM
    informazioni:  lunghezza: 16 cm

Tabella riassuntiva (ipotetica):

ComponenteTipoCapacitàVelocità
Modulo 1DDR4 DIMM8GB3200MHz
Modulo 2DDR4 DIMM8GB3200MHz
Modulo 3DDR4 DIMM8GB3200MHz

(Nota: questa tabella è un esempio, l’output effettivo dello script conterrà informazioni più dettagliate.)

Consigli Pratici:

  • Esecuzione: Salva lo script in un file (ad esempio, memory.sh), rendilo eseguibile con chmod +x memory.sh e poi eseguilo con ./memory.sh.
  • Privilegi: Lo script richiede privilegi di amministratore (sudo) per accedere alle informazioni sull’hardware.
  • Personalizzazione: Puoi modificare lo script per estrarre altre informazioni, come la dimensione totale della memoria o il tipo di memoria.

Questo script è un ottimo punto di partenza per monitorare la tua memoria e assicurarti che il tuo sistema funzioni in modo ottimale! 🚀

🔍 Verificare Record DNS con Bash: Script Pratico per Admin Reti

In ambienti aziendali o laboratori, è fondamentale sapere se i propri record DNS (A, MX, PTR, SRV…) sono correttamente configurati e risolvibili. Ecco uno script in Bash che permette di eseguire questa verifica in modo semplice, elegante e documentato — con output in un file di log.

🧪 Cos’è questo script?

Un semplice tool scritto in Bash che:

  • interroga una lista personalizzata di record DNS
  • gestisce diversi tipi (A, MX, PTR, SRV)
  • salva i risultati in un file di log con timestamp
  • usa dig per ottenere le risposte dal server DNS specificato

📜 Il codice

#!/bin/bash

# 🔧 Configura IP del tuo DNS server (es. Unbound locale)
DNS_SERVER="192.168.3.123"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
LOGFILE="$SCRIPT_DIR/dnscheck.log"

# 🧹 Pulizia del log: ogni esecuzione parte da zero
> "$LOGFILE"

DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "🔍 DNS Check — $DATE" >> "$LOGFILE"
echo "==========================" >> "$LOGFILE"

# 📋 Lista dei record da interrogare: nome,tipo
RECORDS=$(cat <<EOF
smtp.internal2.lan,A
internal2.lan,MX
192.168.3.83,PTR
_ldap._tcp.internal2.lan,SRV
_kerberos._tcp.internal2.lan,SRV
_kerberos._udp.internal2.lan,SRV
_ldap._tcp.gc._msdcs.internal2.lan,SRV
ns8.internal.lan,A
internal.lan,MX
192.168.3.76,PTR
dc1.ad.internal.lan,A
_ldap._tcp.internal.lan,SRV
_kerberos._tcp.internal.lan,SRV
_kerberos._udp.internal.lan,SRV
_ldap._tcp.gc._msdcs.internal.lan,SRV
EOF
)

# 🔄 Loop per interrogare ogni record e verificare risposta
IFS=$'\n'
for entry in $RECORDS; do
    NAME=$(echo "$entry" | cut -d',' -f1)
    TYPE=$(echo "$entry" | cut -d',' -f2)

    echo -ne "🔎 [$TYPE] $NAME... " >> "$LOGFILE"

    if [ "$TYPE" = "PTR" ]; then
        RESULT=$(dig -x "$NAME" @$DNS_SERVER +short)
    else
        RESULT=$(dig "$NAME" "$TYPE" @$DNS_SERVER +short)
    fi

    if [ -z "$RESULT" ]; then
        echo "❌ Nessuna risposta" >> "$LOGFILE"
    else
        echo "$RESULT" >> "$LOGFILE"
    fi
done

echo -e "✅ Fine verifica\n" >> "$LOGFILE"

🛡️ Come usarlo

  1. Imposta il server DNS in DNS_SERVER (es. 192.168.3.123).
  2. Personalizza la lista RECORDS con i nomi e tipi che vuoi controllare.
  3. Salva lo script come dnscheck.sh, rendilo eseguibile (chmod +x dnscheck.sh) ed eseguilo.
  4. I risultati verranno salvati in dnscheck.log nella stessa directory.

Disattivazione AUTH “STRONG”

Ecco la procedura per disattivare la strong auth (tls)

runagent -m samba1 podman exec -it samba-dc bash

Disattivare l’Autenticazione Forte (Strong Auth) su NethServer 8: Guida Passo-Passo

Attenzione: Questa procedura disabilita un meccanismo di sicurezza critico. Valuta i rischi prima di procedere! Compatibile solo con client Samba legacy senza supporto per Kerberos/TLS.

Procedura Tecnica (via Podman):

  1. Accedi al container Samba:runagent -m samba1 podman exec -it samba-dc bash
  2. Modifica il file di configurazione:echo 'ldap server require strong auth = no' >> /etc/samba/include.conf
  3. Riavvia Samba (senza riavvio completo del sistema):runagent -m samba1 systemctl --user restart samba-dc1

Spiegazione Dettagliata:

  • podman exec -it samba-dc bash: Esegue un terminale interattivo nel container Samba (basato su Samba4 ma compatibile con impostazioni legacy).
  • echo '...' >> /etc/samba/include.conf: Aggiunge la direttiva di disattivazione all’inclusione globale del file di configurazione Samba.
  • runagent -m samba1 systemctl --user restart samba-dc: Riavvia solo i servizi Samba (SMB e NetBIOS) senza interrompere altri servizi NethServer.

Verifica:

  1. Controlla il file modificato:cat /etc/samba/include.conf | grep 'require strong auth'
  2. Testa l’accesso con un client Samba legacy (es: Windows XP) senza Kerberos attivo.

Rischi:

  • Espone il server a attacchi di tipo “man-in-the-middle” su reti non sicure.
  • Incompatibile con standard moderni (Kerberos/TLS obbligatorio per conformità).
    Alternativa Sicura: Abilita LDAP e Kerberos tramite NethServer GUI senza disabilitare strong auth!

Comando Unico da Eseguire su Terminale NethServer:

podman exec -it samba-dc bash -c "echo 'ldap server require strong auth = no' >> /etc/samba/include.conf && runagent -m samba1 systemctl --user restart samba-dc

Backup Consigliato: Salva il file /etc/samba/smb.conf originale prima di procedere!