File size: 6,421 Bytes
ffd513e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import os
import subprocess
import sys

WG_DIR = "/etc/wireguard"
SERVER_PRIVATE = os.path.join(WG_DIR, "privatekey")
SERVER_PUBLIC = os.path.join(WG_DIR, "publickey")
PEER_PRIVATE = os.path.join(WG_DIR, "peer1_privatekey")
PEER_PUBLIC = os.path.join(WG_DIR, "peer1_publickey")


def check_root():
    """Check if running as root"""
    if os.geteuid() != 0:
        print("❌ This script must be run as root (use sudo)")
        sys.exit(1)


def check_wireguard():
    """Check if WireGuard is available"""
    try:
        subprocess.run(["wg", "--version"], check=True, capture_output=True)
        print("✔ WireGuard tools found")
    except (subprocess.CalledProcessError, FileNotFoundError):
        print("❌ WireGuard tools not found. Install with:")
        print("   Amazon Linux: sudo yum install wireguard-tools")
        print("   Ubuntu/Debian: sudo apt install wireguard")
        sys.exit(1)


def load_wireguard_module():
    """Try to load WireGuard kernel module"""
    try:
        subprocess.run(["modprobe", "wireguard"], check=True, capture_output=True)
        print("✔ WireGuard kernel module loaded")
    except subprocess.CalledProcessError:
        print("⚠ Warning: Could not load WireGuard kernel module")
        print("  This might be a container/virtualized environment")
        print("  WireGuard may still work with userspace implementation")


def enable_ip_forwarding():
    """Enable IP forwarding if possible"""
    try:
        # Try to enable IP forwarding
        subprocess.run(["sysctl", "-w", "net.ipv4.ip_forward=1"], 
                      check=True, capture_output=True)
        subprocess.run(["sysctl", "-w", "net.ipv6.conf.all.forwarding=1"], 
                      check=True, capture_output=True)
        print("✔ IP forwarding enabled")
    except subprocess.CalledProcessError:
        print("⚠ Warning: Could not enable IP forwarding")
        print("  This might be a read-only filesystem or container")
        print("  You may need to enable it manually or in the host system")


def generate_keypair(private_path, public_path):
    """Generate WireGuard key pair"""
    try:
        priv = subprocess.check_output(["wg", "genkey"]).decode().strip()
        with open(private_path, "w") as f:
            f.write(priv)
        os.chmod(private_path, 0o600)  # Secure permissions
        
        pub = subprocess.check_output(["wg", "pubkey"], input=priv.encode()).decode().strip()
        with open(public_path, "w") as f:
            f.write(pub)
        os.chmod(public_path, 0o644)
        
        return priv, pub
    except Exception as e:
        print(f"❌ Error generating keypair: {e}")
        sys.exit(1)


def get_public_ip():
    """Auto-detect public IP address"""
    import socket
    import urllib.request
    
    # Try external service first
    try:
        with urllib.request.urlopen('https://api.ipify.org', timeout=5) as response:
            return response.read().decode().strip()
    except Exception:
        pass
    
    # Fallback to local interface IP
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception:
        return "<REPLACE_WITH_YOUR_PUBLIC_IP>"


def create_server_config(server_priv, peer_pub, interface="eth0"):
    """Create server configuration"""
    return f"""[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = {server_priv}
PostUp = iptables -t nat -A POSTROUTING -o {interface} -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o {interface} -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -o wg0 -j ACCEPT

[Peer]
PublicKey = {peer_pub}
AllowedIPs = 10.10.0.2/32"""


def create_peer_config(peer_priv, server_pub, public_ip):
    """Create peer configuration"""
    return f"""[Interface]
PrivateKey = {peer_priv}
Address = 10.10.0.2/24
DNS = 1.1.1.1, 8.8.8.8

[Peer]
PublicKey = {server_pub}
Endpoint = {public_ip}:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25"""


def main():
    print("🔧 WireGuard Configuration Generator")
    print("=" * 40)
    
    # Pre-flight checks
    check_root()
    check_wireguard()
    load_wireguard_module()
    enable_ip_forwarding()
    
    # Create directory
    try:
        os.makedirs(WG_DIR, exist_ok=True)
        print(f"✔ Created directory: {WG_DIR}")
    except Exception as e:
        print(f"❌ Could not create directory {WG_DIR}: {e}")
        sys.exit(1)
    
    # Generate keys
    print("\n🔑 Generating keypairs...")
    server_priv, server_pub = generate_keypair(SERVER_PRIVATE, SERVER_PUBLIC)
    peer_priv, peer_pub = generate_keypair(PEER_PRIVATE, PEER_PUBLIC)
    print("✔ Server and peer keypairs generated")
    
    # Get public IP
    public_ip = get_public_ip()
    print(f"🌐 Detected public IP: {public_ip}")
    
    # Create server config
    server_config = create_server_config(server_priv, peer_pub)
    try:
        with open(os.path.join(WG_DIR, "wg0.conf"), "w") as f:
            f.write(server_config)
        os.chmod(os.path.join(WG_DIR, "wg0.conf"), 0o600)
        print("✔ Server config written to wg0.conf")
    except Exception as e:
        print(f"❌ Error writing server config: {e}")
        sys.exit(1)
    
    # Create peer config
    peer_config = create_peer_config(peer_priv, server_pub, public_ip)
    try:
        with open(os.path.join(WG_DIR, "peer1.conf"), "w") as f:
            f.write(peer_config)
        os.chmod(os.path.join(WG_DIR, "peer1.conf"), 0o600)
        print("✔ Peer config written to peer1.conf")
    except Exception as e:
        print(f"❌ Error writing peer config: {e}")
        sys.exit(1)
    
    print("\n🎉 WireGuard configuration completed!")
    print("\nNext steps:")
    print("1. Start WireGuard: sudo wg-quick up wg0")
    print("2. Enable at boot: sudo systemctl enable wg-quick@wg0")
    print("3. Copy peer1.conf to your client device")
    print("4. Check status: sudo wg show")
    
    if public_ip == "<REPLACE_WITH_YOUR_PUBLIC_IP>":
        print("\n⚠ Warning: Could not detect public IP!")
        print("  Edit peer1.conf and replace the placeholder with your server's public IP")


if __name__ == "__main__":
    main()