166 lines
6.7 KiB
PHP
166 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\VpnConfig;
|
|
use Illuminate\Http\Request;
|
|
|
|
class VpnConfigController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$vpns = VpnConfig::orderBy('partner_name')->paginate(15);
|
|
return view('vpns.index', compact('vpns'));
|
|
}
|
|
|
|
// Handle Add Form Submission
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'partner_name' => 'required|string|max:255',
|
|
'status' => 'required|in:Active,Inactive',
|
|
'local_ip' => 'required|ip',
|
|
'peer_ip' => 'required|ip',
|
|
'encryption_domain_local' => 'nullable|string|max:255',
|
|
'encryption_domain_remote' => 'nullable|string|max:255',
|
|
'preshared_key' => 'required|string',
|
|
'local_device' => 'nullable|string|max:255',
|
|
'peer_device' => 'nullable|string|max:255',
|
|
'ike_version' => 'required|integer',
|
|
'phase1_encryption' => 'required|string|max:50',
|
|
'phase1_hash' => 'required|string|max:50',
|
|
'phase1_dh_group' => 'required|string|max:50',
|
|
'phase1_lifetime' => 'required|integer',
|
|
'phase2_encryption' => 'required|string|max:50',
|
|
'phase2_hash' => 'required|string|max:50',
|
|
'phase2_dh_group' => 'nullable|string|max:50',
|
|
'phase2_lifetime' => 'required|integer',
|
|
'pfs_enabled' => 'boolean',
|
|
]);
|
|
|
|
VpnConfig::create($validated);
|
|
|
|
return response()->json(['success' => true, 'message' => 'VPN configuration added successfully.']);
|
|
}
|
|
|
|
// Fetch data for the Edit Modal
|
|
public function show($id)
|
|
{
|
|
$vpn = VpnConfig::findOrFail($id);
|
|
|
|
// Hide the pre-shared key from being sent back in the JSON response for security
|
|
$vpn->makeHidden('preshared_key');
|
|
|
|
return response()->json($vpn);
|
|
}
|
|
|
|
// Handle Edit Form Submission
|
|
public function update(Request $request, $id)
|
|
{
|
|
$vpn = VpnConfig::findOrFail($id);
|
|
|
|
$validated = $request->validate([
|
|
'partner_name' => 'required|string|max:255',
|
|
'status' => 'required|in:Active,Inactive',
|
|
'local_ip' => 'required|ip',
|
|
'peer_ip' => 'required|ip',
|
|
'encryption_domain_local' => 'nullable|string|max:255',
|
|
'encryption_domain_remote' => 'nullable|string|max:255',
|
|
'preshared_key' => 'nullable|string',
|
|
'local_device' => 'nullable|string|max:255',
|
|
'peer_device' => 'nullable|string|max:255',
|
|
'ike_version' => 'required|integer',
|
|
'phase1_encryption' => 'required|string|max:50',
|
|
'phase1_hash' => 'required|string|max:50',
|
|
'phase1_dh_group' => 'required|string|max:50',
|
|
'phase1_lifetime' => 'required|integer',
|
|
'phase2_encryption' => 'required|string|max:50',
|
|
'phase2_hash' => 'required|string|max:50',
|
|
'phase2_dh_group' => 'nullable|string|max:50',
|
|
'phase2_lifetime' => 'required|integer',
|
|
'pfs_enabled' => 'boolean',
|
|
]);
|
|
|
|
|
|
// If the PSK field is empty, remove it so we don't overwrite the existing key
|
|
if (empty($validated['preshared_key'])) {
|
|
unset($validated['preshared_key']);
|
|
}
|
|
|
|
$vpn->update($validated);
|
|
|
|
return response()->json(['success' => true, 'message' => 'VPN configuration updated successfully.']);
|
|
}
|
|
|
|
// Export the company's global standard VPN parameters
|
|
public function downloadStandardTemplate()
|
|
{
|
|
$template = "=================================================\n";
|
|
$template .= " Click Mobile VPN Configuration Parameters\n";
|
|
$template .= "=================================================\n\n";
|
|
|
|
$template .= "! Phase 1 (IKE / ISAKMP)\n";
|
|
$template .= " Encryption Algorithm: AES-256\n";
|
|
$template .= " Hash Algorithm: SHA-256\n";
|
|
$template .= " Authentication Method: Pre-Shared Key (PSK)\n";
|
|
$template .= " Diffie-Hellman Group: Group 14\n";
|
|
$template .= " Lifetime: 86400 seconds\n\n";
|
|
|
|
$template .= "! Phase 2 (IPsec)\n";
|
|
$template .= " Protocol: ESP\n";
|
|
$template .= " Encryption Algorithm: AES-256\n";
|
|
$template .= " Hash Algorithm: SHA-256\n";
|
|
$template .= " Perfect Forward Secrecy (PFS): Group 14\n";
|
|
$template .= " Lifetime: 3600 seconds\n\n";
|
|
|
|
$template .= "! Gateway Details\n";
|
|
$template .= " Our Public Gateway IP: [216.55.137.19]\n";
|
|
$template .= " Our Encryption Domain: [10.199.0.0/24]\n";
|
|
|
|
return response($template)
|
|
->header('Content-Type', 'text/plain')
|
|
->header('Content-Disposition', 'attachment; filename="standard_vpn_parameters.txt"');
|
|
}
|
|
|
|
// Fetch data to populate the Partner Export Modal
|
|
public function generateTemplate($id)
|
|
{
|
|
$vpn = VpnConfig::findOrFail($id);
|
|
|
|
$template = "=================================================\n";
|
|
$template .= " VPN Configuration for Partner: {$vpn->partner_name}\n";
|
|
$template .= "=================================================\n\n";
|
|
$template .= "! Phase 1 (IKE)\n";
|
|
$template .= "crypto isakmp policy 10\n";
|
|
$template .= " encr aes 256\n";
|
|
$template .= " hash sha256\n";
|
|
$template .= " authentication pre-share\n";
|
|
$template .= " group 14\n";
|
|
$template .= "crypto isakmp key {$vpn->preshared_key} address {$vpn->local_ip}\n\n";
|
|
$template .= "! Phase 2 (IPsec)\n";
|
|
$template .= "crypto ipsec transform-set TS-AES256-SHA256 esp-aes 256 esp-sha256-hmac\n";
|
|
$template .= "crypto map VPNMAP 10 ipsec-isakmp\n";
|
|
$template .= " set peer {$vpn->local_ip}\n";
|
|
$template .= " set transform-set TS-AES256-SHA256\n";
|
|
$template .= " match address 100\n\n";
|
|
$template .= "! Access Control List (Encryption Domains)\n";
|
|
$template .= "access-list 100 permit ip {$vpn->encryption_domain_remote} {$vpn->encryption_domain_local}\n";
|
|
|
|
return response()->json(['template' => $template, 'partner_name' => $vpn->partner_name]);
|
|
}
|
|
|
|
// Process the edited text and force a file download
|
|
public function download(Request $request)
|
|
{
|
|
$request->validate([
|
|
'config_content' => 'required|string',
|
|
'partner_name' => 'required|string',
|
|
]);
|
|
|
|
$filename = str_replace(' ', '_', strtolower($request->partner_name)) . '_vpn_config.txt';
|
|
|
|
return response($request->config_content)
|
|
->header('Content-Type', 'text/plain')
|
|
->header('Content-Disposition', "attachment; filename=\"{$filename}\"");
|
|
}
|
|
} |