mirror of
https://github.com/Kiritow/wg-ops.git
synced 2024-03-22 13:11:37 +08:00
Back to basics: wg-quick extend comment
This commit is contained in:
parent
4174606921
commit
ea89859850
184
generate.py
Normal file
184
generate.py
Normal file
|
@ -0,0 +1,184 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
filepath = sys.argv[1]
|
||||
|
||||
path_udp2raw = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'bin/udp2raw_amd64')
|
||||
path_w2u = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'bin/w2u')
|
||||
path_gost = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'bin/gost')
|
||||
|
||||
filename = os.path.basename(filepath)
|
||||
wg_name = filename.split('.')[0]
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
content = f.read().split('\n')
|
||||
|
||||
gen_ctx = {
|
||||
'tunnels': {},
|
||||
'post_down': [],
|
||||
}
|
||||
|
||||
results = []
|
||||
|
||||
|
||||
def add_tmux_session_once():
|
||||
if 'has_setup_tmux' not in gen_ctx:
|
||||
gen_ctx['has_setup_tmux'] = True
|
||||
results.append('''PostUp=/usr/bin/tmux new-session -s tunnel-{} -d 'watch -n 1 --color WG_COLOR_MODE=always wg show {}' '''.format(wg_name, wg_name))
|
||||
|
||||
for line in content:
|
||||
if line.startswith('ListenPort'):
|
||||
gen_ctx['wg_port'] = int(line.split('=')[1])
|
||||
if line.startswith('[Peer]'):
|
||||
if 'peer_started' not in gen_ctx:
|
||||
gen_ctx['peer_started'] = True
|
||||
if gen_ctx['post_down']:
|
||||
results.extend(gen_ctx['post_down'])
|
||||
|
||||
if 'has_setup_tmux' in gen_ctx:
|
||||
results.append('PostDown=sleep 1; /usr/bin/tmux kill-session -t tunnel-{}'.format(wg_name))
|
||||
|
||||
if not line.startswith('#'):
|
||||
results.append(line)
|
||||
continue
|
||||
|
||||
if line.startswith('#enable-bbr'):
|
||||
results.append('PostUp=sysctl net.core.default_qdisc=fq\nPostUp=sysctl net.ipv4.tcp_congestion_control=bbr')
|
||||
elif line.startswith('#enable-forward'):
|
||||
results.append('PostUp=sysctl net.ipv4.ip_forward=1')
|
||||
elif line.startswith('#iptables-forward'):
|
||||
results.append('PostUp=iptables -A FORWARD -i {} -j ACCEPT')
|
||||
elif line.startswith('#udp2raw-server'):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
tunnel_port = parts[1]
|
||||
tunnel_passwd = parts[2]
|
||||
|
||||
add_tmux_session_once()
|
||||
|
||||
results.append('''PostUp=/usr/bin/echo -e '-s\\n-l 0.0.0.0:{}\\n-r 127.0.0.1:{}\\n-k {}\\n--raw-mode faketcp\\n--fix-gro\\n-a' > /tmp/temp-udp2raw-{}.conf'''.format(
|
||||
tunnel_port, gen_ctx['wg_port'], tunnel_passwd, tunnel_name
|
||||
))
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -d '{} --conf-file /tmp/temp-udp2raw-{}.conf'; sleep 2'''.format(
|
||||
wg_name, path_udp2raw, tunnel_name
|
||||
))
|
||||
results.append('''PostUp=/usr/bin/rm /tmp/temp-udp2raw-{}.conf'''.format(tunnel_name))
|
||||
elif line.startswith('#udp2raw-client '):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
tunnel_port = parts[1]
|
||||
tunnel_remote = parts[2]
|
||||
tunnel_passwd = parts[3]
|
||||
|
||||
gen_ctx['tunnels'][tunnel_name] = tunnel_port
|
||||
add_tmux_session_once()
|
||||
|
||||
results.append('''PostUp=/usr/bin/echo -e '-c\\n-l 127.0.0.1:{}\\n-r {}\\n-k {}\\n--raw-mode faketcp\\n--fix-gro\\n-a' > /tmp/temp-udp2raw-{}.conf'''.format(
|
||||
tunnel_port, tunnel_remote, tunnel_passwd, tunnel_name
|
||||
))
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -n {}-win -d '{} --conf-file /tmp/temp-udp2raw-{}.conf'; sleep 2'''.format(
|
||||
wg_name, tunnel_name, path_udp2raw, tunnel_name
|
||||
))
|
||||
results.append('''PostUp=/usr/bin/rm /tmp/temp-udp2raw-{}.conf'''.format(tunnel_name))
|
||||
|
||||
gen_ctx['post_down'].append('''PostDown=/usr/bin/tmux send-keys -t {}-win C-c '''.format(tunnel_name))
|
||||
elif line.startswith('#udp2raw-client-mux '):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
tunnel_mux = int(parts[1])
|
||||
tunnel_port = int(parts[2])
|
||||
tunnel_remote = parts[3]
|
||||
tunnel_passwd = parts[4]
|
||||
|
||||
gen_ctx['tunnels'][tunnel_name] = tunnel_port
|
||||
add_tmux_session_once()
|
||||
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -d '{} -f {} -l {} -t {} -s {}' '''.format(
|
||||
wg_name, path_w2u, gen_ctx['wg_port'], tunnel_port, tunnel_port + 1, tunnel_mux
|
||||
))
|
||||
for mux_idx in range(tunnel_mux):
|
||||
results.append('''PostUp=/usr/bin/echo -e '-c\\n-l 127.0.0.1:{}\\n-r {}\\n-k {}\\n--raw-mode faketcp\\n--fix-gro\\n-a' > /tmp/temp-udp2raw-{}-{}.conf'''.format(
|
||||
tunnel_port + 1 + mux_idx, tunnel_remote, tunnel_passwd, tunnel_name, mux_idx
|
||||
))
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -n {}-win-{} -d '{} --conf-file /tmp/temp-udp2raw-{}-{}.conf'; sleep 2'''.format(
|
||||
wg_name, tunnel_name, mux_idx, path_udp2raw, tunnel_name, mux_idx
|
||||
))
|
||||
results.append('''PostUp=/usr/bin/rm /tmp/temp-udp2raw-{}-{}.conf'''.format(tunnel_name, mux_idx))
|
||||
|
||||
gen_ctx['post_down'].append('''PostDown=/usr/bin/tmux send-keys -t {}-win-{} C-c '''.format(tunnel_name, mux_idx))
|
||||
|
||||
elif line.startswith('#gost-server '):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
tunnel_port = parts[1]
|
||||
|
||||
add_tmux_session_once()
|
||||
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -d '{} -L=relay+tls://:{}/127.0.0.1:{}' '''.format(
|
||||
wg_name, path_gost, tunnel_port, gen_ctx['wg_port']
|
||||
))
|
||||
elif line.startswith('#gost-client '):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
tunnel_port = parts[1]
|
||||
tunnel_remote = parts[2]
|
||||
|
||||
gen_ctx['tunnels'][tunnel_name] = tunnel_port
|
||||
add_tmux_session_once()
|
||||
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -d '{} -L udp://:{} -F relay+tls://{}' '''.format(
|
||||
wg_name, path_gost, tunnel_port, tunnel_remote
|
||||
))
|
||||
elif line.startswith('#gost-client-mux '):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
tunnel_mux = int(parts[1])
|
||||
tunnel_port = int(parts[2])
|
||||
tunnel_remote = parts[3]
|
||||
|
||||
gen_ctx['tunnels'][tunnel_name] = tunnel_port
|
||||
add_tmux_session_once()
|
||||
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -d '{} -f {} -l {} -t {} -s {}' '''.format(
|
||||
wg_name, path_w2u, gen_ctx['wg_port'], tunnel_port, tunnel_port + 1, tunnel_mux
|
||||
))
|
||||
for mux_idx in range(tunnel_mux):
|
||||
results.append('''PostUp=/usr/bin/tmux new-window -t tunnel-{} -d '{} -L udp://:{} -F relay+tls://{}' '''.format(
|
||||
wg_name, path_gost, tunnel_port + 1 + mux_idx, tunnel_remote
|
||||
))
|
||||
elif line.startswith('#use-tunnel'):
|
||||
parts = line.split(' ')[1:]
|
||||
tunnel_name = parts[0]
|
||||
|
||||
tunnel_port = gen_ctx['tunnels'][tunnel_name]
|
||||
results.append('Endpoint=127.0.0.1:{}'.format(tunnel_port))
|
||||
elif line.startswith('#route'):
|
||||
parts = line.split(' ')[1:]
|
||||
route_target = parts[0]
|
||||
|
||||
if 'disable_table' not in gen_ctx:
|
||||
gen_ctx['disable_table'] = True
|
||||
results.insert(1, 'Table=off')
|
||||
|
||||
# find last post-up
|
||||
prev_postup = False
|
||||
last_postup_idx = 0
|
||||
for i in range(len(results)):
|
||||
if results[i].startswith('PostUp='):
|
||||
prev_postup = True
|
||||
continue
|
||||
if prev_postup:
|
||||
last_postup_idx = i
|
||||
break
|
||||
if not last_postup_idx:
|
||||
results.append('PostUp=ip -4 route add {} dev wg0'.format(route_target))
|
||||
else:
|
||||
results.insert(last_postup_idx, 'PostUp=ip -4 route add {} dev wg0'.format(route_target))
|
||||
else:
|
||||
print('[WARN] comment or unknown hint: {}'.format(line))
|
||||
|
||||
|
||||
with open('{}.gen'.format(filename), 'w') as f:
|
||||
f.write('# Generated by wg-ops at {}. DO NOT EDIT\n'.format(time.strftime("%Y-%m-%d %H:%M:%S")))
|
||||
f.write('\n'.join(results))
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
export WG_MYPRIK=$(wg genkey)
|
||||
export WG_MYPUBK=$(echo $WG_MYPRIK | wg pubkey)
|
||||
|
||||
export TMUX_PATH=$(which tmux)
|
||||
|
||||
python3 wgop_quick_client.py
|
||||
python3 wgop_generate.py
|
||||
|
||||
chmod +x start.sh
|
||||
chmod +x stop.sh
|
||||
chmod +x restart.sh
|
||||
chmod +x reload.sh
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo 'Detecting Public IP address...'
|
||||
export WG_PUBLICIP=$(curl ident.me)
|
||||
|
||||
python3 wgop_display.py
|
175
wgop_common.py
175
wgop_common.py
|
@ -1,175 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import json
|
||||
import traceback
|
||||
import base64
|
||||
import hashlib
|
||||
import random
|
||||
import string
|
||||
|
||||
|
||||
# Constants
|
||||
WGOP_USPEEDER_S_PBEGIN = 27100
|
||||
WGOP_USPEEDER_C_PBEGIN = 28100
|
||||
WGOP_LB_PBEGIN = 29000
|
||||
WGOP_UC_PBEGIN = 29100
|
||||
|
||||
class SimpleLogger(object):
|
||||
def __init__(self, name=None, filename=None, fileonly=False,
|
||||
level=logging.INFO,
|
||||
default_encoding='utf-8',
|
||||
log_format="%(asctime)s @%(module)s [%(levelname)s] %(funcName)s: %(message)s"):
|
||||
if name is None:
|
||||
name = __name__
|
||||
|
||||
if not filename and fileonly:
|
||||
raise Exception("FileOnly=True but no filename provided.")
|
||||
|
||||
self.logger = logging.getLogger(name)
|
||||
if not getattr(self.logger, "_is_configured", None):
|
||||
formatter = logging.Formatter(log_format)
|
||||
if not fileonly:
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(formatter)
|
||||
self.logger.addHandler(console_handler)
|
||||
if filename is not None:
|
||||
file_handler = logging.FileHandler(filename, encoding=default_encoding)
|
||||
file_handler.setFormatter(formatter)
|
||||
self.logger.addHandler(file_handler)
|
||||
self.logger.setLevel(level)
|
||||
setattr(self.logger, "_is_configured", True)
|
||||
|
||||
# Just acts as a logger
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.logger, name)
|
||||
|
||||
|
||||
logger = SimpleLogger()
|
||||
|
||||
|
||||
def load_config(filename=None):
|
||||
config_filename = filename or "local/config.json"
|
||||
try:
|
||||
with open(config_filename) as f:
|
||||
return json.loads(f.read())
|
||||
except Exception:
|
||||
logger.error("Unable to load config: {}".format(traceback.format_exc()))
|
||||
return {}
|
||||
|
||||
|
||||
def save_config(config, filename=None):
|
||||
config_filename = filename or "local/config.json"
|
||||
content = json.dumps(config, ensure_ascii=False, default=str, indent=2)
|
||||
try:
|
||||
with open(config_filename, "w", encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
except Exception:
|
||||
logger.error("Unable to save config: {}".format(traceback.format_exc()))
|
||||
logger.info("Config:\n{}".format(content))
|
||||
|
||||
|
||||
def json_to_base64(content):
|
||||
return base64.b64encode(json.dumps(content, ensure_ascii=False).encode('utf-8')).decode('utf-8')
|
||||
|
||||
|
||||
def base64_to_json(content):
|
||||
return json.loads(base64.b64decode(content).decode('utf-8'))
|
||||
|
||||
|
||||
def get_sha256(content):
|
||||
return hashlib.sha256(content.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
def get_randpass(length):
|
||||
return ''.join(random.choices(string.ascii_uppercase, k=2) + random.choices(string.ascii_lowercase + string.ascii_uppercase + string.digits, k=length - 2))
|
||||
|
||||
|
||||
def get_quick_config(config, server_public_ip):
|
||||
if config["ip"].endswith(".1"):
|
||||
suggest_allowed = "{}.0/24".format('.'.join(config["ip"].split('.')[:-1]))
|
||||
else:
|
||||
suggest_allowed = config["ip"]
|
||||
|
||||
quicks = []
|
||||
|
||||
for server_info in config["udp2raw"]["server"]:
|
||||
speeder_info = server_info["speeder"]
|
||||
|
||||
quick_config = {
|
||||
"pubkey": config["pubkey"],
|
||||
"allowed": suggest_allowed,
|
||||
"remote": "{}:{}".format(server_public_ip, server_info["port"]),
|
||||
"password": server_info["password"],
|
||||
"ratio": speeder_info["ratio"] if speeder_info else None
|
||||
}
|
||||
|
||||
quicks.append({
|
||||
"port": server_info["port"],
|
||||
"qcs": "#QCS#{}".format(json_to_base64(quick_config))
|
||||
})
|
||||
|
||||
return quicks
|
||||
|
||||
|
||||
class UConfigController:
|
||||
next_port_speeder_server = WGOP_USPEEDER_S_PBEGIN
|
||||
next_port_speeder_client = WGOP_USPEEDER_C_PBEGIN
|
||||
next_port_balancer = WGOP_LB_PBEGIN
|
||||
next_port_client = WGOP_UC_PBEGIN
|
||||
udp2raw_config = {
|
||||
"server": [],
|
||||
"client": []
|
||||
}
|
||||
|
||||
def add_server(self, port_required, password, speeder_info):
|
||||
self.udp2raw_config["server"].append({
|
||||
"port": port_required,
|
||||
"password": get_sha256(password),
|
||||
"speeder": speeder_info
|
||||
})
|
||||
|
||||
def add_client(self, remote, password, port, speeder_info, demuxer_info, no_hash=False):
|
||||
if port is None:
|
||||
port = self.next_port_client
|
||||
if demuxer_info:
|
||||
self.next_port_client += demuxer_info["size"]
|
||||
else:
|
||||
self.next_port_client += 1
|
||||
|
||||
self.udp2raw_config["client"].append({
|
||||
"remote": remote,
|
||||
"password": password if no_hash else get_sha256(password),
|
||||
"port": port,
|
||||
"speeder": speeder_info,
|
||||
"demuxer": demuxer_info
|
||||
})
|
||||
|
||||
def new_server_speeder(self, port, ratio):
|
||||
if port is None:
|
||||
port = self.next_port_speeder_server
|
||||
self.next_port_speeder_server += 1
|
||||
|
||||
return {
|
||||
"port": port,
|
||||
"ratio": ratio
|
||||
}
|
||||
|
||||
def new_client_speeder(self, port, ratio):
|
||||
if port is None:
|
||||
port = self.next_port_speeder_client
|
||||
self.next_port_speeder_client += 1
|
||||
|
||||
return {
|
||||
"port": port,
|
||||
"ratio": ratio
|
||||
}
|
||||
|
||||
def new_demuxer(self, port, size):
|
||||
if port is None:
|
||||
port = self.next_port_balancer
|
||||
self.next_port_balancer += 1
|
||||
|
||||
return {
|
||||
"port": port,
|
||||
"size": size
|
||||
}
|
220
wgop_create.py
220
wgop_create.py
|
@ -1,220 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import getpass
|
||||
from wgop_common import load_config, save_config, get_randpass, get_quick_config
|
||||
from wgop_common import UConfigController
|
||||
|
||||
|
||||
config = load_config()
|
||||
if config:
|
||||
print("Valid config found. Creation of server is skipped.")
|
||||
exit(0)
|
||||
else:
|
||||
print("No config found. Start creating interactively.")
|
||||
|
||||
print("====== Choose Role ======")
|
||||
|
||||
op_mode = input("What will this node act as? (C)lient [S]erver [M]ixed: ").strip().lower()
|
||||
if not op_mode:
|
||||
print("Default to client mode.")
|
||||
op_mode = "c"
|
||||
|
||||
if op_mode not in ("c", "s", "m"):
|
||||
print("Invalid node mode. Please try again.")
|
||||
exit(1)
|
||||
|
||||
|
||||
ucontrol = UConfigController()
|
||||
|
||||
|
||||
if op_mode in ("s", "m"):
|
||||
print("====== Configuring udp2raw server ======")
|
||||
|
||||
while True:
|
||||
print("====== Adding UDP2RAW Server #{} ======".format(len(ucontrol.udp2raw_config["server"]) + 1))
|
||||
|
||||
while True:
|
||||
udp_server_port = input("Please select an Internet-Facing port for incoming udp2raw connection: ").strip()
|
||||
if not udp_server_port:
|
||||
print("A udp2raw listen port is required. Try again.")
|
||||
continue
|
||||
break
|
||||
|
||||
while True:
|
||||
udp_server_password = getpass.getpass('Tunnel Password: (Keep empty to generate one)').strip()
|
||||
if not udp_server_password:
|
||||
udp_server_password = get_randpass(15)
|
||||
print("Generated Password: {}".format(udp_server_password))
|
||||
break
|
||||
|
||||
if udp_server_password != getpass.getpass('Confirm Tunnel Password: ').strip():
|
||||
print("Password mismatch. Try again.")
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
is_enable_speeder = input("Enable UDP Speeder for this tunnel? [y/N]: ").strip()
|
||||
if is_enable_speeder and is_enable_speeder.lower() in ('y', 'yes'):
|
||||
speeder_ratio = input("Enter UDP Speeder Ratio (default to 20:10. Use 2:4 for gaming usage): ").strip() or "20:10"
|
||||
speeder_info = ucontrol.new_server_speeder(None, speeder_ratio)
|
||||
else:
|
||||
speeder_info = None
|
||||
|
||||
ucontrol.add_server(udp_server_port, udp_server_password, speeder_info)
|
||||
|
||||
if not input("Add more udp2raw server? (Keep empty to finish): ").strip():
|
||||
break
|
||||
|
||||
|
||||
if op_mode in ("c", "m"):
|
||||
print("====== Configuring udp2raw client ======")
|
||||
|
||||
while True:
|
||||
print("====== Adding UDP2RAW Client {} ======".format(len(ucontrol.udp2raw_config["client"]) + 1))
|
||||
|
||||
while True:
|
||||
udp_server_address = input("Please input remote node internet-facing udp2raw ip:port : ").strip()
|
||||
if not udp_server_address:
|
||||
print("A udp2raw remote server information is required. Try again.")
|
||||
continue
|
||||
break
|
||||
|
||||
while True:
|
||||
udp_server_password = getpass.getpass('Tunnel Password: ').strip()
|
||||
if not udp_server_password:
|
||||
print("A udp2raw tunnel password is required. Try again.")
|
||||
continue
|
||||
|
||||
if udp_server_password != getpass.getpass('Confirm Tunnel Password: ').strip():
|
||||
print("Password mismatch. Try again.")
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
is_enable_speeder = input("Enable UDP Speeder for this tunnel? [y/N]: ").strip()
|
||||
if is_enable_speeder and is_enable_speeder.lower() in ('y', 'yes'):
|
||||
speeder_ratio = input("Enter UDP Speeder Ratio (default to 20:10. Use 2:4 for gaming usage): ").strip() or "20:10"
|
||||
speeder_info = ucontrol.new_client_speeder(None, speeder_ratio)
|
||||
else:
|
||||
speeder_info = None
|
||||
|
||||
is_enable_balance = input("Enable Load Balance? [y/N]: ").strip()
|
||||
if is_enable_balance and is_enable_balance.lower() in ('y', 'yes'):
|
||||
balance_count = input("Enter Balance Underlay Connection counts (default to 10): ").strip() or "10"
|
||||
balance_count = int(balance_count)
|
||||
|
||||
if balance_count > 1:
|
||||
balancer_info = ucontrol.new_demuxer(None, balance_count)
|
||||
else:
|
||||
print("[WARN] Only one target, skipped balancer creation.")
|
||||
balancer_info = None
|
||||
else:
|
||||
balancer_info = None
|
||||
|
||||
ucontrol.add_client(udp_server_address, udp_server_password, None, speeder_info, balancer_info)
|
||||
|
||||
if not input("Add more udp2raw client? (Keep empty to finish)").strip():
|
||||
break
|
||||
|
||||
|
||||
wg_prik = os.getenv("WG_MYPRIK")
|
||||
wg_pubk = os.getenv("WG_MYPUBK")
|
||||
wg_mtu = "1000"
|
||||
wg_public_ip = os.getenv("WG_PUBLICIP")
|
||||
|
||||
print('''
|
||||
|
||||
====== Your WireGuard Public Key ======
|
||||
|
||||
{}
|
||||
|
||||
======= Your Public IP Address ========
|
||||
|
||||
{}
|
||||
|
||||
=======================================
|
||||
|
||||
'''.format(wg_pubk, wg_public_ip))
|
||||
|
||||
ifname = input("Input new WireGuard interface name (wg0):").strip() or "wg0"
|
||||
listen_port = input("Input new WireGuard listen port (51820): ").strip() or "51820"
|
||||
while True:
|
||||
ifip = input("Input WireGuard interface ip (Example: 10.0.0.1)\n> ").strip()
|
||||
if not ifip:
|
||||
print("You MUST set a valid WireGuard interface IP. Try Again.")
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
print("Saving config...")
|
||||
config = {
|
||||
"version": 1,
|
||||
"mode": op_mode,
|
||||
"pubkey": wg_pubk,
|
||||
"prikey": wg_prik,
|
||||
"mtu": wg_mtu,
|
||||
"interface": ifname,
|
||||
"ip": ifip,
|
||||
"listen": listen_port,
|
||||
"peers": [],
|
||||
"udp2raw": ucontrol.udp2raw_config
|
||||
}
|
||||
save_config(config)
|
||||
|
||||
|
||||
# Display Quick Config
|
||||
if op_mode in ("s", "m"):
|
||||
print("===== Quick Import =====")
|
||||
quicks = get_quick_config(config, wg_public_ip)
|
||||
for quick_info in quicks:
|
||||
print("Connect to this server via tunnel at port {}: (credential included)\n{}\n".format(quick_info["port"], quick_info["qcs"]))
|
||||
|
||||
|
||||
# Configure Peer
|
||||
while True:
|
||||
print("====== Adding Peer {} ======".format(len(config["peers"]) + 1))
|
||||
while True:
|
||||
peer_pubk = input("Enter WireGuard Peer Public Key: ").strip()
|
||||
if not peer_pubk:
|
||||
print("A public key is required. Try Again.")
|
||||
continue
|
||||
break
|
||||
while True:
|
||||
peer_allowed = input("Enter WireGuard Peer AllowedIPs (CIDR, Example: 10.0.0.0/24)\n> ").strip()
|
||||
if not peer_allowed:
|
||||
print("Peer allowed ips required. Try Again.")
|
||||
continue
|
||||
break
|
||||
|
||||
if ucontrol.udp2raw_config["client"]:
|
||||
print(">>> Choose from following udp2raw clients <<<")
|
||||
for index, client_info in enumerate(ucontrol.udp2raw_config["client"]):
|
||||
speeder_info = client_info["speeder"]
|
||||
balancer_info = client_info["demuxer"]
|
||||
|
||||
print("[{}] {} {} {}".format(index + 1, client_info["remote"],
|
||||
"SpeederRatio: {}".format(speeder_info["ratio"]) if speeder_info else "",
|
||||
"Load-Balanced over {} tunnels".format(balancer_info["size"]) if balancer_info else ""
|
||||
))
|
||||
|
||||
peer_endpoint = input("Enter WireGuard Peer Endpoint (ID from list, default to 1): ").strip() or "1"
|
||||
peer_keepalive = input("Enter WireGuard Peer Keep Alive seconds (default to 30): ").strip() or "30"
|
||||
else:
|
||||
peer_endpoint = ""
|
||||
peer_keepalive = ""
|
||||
|
||||
peer_name = input("Enter Peer name (optional): ").strip() or ""
|
||||
|
||||
config["peers"].append({
|
||||
"pubkey": peer_pubk,
|
||||
"allowed": peer_allowed,
|
||||
"endpoint": peer_endpoint,
|
||||
"keepalive": peer_keepalive,
|
||||
"name": peer_name,
|
||||
})
|
||||
|
||||
print("Saving config...")
|
||||
save_config(config)
|
||||
|
||||
if not input("Add more peers? (Keep empty to finish)").strip():
|
||||
break
|
|
@ -1,19 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from wgop_common import load_config, get_quick_config
|
||||
|
||||
|
||||
config = load_config()
|
||||
if not config:
|
||||
print("[WARN] Config not found.")
|
||||
exit(1)
|
||||
|
||||
|
||||
quicks = get_quick_config(config, os.getenv("WG_PUBLICIP"))
|
||||
if not quicks:
|
||||
print("No server configured.")
|
||||
exit(0)
|
||||
|
||||
print("===== Quick Import =====")
|
||||
for quick_info in quicks:
|
||||
print("Connect to this server via tunnel at port {}: (credential included)\n{}\n".format(quick_info["port"], quick_info["qcs"]))
|
195
wgop_generate.py
195
wgop_generate.py
|
@ -1,195 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import uuid
|
||||
from wgop_common import load_config, SimpleLogger
|
||||
|
||||
|
||||
logger = SimpleLogger()
|
||||
|
||||
|
||||
def write_tunnel_config(mode, listen_addr, remote_addr, password):
|
||||
filename = "{}.conf".format(uuid.uuid4())
|
||||
with open("local/tunnel/{}".format(filename), "w", encoding='utf-8') as f:
|
||||
f.write('''
|
||||
-{}
|
||||
-l {}
|
||||
-r {}
|
||||
-k {}
|
||||
--raw-mode faketcp
|
||||
--fix-gro
|
||||
-a
|
||||
'''.format(mode, listen_addr, remote_addr, password))
|
||||
return filename
|
||||
|
||||
|
||||
tmux_path = os.getenv("TMUX_PATH")
|
||||
|
||||
config = load_config()
|
||||
if not config:
|
||||
logger.error("No valid config found.")
|
||||
exit(1)
|
||||
|
||||
|
||||
if "version" not in config or int(config["version"]) < 1:
|
||||
logger.warn("[WARN] Legacy version of config found. This may cause issues.")
|
||||
|
||||
|
||||
op_mode = config["mode"]
|
||||
udp_clients = config["udp2raw"]["client"]
|
||||
udp_servers = config["udp2raw"]["server"]
|
||||
|
||||
|
||||
logger.info("Generating WireGuard config...")
|
||||
with open("local/{}.conf".format(config["interface"]), "w", encoding='utf-8') as f:
|
||||
f.write('''[Interface]
|
||||
Address = {}
|
||||
PrivateKey = {}
|
||||
ListenPort = {}
|
||||
MTU = {}
|
||||
'''.format(config["ip"], config["prikey"], config["listen"], config["mtu"]))
|
||||
|
||||
# Generate PostUp
|
||||
f.write('''PostUp={} new-session -s tunnel -d 'watch -n 1 --color WG_COLOR_MODE=always wg'
|
||||
PostUp=sysctl net.core.default_qdisc=fq
|
||||
PostUp=sysctl net.ipv4.tcp_congestion_control=bbr
|
||||
'''.format(tmux_path))
|
||||
|
||||
if op_mode in ("s", "m"):
|
||||
f.write("PostUp=sysctl net.ipv4.ip_forward=1\n")
|
||||
|
||||
current_dir = os.getcwd()
|
||||
bin_tunnel = os.path.join(current_dir, "bin", "udp2raw_amd64")
|
||||
bin_speeder = os.path.join(current_dir, "bin", "speederv2_amd64")
|
||||
bin_demuxer = os.path.join(current_dir, "bin", "w2u")
|
||||
|
||||
cache_nb_config = []
|
||||
cache_config = []
|
||||
for client_info in udp_clients:
|
||||
speeder_info = client_info["speeder"]
|
||||
balancer_info = client_info["demuxer"]
|
||||
|
||||
if balancer_info:
|
||||
# ... => Balancer => Tunnels
|
||||
cache_nb_config.append("PostUp={} new-window -t tunnel -d '{} -f {} -l {} -t {} -s {}'".format(tmux_path, bin_demuxer, config["listen"], balancer_info["port"], client_info["port"], balancer_info["size"]))
|
||||
|
||||
if speeder_info:
|
||||
if balancer_info:
|
||||
# WG => Speeder => Balancer => Tunnels
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} -c -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0'".format(tmux_path, bin_speeder, speeder_info["port"], balancer_info["port"], speeder_info["ratio"]))
|
||||
else:
|
||||
# WG => Speeder => Tunnel
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} -c -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0'".format(tmux_path, bin_speeder, speeder_info["port"], client_info["port"], speeder_info["ratio"]))
|
||||
|
||||
if balancer_info:
|
||||
# Generate multiple tunnels
|
||||
for offset in range(balancer_info["size"]):
|
||||
config_filename = write_tunnel_config("c", "127.0.0.1:{}".format(client_info["port"] + offset), client_info["remote"], client_info["password"])
|
||||
filepath = os.path.join(current_dir, "local", "tunnel", config_filename)
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} --conf-file {}'".format(tmux_path, bin_tunnel, filepath))
|
||||
else:
|
||||
config_filename = write_tunnel_config("c", "127.0.0.1:{}".format(client_info["port"]), client_info["remote"], client_info["password"])
|
||||
filepath = os.path.join(current_dir, "local", "tunnel", config_filename)
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} --conf-file {}'".format(tmux_path, bin_tunnel, filepath))
|
||||
|
||||
for server_info in udp_servers:
|
||||
speeder_info = server_info["speeder"]
|
||||
|
||||
if speeder_info:
|
||||
# RawTunnel => Speeder => WG
|
||||
speeder = server_info["speeder"]
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} -s -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0'".format(tmux_path, bin_speeder, speeder["port"], config["listen"], speeder["ratio"]))
|
||||
|
||||
config_filename = write_tunnel_config("s", "0.0.0.0:{}".format(server_info["port"]), "127.0.0.1:{}".format(speeder["port"]), server_info["password"])
|
||||
filepath = os.path.join(current_dir, "local", "tunnel", config_filename)
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} --conf-file {}'".format(tmux_path, bin_tunnel, filepath))
|
||||
else:
|
||||
# RawTunnel => WG
|
||||
config_filename = write_tunnel_config("s", "0.0.0.0:{}".format(server_info["port"]), "127.0.0.1:{}".format(config["listen"]), server_info["password"])
|
||||
filepath = os.path.join(current_dir, "local", "tunnel", config_filename)
|
||||
cache_config.append("PostUp={} new-window -t tunnel -d '{} --conf-file {}'".format(tmux_path, bin_tunnel, filepath))
|
||||
|
||||
# Add sleep interval
|
||||
if cache_config:
|
||||
for i in range(len(cache_config) - 1):
|
||||
cache_config[i] = "{}; sleep 2".format(cache_config[i])
|
||||
cache_config.append("")
|
||||
f.write('\n'.join(cache_config))
|
||||
|
||||
if cache_nb_config:
|
||||
cache_nb_config.append("")
|
||||
f.write('\n'.join(cache_nb_config))
|
||||
|
||||
# Generate PostDown
|
||||
f.write("PostDown={} kill-session -t tunnel\n".format(tmux_path))
|
||||
|
||||
for peer_info in config["peers"]:
|
||||
f.write('''
|
||||
[Peer]
|
||||
PublicKey = {}
|
||||
AllowedIPs = {}
|
||||
'''.format(peer_info["pubkey"], peer_info["allowed"]))
|
||||
if peer_info["endpoint"]:
|
||||
client_info = udp_clients[int(peer_info["endpoint"]) - 1]
|
||||
speeder_info = client_info["speeder"]
|
||||
balancer_info = client_info["demuxer"]
|
||||
|
||||
if speeder_info:
|
||||
# WG => Speeder => ...
|
||||
f.write("Endpoint = 127.0.0.1:{}\n".format(speeder_info["port"]))
|
||||
elif balancer_info:
|
||||
# WG => Balancer => ...
|
||||
f.write("Endpoint = 127.0.0.1:{}\n".format(balancer_info["port"]))
|
||||
else:
|
||||
# WG => ...
|
||||
f.write("Endpoint = 127.0.0.1:{}\n".format(client_info["port"]))
|
||||
|
||||
if peer_info["keepalive"]:
|
||||
f.write("PersistentKeepalive = {}\n".format(peer_info["keepalive"]))
|
||||
|
||||
os.system("chmod 600 local/{}.conf".format(config["interface"]))
|
||||
|
||||
logger.info("Generating start script...")
|
||||
with open("start.sh", "w", encoding='utf-8') as f:
|
||||
f.write('''#!/bin/bash
|
||||
set -e
|
||||
|
||||
sudo cp local/{}.conf /etc/wireguard/
|
||||
sudo wg-quick up {}
|
||||
sudo tmux attach-session -t tunnel
|
||||
'''.format(config["interface"], config["interface"]))
|
||||
|
||||
|
||||
logger.info("Generating stop script...")
|
||||
with open("stop.sh", "w", encoding='utf-8') as f:
|
||||
f.write('''#!/bin/bash
|
||||
set -x
|
||||
sudo wg-quick down {}
|
||||
'''.format(config["interface"]))
|
||||
|
||||
|
||||
logger.info("Generating restart script...")
|
||||
with open("restart.sh", "w", encoding='utf-8') as f:
|
||||
f.write('''#!/bin/bash
|
||||
set -x
|
||||
./stop.sh
|
||||
./start.sh
|
||||
''')
|
||||
|
||||
logger.info("Generate reload script...")
|
||||
with open("reload.sh", "w", encoding='utf-8') as f:
|
||||
f.write('''#!/bin/bash
|
||||
set -x
|
||||
sudo cp local/{}.conf /etc/wireguard/
|
||||
sudo -- bash -c "wg syncconf {} <(wg-quick strip {})"
|
||||
'''.format(config["interface"], config["interface"], config["interface"]))
|
||||
|
||||
for peer_info in config["peers"]:
|
||||
f.write("sudo ip -4 route add {} dev {}\n".format(peer_info["allowed"], config["interface"]))
|
||||
|
||||
|
||||
logger.info('''[Done] Config generated. Before you run start.sh, besure to:
|
||||
1. Disable SSH Server password login.
|
||||
2. Enable UFW (or any other firewall)
|
||||
|
||||
Safety First.
|
||||
''')
|
|
@ -1,114 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from wgop_common import load_config, save_config, base64_to_json
|
||||
from wgop_common import UConfigController
|
||||
|
||||
|
||||
config = load_config()
|
||||
|
||||
if config:
|
||||
print("Valid config found. Creation of server is skipped.")
|
||||
exit(0)
|
||||
|
||||
|
||||
print("No valid config found, creating a default one...")
|
||||
|
||||
ifname = input("Input new WireGuard interface name (wg0): ").strip() or "wg0"
|
||||
listen_port = input("Input new WireGuard listen port (51820): ").strip() or "51820"
|
||||
while True:
|
||||
ifip = input("Input WireGuard interface ip (Example: 10.0.0.1)\n> ").strip()
|
||||
if not ifip:
|
||||
print("You MUST set a valid WireGuard interface IP. Try Again.")
|
||||
continue
|
||||
break
|
||||
|
||||
ucontrol = UConfigController()
|
||||
|
||||
paste_config = {}
|
||||
while True:
|
||||
paste_temp = input("Paste Quick Setup: ").strip()
|
||||
if not paste_temp.startswith("#QCS#"):
|
||||
print("Config not valid. Try again.")
|
||||
continue
|
||||
|
||||
paste_config = base64_to_json(paste_temp.replace("#QCS#", ""))
|
||||
print("Config imported. Server: {} with public key: {}{}".format(
|
||||
paste_config["remote"], paste_config["pubkey"],
|
||||
" and speeders enabled" if paste_config["ratio"] else ""))
|
||||
break
|
||||
|
||||
|
||||
if paste_config["ratio"]:
|
||||
speeder_info = ucontrol.new_client_speeder(None, paste_config["ratio"])
|
||||
else:
|
||||
speeder_info = None
|
||||
|
||||
|
||||
is_enable_balance = input("Enable Load Balance? [y/N]: ").strip()
|
||||
if is_enable_balance and is_enable_balance.lower() in ('y', 'yes'):
|
||||
balance_count = input("Enter Balance Underlay Connection counts (default to 10): ").strip() or "10"
|
||||
balance_count = int(balance_count)
|
||||
|
||||
if balance_count > 1:
|
||||
balancer_info = ucontrol.new_demuxer(None, balance_count)
|
||||
else:
|
||||
print("[WARN] Only one target, skipped balancer creation.")
|
||||
balancer_info = None
|
||||
else:
|
||||
balancer_info = None
|
||||
|
||||
|
||||
ucontrol.add_client(paste_config["remote"], paste_config["password"], None, speeder_info, balancer_info, no_hash=True)
|
||||
|
||||
|
||||
if paste_config["allowed"]:
|
||||
peer_allowed = input("Enter WireGuard Peer AllowedIPs (CIDR, Example: 10.0.0.0/24, default to {})\n> ".format(paste_config["allowed"])).strip()
|
||||
if not peer_allowed:
|
||||
peer_allowed = paste_config["allowed"]
|
||||
else:
|
||||
while True:
|
||||
peer_allowed = input("Enter WireGuard Peer AllowedIPs (CIDR, Example: 10.0.0.0/24)\n> ").strip()
|
||||
if not peer_allowed:
|
||||
print("Peer allowed ips required. Try Again.")
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
peer_keepalive = input("Enter WireGuard Peer Keep Alive seconds (default to 30): ").strip() or "30"
|
||||
|
||||
|
||||
# Generate Config
|
||||
config = {
|
||||
"version": 1,
|
||||
"mode": "c",
|
||||
"prikey": os.getenv("WG_MYPRIK"),
|
||||
"pubkey": os.getenv("WG_MYPUBK"),
|
||||
"mtu": "1000",
|
||||
"interface": ifname,
|
||||
"ip": ifip,
|
||||
"listen": listen_port,
|
||||
"peers": [{
|
||||
"pubkey": paste_config["pubkey"],
|
||||
"allowed": peer_allowed,
|
||||
"endpoint": "1",
|
||||
"keepalive": peer_keepalive
|
||||
}],
|
||||
"udp2raw": ucontrol.udp2raw_config
|
||||
}
|
||||
|
||||
print("Saving config...")
|
||||
save_config(config)
|
||||
|
||||
print('''
|
||||
|
||||
====== Your WireGuard Public Key ======
|
||||
|
||||
{}
|
||||
|
||||
====== Your WireGuard IP Address ======
|
||||
|
||||
{}
|
||||
|
||||
=======================================
|
||||
|
||||
'''.format(os.getenv("WG_MYPUBK"), ifip))
|
Loading…
Reference in New Issue
Block a user