""" Utility for generating OpenVPN client configuration files. """ import os import subprocess def generate_client_config(username: str): """ Generates a .ovpn file for a given user. Args: username: The username for which to generate the config. """ easyrsa_dir = "/home/arthur/openvpn-ca/" ca_path = "/home/arthur/openvpn-ca/pki/ca.crt" ta_path = "/home/arthur/openvpn-ca/ta.key" client_crt_path = f"/home/arthur/openvpn-ca/pki/issued/{username}.crt" client_key_path = f"/home/arthur/openvpn-ca/pki/private/{username}.key" output_path = f"/etc/openvpn/client/{username}.ovpn" # Step 1: Generate the client certificate print(f"Generating certificate for user: {username}...") try: command = ["./easyrsa", "--batch", "build-client-full", username, "nopass"] process = subprocess.run( command, cwd=easyrsa_dir, check=True, capture_output=True, text=True ) print(process.stdout) print("Certificate generated successfully.") except FileNotFoundError: print(f"Error: 'easyrsa' script not found in {easyrsa_dir}. Please check the path.") return except subprocess.CalledProcessError as e: print(f"Error generating certificate for user: {username}") print(f"Return code: {e.returncode}") print(f"Stderr: {e.stderr}") return # Step 2: Verify that all required files exist for f in [ca_path, ta_path, client_crt_path, client_key_path]: if not os.path.isfile(f): print(f"Error: Cannot read file '{f}'. File not found after generation.") return # Step 3: Read the content of the files try: with open(ca_path, 'r') as f: ca_content = f.read() with open(client_crt_path, 'r') as f: client_crt_content = f.read() with open(client_key_path, 'r') as f: client_key_content = f.read() with open(ta_path, 'r') as f: ta_content = f.read() except IOError as e: print(f"Error reading files: {e}") return # Step 4: Assemble the .ovpn configuration ovpn_config = f""" client dev tun proto udp remote 14.241.240.102 1194 # use FTP IP address resolv-retry infinite nobind persist-key persist-tun remote-cert-tls server cipher AES-256-GCM # push mac address info push-peer-info verb 3 {ca_content} {client_crt_content} {client_key_content} {ta_content} key-direction 1 """ # Step 5: Write the configuration to the output file try: output_dir = os.path.dirname(output_path) # Check if dir exists and if we have write permission if not os.path.isdir(output_dir) or not os.access(output_dir, os.W_OK): print(f"Error: Output directory '{output_dir}' does not exist or is not writable.") print("Please ensure you have the correct permissions to write to this directory.") # As a fallback, save to a local directory local_output_dir = "generated-clients" if not os.path.exists(local_output_dir): os.makedirs(local_output_dir) local_output_path = os.path.join(local_output_dir, f"{username}.ovpn") with open(local_output_path, 'w') as f: f.write(ovpn_config) print(f"Could not write to server path. Saved config locally to: {local_output_path}") return with open(output_path, 'w') as f: f.write(ovpn_config) print(f"Successfully generated client config: {output_path}") except IOError as e: print(f"Error writing to file: {e}")