Bladeren bron

inizio btn vpn

FabioFratini 7 maanden geleden
bovenliggende
commit
61d9c77360

+ 36 - 0
app/Console/Commands/VpnUpdateStatus.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+
+class VpnUpdateStatus extends Command
+{
+    protected $signature = 'vpn:update-status {status}';
+    protected $description = 'Aggiorna lo stato della connessione VPN';
+
+    public function handle()
+    {
+        $status = $this->argument('status');
+
+        try {
+            DB::table('vpn_status')->updateOrInsert(
+                ['id' => 1],
+                [
+                    'status' => $status,
+                    'last_update' => now(),
+                    'updated_at' => now(),
+                ]
+            );
+
+            Log::info("Stato VPN aggiornato: {$status}");
+            $this->info("Stato VPN aggiornato: {$status}");
+
+        } catch (\Exception $e) {
+            Log::error("Errore aggiornamento stato VPN: " . $e->getMessage());
+            $this->error("Errore aggiornamento stato VPN: " . $e->getMessage());
+        }
+    }
+}

+ 98 - 0
app/Http/Controllers/VpnController.php

@@ -0,0 +1,98 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+use App\Services\VpnManager;
+use Illuminate\Support\Facades\Validator;
+
+class VpnController extends Controller
+{
+    private $vpnManager;
+
+    public function __construct(VpnManager $vpnManager)
+    {
+        $this->vpnManager = $vpnManager;
+    }
+
+    public function showCredentialsForm()
+    {
+        $status = $this->vpnManager->getVpnStatus();
+        return view('vpn.credentials', compact('status'));
+    }
+
+    public function updateCredentials(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'username' => 'required|string',
+            'password' => 'required|string',
+            'server' => 'required|string',
+        ]);
+
+        if ($validator->fails()) {
+            return redirect()->back()
+                ->withErrors($validator)
+                ->withInput();
+        }
+
+        $success = $this->vpnManager->updateCredentials(
+            $request->username,
+            $request->password,
+            $request->server
+        );
+
+        if ($success) {
+            return redirect()->back()->with('success', 'Credenziali VPN aggiornate con successo!');
+        } else {
+            return redirect()->back()->with('error', 'Errore nell\'aggiornamento delle credenziali VPN.');
+        }
+    }
+
+    public function getStatus()
+    {
+        $status = $this->vpnManager->getVpnStatus();
+        $lastUpdate = $this->vpnManager->getLastUpdate();
+
+        return response()->json([
+            'status' => $status,
+            'last_update' => $lastUpdate
+        ]);
+    }
+
+    public function connect()
+    {
+        try {
+            $result = $this->vpnManager->connectVpn();
+
+            if ($result) {
+                return response()->json(['success' => true, 'message' => 'Connessione VPN avviata']);
+            } else {
+                return response()->json(['success' => false, 'message' => 'Errore nella connessione VPN']);
+            }
+        } catch (\Exception $e) {
+            return response()->json(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
+        }
+    }
+
+    public function disconnect()
+    {
+        try {
+            $result = $this->vpnManager->disconnectVpn();
+
+            if ($result) {
+                return response()->json(['success' => true, 'message' => 'Disconnessione VPN avviata']);
+            } else {
+                return response()->json(['success' => false, 'message' => 'Errore nella disconnessione VPN']);
+            }
+        } catch (\Exception $e) {
+            return response()->json(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
+        }
+    }
+
+        public function showManagementPage()
+    {
+        $status = $this->vpnManager->getVpnStatus();
+        $lastUpdate = $this->vpnManager->getLastUpdate();
+        return view('vpn.management', compact('status', 'lastUpdate'));
+    }
+}

+ 3 - 1
app/Providers/AppServiceProvider.php

@@ -11,7 +11,9 @@ class AppServiceProvider extends ServiceProvider
      */
     public function register(): void
     {
-        //
+        $this->app->singleton(VpnManager::class, function ($app) {
+            return new VpnManager();
+        });
     }
 
     /**

+ 130 - 0
app/Services/VpnManager.php

@@ -0,0 +1,130 @@
+<?php
+
+namespace App\Services;
+
+use Illuminate\Support\Facades\Storage;
+use Illuminate\Support\Facades\Crypt;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+class VpnManager
+{
+    private $configPath = 'scripts/vpn-config.conf';
+    private $scriptPath = 'scripts/vpn-connect.sh';
+
+    public function updateCredentials($username, $password, $server)
+    {
+        try {
+            // Crea il contenuto del file di configurazione
+            $configContent = "# Configurazione VPN - storage/scripts/vpn-config.conf\n";
+            $configContent .= "# ATTENZIONE: Questo file deve avere permessi 600\n\n";
+            $configContent .= "VPN_USERNAME=\"{$username}\"\n";
+            $configContent .= "VPN_PASSWORD=\"{$password}\"\n";
+            $configContent .= "VPN_SERVER=\"{$server}\"\n";
+
+            // Salva il file di configurazione
+            Storage::put($this->configPath, $configContent);
+
+            // Imposta i permessi corretti (solo per sistemi Unix/Linux)
+            $fullPath = storage_path('app/' . $this->configPath);
+            chmod($fullPath, 0600);
+
+            Log::info('Credenziali VPN aggiornate con successo');
+            return true;
+
+        } catch (\Exception $e) {
+            Log::error('Errore nell\'aggiornamento delle credenziali VPN: ' . $e->getMessage());
+            return false;
+        }
+    }
+
+    public function getVpnStatus()
+    {
+        try {
+            $status = DB::table('vpn_status')->first();
+            return $status ? $status->status : 'unknown';
+        } catch (\Exception $e) {
+            Log::error('Errore nel recupero dello stato VPN: ' . $e->getMessage());
+            return 'error';
+        }
+    }
+
+    public function getLastUpdate()
+    {
+        try {
+            $status = DB::table('vpn_status')->first();
+            return $status ? $status->last_update : null;
+        } catch (\Exception $e) {
+            Log::error('Errore nel recupero dell\'ultimo aggiornamento VPN: ' . $e->getMessage());
+            return null;
+        }
+    }
+
+    public function connectVpn()
+    {
+        try {
+            $scriptPath = storage_path('app/' . $this->scriptPath);
+
+            if (!file_exists($scriptPath)) {
+                Log::error('Script VPN non trovato: ' . $scriptPath);
+                return false;
+            }
+
+            // Esegue lo script in background
+            $command = "bash {$scriptPath} > /dev/null 2>&1 &";
+            exec($command, $output, $returnVar);
+
+            Log::info('Comando VPN connect eseguito', [
+                'command' => $command,
+                'return_var' => $returnVar
+            ]);
+
+            return true;
+
+        } catch (\Exception $e) {
+            Log::error('Errore nell\'esecuzione del comando VPN connect: ' . $e->getMessage());
+            return false;
+        }
+    }
+
+    public function disconnectVpn()
+    {
+        try {
+            // Comando per disconnettere VPN Cisco AnyConnect
+            $command = "/opt/cisco/anyconnect/bin/vpn disconnect > /dev/null 2>&1 &";
+            exec($command, $output, $returnVar);
+
+            // Aggiorna lo stato nel database
+            DB::table('vpn_status')->updateOrInsert(
+                ['id' => 1],
+                [
+                    'status' => 'disconnected',
+                    'last_update' => now(),
+                    'updated_at' => now(),
+                ]
+            );
+
+            Log::info('Comando VPN disconnect eseguito', [
+                'command' => $command,
+                'return_var' => $returnVar
+            ]);
+
+            return true;
+
+        } catch (\Exception $e) {
+            Log::error('Errore nell\'esecuzione del comando VPN disconnect: ' . $e->getMessage());
+            return false;
+        }
+    }
+
+    public function makeScriptExecutable()
+    {
+        try {
+            $fullPath = storage_path('app/' . $this->scriptPath);
+            chmod($fullPath, 0755);
+            return true;
+        } catch (\Exception $e) {
+            Log::error('Errore nell\'impostazione dei permessi script: ' . $e->getMessage());
+            return false;
+        }
+    }
+}

+ 24 - 0
database/migrations/2025_07_03_105719_creat_vpn_staus_table.php

@@ -0,0 +1,24 @@
+
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up()
+    {
+        Schema::create('vpn_status', function (Blueprint $table) {
+            $table->id();
+            $table->string('status')->default('disconnected');
+            $table->timestamp('last_update');
+            $table->timestamps();
+        });
+    }
+
+    public function down()
+    {
+        Schema::dropIfExists('vpn_status');
+    }
+};

+ 31 - 1
resources/views/layouts/app.blade.php

@@ -237,6 +237,15 @@
                     </a>
                 </li>
             </ul>
+                <li class="nav-item">
+                    <a href="/vpn" class="nav-link">
+                        <i class="nav-icon fas fa-shield-alt"></i>
+                        <p>
+                            Connessione VPN
+                            <span class="badge badge-info right" id="vpn-status-badge">...</span>
+                        </p>
+                    </a>
+                </li>
           </li>
 
 
@@ -323,7 +332,28 @@
 <script src="/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
 <!-- AdminLTE App -->
 <script src="/dist/js/adminlte.js"></script>
-
+<script>
+$(document).ready(function() {
+    // Aggiorna il badge VPN nella sidebar ogni 30 secondi
+    function updateVpnBadge() {
+        $.get('/vpn/status', function(data) {
+            const badge = $('#vpn-status-badge');
+            if (data.status === 'connected') {
+                badge.removeClass().addClass('badge badge-success right').text('ON');
+            } else if (data.status === 'disconnected') {
+                badge.removeClass().addClass('badge badge-danger right').text('OFF');
+            } else {
+                badge.removeClass().addClass('badge badge-warning right').text('?');
+            }
+        }).fail(function() {
+            $('#vpn-status-badge').removeClass().addClass('badge badge-danger right').text('ERR');
+        });
+    }
+
+    updateVpnBadge();
+    setInterval(updateVpnBadge, 30000);
+});
+</script>
 
 @livewireScripts
 

+ 248 - 0
resources/views/vpn/management.blade.php

@@ -0,0 +1,248 @@
+
+<div class="content-header">
+    <div class="container-fluid">
+        <div class="row mb-2">
+            <div class="col-sm-6">
+                <h1 class="m-0">Gestione Connessione VPN</h1>
+            </div>
+            <div class="col-sm-6">
+                <ol class="breadcrumb float-sm-right">
+                    <li class="breadcrumb-item"><a href="/dashboard">Home</a></li>
+                    <li class="breadcrumb-item active">VPN</li>
+                </ol>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- Main content -->
+<div class="row">
+    <!-- Stato VPN -->
+    <div class="col-md-6">
+        <div class="card card-primary">
+            <div class="card-header">
+                <h3 class="card-title">
+                    <i class="fas fa-shield-alt"></i> Stato Connessione VPN
+                </h3>
+            </div>
+            <div class="card-body">
+                <div class="row">
+                    <div class="col-md-6">
+                        <div class="info-box">
+                            <span class="info-box-icon bg-info" id="vpn-status-icon">
+                                <i class="fas fa-question"></i>
+                            </span>
+                            <div class="info-box-content">
+                                <span class="info-box-text">Stato VPN</span>
+                                <span class="info-box-number" id="vpn-status-text">Caricamento...</span>
+                                <span class="info-box-more" id="vpn-last-update">--</span>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-md-6">
+                        <div class="text-center">
+                            <button type="button" class="btn btn-success btn-lg" id="connect-vpn-btn">
+                                <i class="fas fa-play"></i> Connetti VPN
+                            </button>
+                            <button type="button" class="btn btn-warning btn-lg mt-2" id="disconnect-vpn-btn">
+                                <i class="fas fa-stop"></i> Disconnetti VPN
+                            </button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Configurazione Credenziali -->
+    <div class="col-md-6">
+        <div class="card card-warning">
+            <div class="card-header">
+                <h3 class="card-title">
+                    <i class="fas fa-cog"></i> Configurazione Credenziali
+                </h3>
+            </div>
+            <div class="card-body">
+                @if(session('success'))
+                    <div class="alert alert-success alert-dismissible">
+                        <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+                        {{ session('success') }}
+                    </div>
+                @endif
+
+                <form action="/vpn/update-credentials" method="POST">
+                    @csrf
+                    <div class="form-group">
+                        <label for="username">Username</label>
+                        <input type="text" class="form-control" id="username" name="username"
+                               value="{{ old('username', 'com.cmrmp013.0001') }}" required>
+                    </div>
+                    <div class="form-group">
+                        <label for="password">Password</label>
+                        <input type="password" class="form-control" id="password" name="password"
+                               placeholder="Inserisci la password" required>
+                    </div>
+                    <div class="form-group">
+                        <label for="server">Server VPN</label>
+                        <input type="text" class="form-control" id="server" name="server"
+                               value="{{ old('server', 'anyvpn.ilportaledellautomobilista.it/utentiMCTC') }}" required>
+                    </div>
+                    <button type="submit" class="btn btn-primary">
+                        <i class="fas fa-save"></i> Salva Credenziali
+                    </button>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- Log VPN -->
+<div class="row mt-4">
+    <div class="col-md-12">
+        <div class="card card-info">
+            <div class="card-header">
+                <h3 class="card-title">
+                    <i class="fas fa-file-alt"></i> Log Connessione VPN
+                </h3>
+                <div class="card-tools">
+                    <button type="button" class="btn btn-tool" id="refresh-logs">
+                        <i class="fas fa-sync"></i>
+                    </button>
+                </div>
+            </div>
+            <div class="card-body">
+                <div class="table-responsive">
+                    <table class="table table-striped">
+                        <thead>
+                            <tr>
+                                <th>Data/Ora</th>
+                                <th>Tipo</th>
+                                <th>Messaggio</th>
+                            </tr>
+                        </thead>
+                        <tbody id="vpn-logs-table">
+                            <tr>
+                                <td colspan="3" class="text-center">Caricamento logs...</td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+@push('css')
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
+@endpush
+
+@push('scripts')
+<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
+<script>
+    $(document).ready(function() {
+        // Funzione per aggiornare lo stato VPN
+        function updateVpnStatus() {
+            $.ajax({
+                url: '/vpn/status',
+                type: 'GET',
+                success: function(data) {
+                    const status = data.status;
+                    const statusIcon = $('#vpn-status-icon i');
+                    const statusText = $('#vpn-status-text');
+                    const statusBadge = $('#vpn-status-badge');
+                    const lastUpdate = $('#vpn-last-update');
+
+                    // Aggiorna icona e testo in base al stato
+                    if (status === 'connected') {
+                        statusIcon.removeClass().addClass('fas fa-check');
+                        $('#vpn-status-icon').removeClass().addClass('info-box-icon bg-success');
+                        statusText.text('Connesso');
+                        if (statusBadge.length) statusBadge.removeClass().addClass('badge badge-success right').text('ON');
+                    } else if (status === 'disconnected') {
+                        statusIcon.removeClass().addClass('fas fa-times');
+                        $('#vpn-status-icon').removeClass().addClass('info-box-icon bg-danger');
+                        statusText.text('Disconnesso');
+                        if (statusBadge.length) statusBadge.removeClass().addClass('badge badge-danger right').text('OFF');
+                    } else {
+                        statusIcon.removeClass().addClass('fas fa-question');
+                        $('#vpn-status-icon').removeClass().addClass('info-box-icon bg-warning');
+                        statusText.text('Sconosciuto');
+                        if (statusBadge.length) statusBadge.removeClass().addClass('badge badge-warning right').text('?');
+                    }
+
+                    if (data.last_update) {
+                        lastUpdate.text('Ultimo aggiornamento: ' + new Date(data.last_update).toLocaleString());
+                    }
+                },
+                error: function() {
+                    $('#vpn-status-text').text('Errore nel recupero dello stato');
+                    const statusBadge = $('#vpn-status-badge');
+                    if (statusBadge.length) statusBadge.removeClass().addClass('badge badge-danger right').text('ERR');
+                }
+            });
+        }
+
+        // Funzione per connettere VPN
+        $('#connect-vpn-btn').click(function() {
+            const btn = $(this);
+            btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Connettendo...');
+
+            $.ajax({
+                url: '/vpn/connect',
+                type: 'POST',
+                data: {
+                    _token: '{{ csrf_token() }}'
+                },
+                success: function(data) {
+                    if (data.success) {
+                        toastr.success('Comando di connessione VPN inviato!');
+                        setTimeout(updateVpnStatus, 3000); // Aggiorna lo stato dopo 3 secondi
+                    } else {
+                        toastr.error('Errore nel lancio della connessione VPN');
+                    }
+                },
+                error: function() {
+                    toastr.error('Errore nel lancio della connessione VPN');
+                },
+                complete: function() {
+                    btn.prop('disabled', false).html('<i class="fas fa-play"></i> Connetti VPN');
+                }
+            });
+        });
+
+        // Funzione per disconnettere VPN
+        $('#disconnect-vpn-btn').click(function() {
+            const btn = $(this);
+            btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Disconnettendo...');
+
+            $.ajax({
+                url: '/vpn/disconnect',
+                type: 'POST',
+                data: {
+                    _token: '{{ csrf_token() }}'
+                },
+                success: function(data) {
+                    if (data.success) {
+                        toastr.success('Comando di disconnessione VPN inviato!');
+                        setTimeout(updateVpnStatus, 3000);
+                    } else {
+                        toastr.error('Errore nella disconnessione VPN');
+                    }
+                },
+                error: function() {
+                    toastr.error('Errore nella disconnessione VPN');
+                },
+                complete: function() {
+                    btn.prop('disabled', false).html('<i class="fas fa-stop"></i> Disconnetti VPN');
+                }
+            });
+        });
+
+        // Aggiorna lo stato all'avvio
+        updateVpnStatus();
+
+        // Aggiorna lo stato ogni 30 secondi
+        setInterval(updateVpnStatus, 30000);
+    });
+</script>
+@endpush

+ 5 - 0
routes/web.php

@@ -112,6 +112,11 @@ Route::group(['middleware' => 'auth'],function(){
     Route::get('/parte-macchina', \App\Http\Livewire\ParteMacchina::class);
     Route::get('/tipo-veicolo', \App\Http\Livewire\TipoVeicolo::class);
     Route::get('/users', \App\Http\Livewire\User::class);
+    Route::get('/vpn', [\App\Http\Controllers\VpnController::class, 'showManagementPage'])->name('vpn.management');
+    Route::get('/vpn/status', [\App\Http\Controllers\VpnController::class, 'getStatus'])->name('vpn.status');
+    Route::post('/vpn/connect', [\App\Http\Controllers\VpnController::class, 'connect'])->name('vpn.connect');
+    Route::post('/vpn/disconnect', [\App\Http\Controllers\VpnController::class, 'disconnect'])->name('vpn.disconnect');
+    Route::post('/vpn/update-credentials', [\App\Http\Controllers\VpnController::class, 'updateCredentials'])->name('vpn.update-credentials');
 
     Route::get('/reports', \App\Http\Livewire\Report::class);
     Route::get('/istat', \App\Http\Livewire\Istat::class);

+ 3 - 0
storage/scripts/vpn-config.conf

@@ -0,0 +1,3 @@
+VPN_USERNAME="com.cmrmp013.0001"
+VPN_PASSWORD="SuperQuindici-50"
+VPN_SERVER="anyvpn.ilportaledellautomobilista.it/utentiMCTC"

+ 42 - 0
storage/scripts/vpn-connect.sh

@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# Script per connessione VPN Cisco AnyConnect
+# Posizionare in: storage/scripts/vpn-connect.sh
+
+# Legge le credenziali da file di configurazione
+source "$(dirname "$0")/vpn-config.conf"
+
+# Log file
+LOG_FILE="$(dirname "$0")/../logs/vpn-connection.log"
+
+# Funzione di logging
+log_message() {
+    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
+}
+
+# Verifica se le credenziali sono configurate
+if [[ -z "$VPN_USERNAME" || -z "$VPN_PASSWORD" || -z "$VPN_SERVER" ]]; then
+    log_message "ERROR: Credenziali VPN non configurate correttamente"
+    exit 1
+fi
+
+# Controlla se AnyConnect è installato
+if [[ ! -f "/opt/cisco/anyconnect/bin/vpn" ]]; then
+    log_message "ERROR: Cisco AnyConnect non trovato"
+    exit 1
+fi
+
+log_message "INFO: Avvio connessione VPN..."
+
+# Esegue la connessione VPN
+echo -e "${VPN_USERNAME}\n${VPN_PASSWORD}\ny" | /opt/cisco/anyconnect/bin/vpn -s connect "$VPN_SERVER"
+
+# Controlla il risultato
+if [[ $? -eq 0 ]]; then
+    log_message "SUCCESS: Connessione VPN stabilita"
+    # Aggiorna timestamp ultimo successo nel database Laravel
+    php "$(dirname "$0")/../../artisan" vpn:update-status connected
+else
+    log_message "ERROR: Connessione VPN fallita"
+    php "$(dirname "$0")/../../artisan" vpn:update-status failed
+fi

+ 33 - 0
storage/scripts/vpn-disconnect.sh

@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Script per disconnessione VPN Cisco AnyConnect
+# Posizionare in: storage/scripts/vpn-disconnect.sh
+
+# Log file
+LOG_FILE="$(dirname "$0")/../logs/vpn-connection.log"
+
+# Funzione di logging
+log_message() {
+    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
+}
+
+# Controlla se AnyConnect è installato
+if [[ ! -f "/opt/cisco/anyconnect/bin/vpn" ]]; then
+    log_message "ERROR: Cisco AnyConnect non trovato"
+    exit 1
+fi
+
+log_message "INFO: Avvio disconnessione VPN..."
+
+# Esegue la disconnessione VPN
+/opt/cisco/anyconnect/bin/vpn disconnect
+
+# Controlla il risultato
+if [[ $? -eq 0 ]]; then
+    log_message "SUCCESS: Disconnessione VPN completata"
+    # Aggiorna timestamp nel database Laravel
+    php "$(dirname "$0")/../../artisan" vpn:update-status disconnected
+else
+    log_message "ERROR: Disconnessione VPN fallita"
+    php "$(dirname "$0")/../../artisan" vpn:update-status error
+fi