wip: peers
This commit is contained in:
+290
-1
@@ -371,4 +371,293 @@ AllowedIPs = {allowed_ips}
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to restart WireGuard service: {e}")
|
||||
return False
|
||||
return False
|
||||
|
||||
def get_peer_config(self, peer_name: str) -> Optional[str]:
|
||||
"""Get WireGuard client configuration for a specific peer"""
|
||||
try:
|
||||
# Get peer information
|
||||
peers = self.get_wireguard_peers()
|
||||
peer_info = None
|
||||
|
||||
for peer in peers:
|
||||
if peer.get('name') == peer_name:
|
||||
peer_info = peer
|
||||
break
|
||||
|
||||
if not peer_info:
|
||||
logger.warning(f"Peer {peer_name} not found")
|
||||
return None
|
||||
|
||||
# Get server configuration
|
||||
server_config = self._get_server_config()
|
||||
|
||||
# Generate client configuration
|
||||
client_config = self._generate_client_config(peer_info, server_config)
|
||||
|
||||
return client_config
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting peer config for {peer_name}: {e}")
|
||||
return None
|
||||
|
||||
def _get_server_config(self) -> Dict[str, str]:
|
||||
"""Get server configuration details"""
|
||||
try:
|
||||
# Try to read server config file
|
||||
server_config_path = os.path.join(self.wg_config_dir, 'wg_confs', 'wg0.conf')
|
||||
if os.path.exists(server_config_path):
|
||||
with open(server_config_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Parse server configuration
|
||||
lines = content.strip().split('\n')
|
||||
server_public_key = None
|
||||
server_endpoint = None
|
||||
server_private_key = None
|
||||
|
||||
# Look for server private key and endpoint
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line.startswith('PrivateKey'):
|
||||
server_private_key = line.split('=', 1)[1].strip()
|
||||
elif line.startswith('ListenPort'):
|
||||
port = line.split('=', 1)[1].strip()
|
||||
# Get server IP from environment or detect it
|
||||
server_ip = os.environ.get('WIREGUARD_SERVER_IP')
|
||||
if not server_ip:
|
||||
# Try to get the actual external IP
|
||||
try:
|
||||
import socket
|
||||
import requests
|
||||
# First try to get external IP from a service
|
||||
try:
|
||||
response = requests.get('https://api.ipify.org', timeout=5)
|
||||
if response.status_code == 200:
|
||||
server_ip = response.text.strip()
|
||||
else:
|
||||
raise Exception("Failed to get external IP")
|
||||
except Exception:
|
||||
# Fallback: try to get local IP that's not Docker internal
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||
s.connect(("8.8.8.8", 80))
|
||||
local_ip = s.getsockname()[0]
|
||||
# If it's a Docker internal IP, use localhost for development
|
||||
if local_ip.startswith('172.') or local_ip.startswith('192.168.'):
|
||||
server_ip = "localhost"
|
||||
else:
|
||||
server_ip = local_ip
|
||||
except Exception:
|
||||
# Ultimate fallback to localhost for development
|
||||
server_ip = "localhost"
|
||||
server_endpoint = f"{server_ip}:{port}"
|
||||
|
||||
# Generate public key from private key if we have it
|
||||
if server_private_key:
|
||||
try:
|
||||
# Use wg pubkey command to generate public key from private key
|
||||
import subprocess
|
||||
result = subprocess.run(['wg', 'pubkey'],
|
||||
input=server_private_key,
|
||||
capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0:
|
||||
server_public_key = result.stdout.strip()
|
||||
else:
|
||||
# Fallback: try to read from existing public key file
|
||||
pubkey_path = os.path.join(self.wg_config_dir, 'publickey')
|
||||
if os.path.exists(pubkey_path):
|
||||
with open(pubkey_path, 'r') as f:
|
||||
server_public_key = f.read().strip()
|
||||
else:
|
||||
server_public_key = "SERVER_PUBLIC_KEY_PLACEHOLDER"
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not generate public key: {e}")
|
||||
server_public_key = "SERVER_PUBLIC_KEY_PLACEHOLDER"
|
||||
else:
|
||||
server_public_key = "SERVER_PUBLIC_KEY_PLACEHOLDER"
|
||||
|
||||
# Set default endpoint if not found
|
||||
if not server_endpoint:
|
||||
# Try to get the actual server IP
|
||||
server_ip = os.environ.get('WIREGUARD_SERVER_IP')
|
||||
if not server_ip:
|
||||
# Try to get the actual external IP
|
||||
try:
|
||||
import socket
|
||||
import requests
|
||||
# First try to get external IP from a service
|
||||
try:
|
||||
response = requests.get('https://api.ipify.org', timeout=5)
|
||||
if response.status_code == 200:
|
||||
server_ip = response.text.strip()
|
||||
else:
|
||||
raise Exception("Failed to get external IP")
|
||||
except Exception:
|
||||
# Fallback: try to get local IP that's not Docker internal
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||
s.connect(("8.8.8.8", 80))
|
||||
local_ip = s.getsockname()[0]
|
||||
# If it's a Docker internal IP, use localhost for development
|
||||
if local_ip.startswith('172.') or local_ip.startswith('192.168.'):
|
||||
server_ip = "localhost"
|
||||
else:
|
||||
server_ip = local_ip
|
||||
except Exception:
|
||||
# Ultimate fallback to localhost for development
|
||||
server_ip = "localhost"
|
||||
server_endpoint = f"{server_ip}:51820"
|
||||
|
||||
return {
|
||||
'public_key': server_public_key,
|
||||
'endpoint': server_endpoint,
|
||||
'allowed_ips': '0.0.0.0/0'
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Error reading server config: {e}")
|
||||
|
||||
# Return default values
|
||||
return {
|
||||
'public_key': 'SERVER_PUBLIC_KEY_PLACEHOLDER',
|
||||
'endpoint': 'YOUR_SERVER_IP:51820',
|
||||
'allowed_ips': '0.0.0.0/0'
|
||||
}
|
||||
|
||||
def _generate_client_config(self, peer_info: Dict[str, Any], server_config: Dict[str, str]) -> str:
|
||||
"""Generate WireGuard client configuration"""
|
||||
try:
|
||||
# Get peer private key from peer data
|
||||
peer_private_key = peer_info.get('private_key', 'YOUR_PRIVATE_KEY_HERE')
|
||||
|
||||
config = f"""[Interface]
|
||||
PrivateKey = {peer_private_key}
|
||||
Address = {peer_info.get('ip', '10.0.0.2')}/32
|
||||
DNS = 8.8.8.8, 1.1.1.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = {server_config['public_key']}
|
||||
Endpoint = {server_config['endpoint']}
|
||||
AllowedIPs = {server_config['allowed_ips']}
|
||||
PersistentKeepalive = {peer_info.get('persistent_keepalive', 25)}"""
|
||||
|
||||
return config
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating client config: {e}")
|
||||
return None
|
||||
|
||||
def get_server_config(self) -> Dict[str, str]:
|
||||
"""Get server configuration details"""
|
||||
try:
|
||||
# Try to read server config file
|
||||
server_config_path = os.path.join(self.wg_config_dir, 'wg_confs', 'wg0.conf')
|
||||
logger.info(f"Looking for server config at: {server_config_path}")
|
||||
logger.info(f"wg_config_dir is: {self.wg_config_dir}")
|
||||
logger.info(f"File exists: {os.path.exists(server_config_path)}")
|
||||
if os.path.exists(server_config_path):
|
||||
with open(server_config_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Parse server configuration
|
||||
lines = content.strip().split('\n')
|
||||
server_public_key = None
|
||||
server_endpoint = None
|
||||
server_private_key = None
|
||||
|
||||
# Look for server private key and endpoint
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line.startswith('PrivateKey'):
|
||||
server_private_key = line.split('=', 1)[1].strip()
|
||||
logger.info(f"Found server private key: {server_private_key[:10]}...")
|
||||
elif line.startswith('ListenPort'):
|
||||
port = line.split('=', 1)[1].strip()
|
||||
logger.info(f"Found listen port: {port}")
|
||||
# Get server IP from environment or detect it
|
||||
server_ip = os.environ.get('WIREGUARD_SERVER_IP')
|
||||
if not server_ip:
|
||||
# Try to get the actual external IP
|
||||
try:
|
||||
import socket
|
||||
import requests
|
||||
# First try to get external IP from a service
|
||||
try:
|
||||
response = requests.get('https://api.ipify.org', timeout=5)
|
||||
if response.status_code == 200:
|
||||
server_ip = response.text.strip()
|
||||
logger.info(f"Got external IP from service: {server_ip}")
|
||||
else:
|
||||
raise Exception("Failed to get external IP")
|
||||
except Exception:
|
||||
# Fallback: try to get local IP that's not Docker internal
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||
s.connect(("8.8.8.8", 80))
|
||||
local_ip = s.getsockname()[0]
|
||||
# If it's a Docker internal IP, use localhost for development
|
||||
if local_ip.startswith('172.') or local_ip.startswith('192.168.'):
|
||||
server_ip = "localhost"
|
||||
logger.info(f"Using localhost for development (Docker internal IP: {local_ip})")
|
||||
else:
|
||||
server_ip = local_ip
|
||||
logger.info(f"Using local IP: {server_ip}")
|
||||
except Exception:
|
||||
# Ultimate fallback to localhost for development
|
||||
server_ip = "localhost"
|
||||
logger.info("Using localhost as ultimate fallback")
|
||||
server_endpoint = f"{server_ip}:{port}"
|
||||
logger.info(f"Set server endpoint: {server_endpoint}")
|
||||
|
||||
# Generate public key from private key if we have it
|
||||
if server_private_key:
|
||||
try:
|
||||
logger.info("Generating public key from private key...")
|
||||
# Use wg pubkey command to generate public key from private key
|
||||
import subprocess
|
||||
result = subprocess.run(['wg', 'pubkey'],
|
||||
input=server_private_key,
|
||||
capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0:
|
||||
server_public_key = result.stdout.strip()
|
||||
logger.info(f"Generated server public key: {server_public_key[:10]}...")
|
||||
else:
|
||||
# Fallback: try to read from existing public key file
|
||||
pubkey_path = os.path.join(self.wg_config_dir, 'publickey')
|
||||
if os.path.exists(pubkey_path):
|
||||
with open(pubkey_path, 'r') as f:
|
||||
server_public_key = f.read().strip()
|
||||
else:
|
||||
server_public_key = "SERVER_PUBLIC_KEY_PLACEHOLDER"
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not generate public key: {e}")
|
||||
server_public_key = "SERVER_PUBLIC_KEY_PLACEHOLDER"
|
||||
else:
|
||||
server_public_key = "SERVER_PUBLIC_KEY_PLACEHOLDER"
|
||||
|
||||
# Set default endpoint if not found
|
||||
if not server_endpoint:
|
||||
# Try to get the actual server IP
|
||||
server_ip = os.environ.get('WIREGUARD_SERVER_IP')
|
||||
if not server_ip:
|
||||
# Try to get the host IP from Docker network
|
||||
try:
|
||||
import socket
|
||||
# Connect to a remote address to determine local IP
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||
s.connect(("8.8.8.8", 80))
|
||||
server_ip = s.getsockname()[0]
|
||||
except Exception:
|
||||
# Fallback to localhost
|
||||
server_ip = "localhost"
|
||||
server_endpoint = f"{server_ip}:51820"
|
||||
|
||||
return {
|
||||
'public_key': server_public_key,
|
||||
'endpoint': server_endpoint
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Error reading server config: {e}")
|
||||
|
||||
# Return default values
|
||||
return {
|
||||
'public_key': 'SERVER_PUBLIC_KEY_PLACEHOLDER',
|
||||
'endpoint': 'YOUR_SERVER_IP:51820'
|
||||
}
|
||||
Reference in New Issue
Block a user