'boolean', 'compress' => 'boolean', 'active' => 'boolean', ]; // Relationships public function server() { return $this->belongsTo(Server::class); } // Scopes public function scopeActive($q) { return $q->where('active', 1); } public function scopeOfType($q, $type) { return $q->where('type', $type); } // Generate a basic OpenVPN config (example). Adapt to your templates and security needs. public function generateConfig() { // If a pre-generated config is stored, return it if ($this->config_path && Storage::exists($this->config_path)) { return Storage::get($this->config_path); } // Example template — replace with your real generation logic $server = $this->server ? $this->server->address : 'vpn.example.com'; $proto = 'udp'; $port = 1194; $conf = []; $conf[] = "client"; $conf[] = "dev tun"; $conf[] = "proto {$proto}"; $conf[] = "remote {$server} {$port}"; $conf[] = "resolv-retry infinite"; $conf[] = "nobind"; if ($this->compress) { $conf[] = "comp-lzo"; } if ($this->push_dns) { $conf[] = "dhcp-option DNS 10.8.0.1"; } if ($this->allowed_ips) { // allowed_ips are usually server-side; include as comment for operator $conf[] = "# Allowed IPs: " . $this->allowed_ips; } // insert certs/keys placeholders — do NOT store private keys in cleartext unless secure if ($this->auth_type === 'cert') { $conf[] = "\n# CA cert here\n"; $conf[] = "\n# Client cert here\n"; $conf[] = "\n# Client key hidden\n"; } else { // username/password auth $conf[] = "auth-user-pass"; } return implode("\n", $conf) . "\n"; } /** * Store generated config to disk (optional). * Returns storage path. */ public function storeGeneratedConfig() { $config = $this->generateConfig(); $filename = 'vpn/configs/' . Str::slug($this->name) . '-' . $this->id . '.ovpn'; Storage::put($filename, $config); $this->config_path = $filename; $this->save(); return $filename; } }