def edit_server(data: dict, sess: Session = Depends(middleware.get_db)): interface = data["interface"] old = schemas.WGServer(interface=interface).from_db(sess) # Stop if running if script.wireguard.is_running(old): script.wireguard.stop_interface(old) # Update server server = schemas.WGServer(**data["server"]) server.configuration = script.wireguard.generate_config(server) server = old.update(sess, new=server) # Update peers for peer_data in server.peers: peer = schemas.WGPeer(**peer_data) peer.configuration = script.wireguard.generate_config( dict(peer=peer, server=server)) db_peer = models.WGPeer(**peer.dict()) sess.merge(db_peer) sess.commit() script.wireguard.start_interface(server) server.is_running = script.wireguard.is_running(server) server.sync(sess) # TODO - fix this sync mess. server.from_db(sess) return server
def server_add(server: schemas.WGServerAdd, sess: Session, start=False): # Configure POST UP with defaults if not manually set. if server.post_up == "": server.post_up = const.DEFAULT_POST_UP if server.v6_address is not None: server.post_up += const.DEFAULT_POST_UP_v6 # Configure POST DOWN with defaults if not manually set. if server.post_down == "": server.post_down = const.DEFAULT_POST_DOWN if server.v6_address is not None: server.post_down += const.DEFAULT_POST_DOWN_v6 peers = server.peers if server.peers else [] # Public/Private key try: if sess.query(models.WGServer) \ .filter( (models.WGServer.interface == server.interface) | (models.WGServer.address == server.address) | (models.WGServer.v6_address == server.v6_address)).count() != 0: raise HTTPException(status_code=400, detail="The server interface or ip %s already exists in the database" % server.interface) if not server.private_key: keys = script.wireguard.generate_keys() server.private_key = keys["private_key"] server.public_key = keys["public_key"] server.configuration = script.wireguard.generate_config(server) server.peers = [] server.sync(sess) if len(peers) > 0: server.from_db(sess) for schemaPeer in peers: schemaPeer.server_id = server.id schemaPeer.configuration = script.wireguard.generate_config(dict( peer=schemaPeer, server=server )) dbPeer = models.WGPeer(**schemaPeer.dict()) sess.add(dbPeer) sess.commit() server.from_db(sess) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) if start and not script.wireguard.is_running(server): script.wireguard.start_interface(server) return server
def add_peer( peer_add: schemas.WGPeerConfigAdd, sess: Session = Depends(middleware.get_db) ): server = schemas.WGServer(interface=peer_add.server_interface).from_db(sess) if server is None: raise HTTPException(500, detail="The server-interface '%s' does not exist!" % peer_add.server_interface) peer = schemas.WGPeer(server_id=server.id) if server.v6_address: peer.v6_address = generate_ip_address(server, v6=True) peer.address = generate_ip_address(server, v6=False) # Private public key generation keys = script.wireguard.generate_keys() peer.private_key = keys["private_key"] peer.public_key = keys["public_key"] # Set 0.0.0.0/0, ::/0 as default allowed ips peer.allowed_ips = ', '.join(const.PEER_DEFAULT_ALLOWED_IPS) # Set unnamed peer.name = "Unnamed" if not peer_add.name else peer_add.name peer.dns = server.dns peer.configuration = script.wireguard.generate_config(dict( peer=peer, server=server )) db_peer = models.WGPeer(**peer.dict()) sess.add(db_peer) sess.commit() # If server is running. Add peer if script.wireguard.is_running(server): script.wireguard.add_peer(server, peer) # Update server configuration db.wireguard.server_update_configuration(sess, db_peer.server_id) return schemas.WGPeer.from_orm(db_peer)
def add_interface(server: schemas.WGServerAdd, sess: Session = Depends(middleware.get_db)): server.post_up = server.post_up if server.post_up != "" else const.DEFAULT_POST_UP server.post_down = server.post_up if server.post_up != "" else const.DEFAULT_POST_DOWN peers = server.peers if server.peers else [] # Public/Private key try: if server.filter_query(sess).count() != 0: raise HTTPException( status_code=400, detail="The server interface %s already exists in the database" % server.interface) if not server.private_key: keys = script.wireguard.generate_keys() server.private_key = keys["private_key"] server.public_key = keys["public_key"] server.configuration = script.wireguard.generate_config(server) server.peers = [] server.sync(sess) if len(peers) > 0: server.from_db(sess) for schemaPeer in peers: schemaPeer.server_id = server.id schemaPeer.configuration = script.wireguard.generate_config( dict(peer=schemaPeer, server=server)) dbPeer = models.WGPeer(**schemaPeer.dict()) sess.add(dbPeer) sess.commit() server.from_db(sess) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) return server
def create_client_config(sess: Session, configuration, client_name, client_routes): parser = configparser.ConfigParser() parser.read_string(configuration) public_key = parser["Peer"]["PublicKey"] assert len(set(parser.sections()) - {"Interface", "Peer"}) == 0, "Missing Interface or Peer section" # Parse Server # Check if server already exists. is_new_server = False is_new_peer = False try: db_server = sess.query(models.WGServer).filter_by( public_key=public_key, read_only=1 ).one() except: db_server = None if db_server is None: db_server = models.WGServer() is_new_server = True db_server.read_only = 1 db_server.public_key = parser["Peer"]["PublicKey"] db_server.address = parser["Peer"]["Endpoint"] db_server.listen_port = random.randint(69000, 19292009) db_server.v6_address = "N/A" db_server.v6_subnet = 0 db_server.address = "N/A" db_server.subnet = 0 db_server.private_key = "N/A" db_server.dns = "N/A" db_server.post_up = "N/A" db_server.post_down = "N/A" db_server.is_running = False db_server.configuration = "N/A" # Parse client try: db_peer = sess.query(models.WGPeer).filter_by( private_key=parser["Interface"]["PrivateKey"], read_only=1 ).one() except: db_peer = None if db_peer is None: db_peer = models.WGPeer() is_new_peer = True db_peer.read_only = 1 db_peer.name = client_name addresses_split = parser["Interface"]["Address"].split(",") assert len(addresses_split) > 0, "Must be at least one address" for address_with_subnet in addresses_split: addr, subnet = address_with_subnet.split("/") if isinstance(ipaddress.ip_address(addr), ipaddress.IPv4Address): db_peer.address = address_with_subnet elif isinstance(ipaddress.ip_address(addr), ipaddress.IPv6Address): db_peer.v6_address = address_with_subnet else: raise RuntimeError("Incorrect IP Address: %s, %s" % (addr, subnet)) db_peer.private_key = parser["Interface"]["PrivateKey"] db_peer.public_key = "N/A" db_peer.allowed_ips = client_routes if client_routes else parser["Peer"]["AllowedIPs"] db_peer.configuration = configuration db_server.interface = f"client_{db_peer.name}" db_server.configuration = configuration try: db_peer.shared_key = parser["Interface"]["PrivateKey"] except KeyError: db_peer.shared_key = "N/A" db_peer.dns = parser["Interface"]["DNS"] db_peer.server = db_server if is_new_server: sess.add(db_server) else: sess.merge(db_server) sess.commit() if is_new_peer: sess.add(db_peer) else: sess.merge(db_peer) sess.commit() if const.CLIENT_START_AUTOMATICALLY and not is_running(db_server): start_interface(db_server)