def iptables_runner( port_id: int, server_id: int, local_port: int, remote_address: str, remote_port: int = None, forward_type: str = None, update_status: bool = False, ): try: if not is_ip(remote_address): remote_ip = dns_query(remote_address) else: remote_ip = remote_address with db_session() as db: port = get_port(db, server_id, port_id) if not forward_type: args = f" delete {local_port}" elif remote_port: port.forward_rule.config["remote_ip"] = remote_ip db.add(port.forward_rule) db.commit() args = ( f" -t={forward_type}" f" {'-v=6' if is_ipv6(remote_ip) else '-v=4'}" f" forward {local_port} {remote_ip} {remote_port}" ) else: args = f" list {local_port}" server = get_server_with_ports_usage(db, server_id) extravars = { "host": server.ansible_name, "local_port": local_port, "iptables_args": args, } run( server=server, playbook="iptables.yml", extravars=extravars, status_handler=lambda s, **k: status_handler( port_id, s, update_status ), finished_callback=iptables_finished_handler( server.id, port_id, True ) if update_status else lambda r: None, ) except Exception: traceback.print_exc() with db_session() as db: port = get_port(db, server_id, port_id) port.forward_rule.status = "failed" port.forward_rule.config["error"] = traceback.format_exc() print(port.forward_rule.__dict__) db.add(port.forward_rule) db.commit()
async def forward_rule_create( response: Response, server_id: int, port_id: int, forward_rule: PortForwardRuleCreate, db=Depends(get_db), user=Depends(get_current_active_user), ): """ Create a port forward rule """ db_port = get_port(db, server_id, port_id) if not user.is_admin() and not any( u.user_id == user.id for u in db_port.allowed_users ): raise HTTPException( status_code=403, detail="User not allowed to create forward rule on this port", ) if db_port.forward_rule: raise HTTPException( status_code=403, detail="Cannot create more than one rule on same port", ) forward_rule = trim_forward_rule(forward_rule) if forward_rule.method == MethodEnum.GOST: forward_rule = verify_gost_config(db_port, forward_rule) forward_rule = create_forward_rule(db, db_port, forward_rule) trigger_forward_rule(forward_rule) return forward_rule
async def forward_rule_edit( response: Response, server_id: int, port_id: int, forward_rule: PortForwardRuleEdit, db=Depends(get_db), user=Depends(get_current_active_user), ): """ Edit a port forward rule """ db_port = get_port(db, server_id, port_id) if not user.is_admin() and not any( u.user_id == user.id for u in db_port.allowed_users ): raise HTTPException( status_code=403, detail="User not allowed to create forward rule on this port", ) if db_port.server.config.get(f"{forward_rule.method.value}_disabled"): raise HTTPException( status_code=403, detail=f"{forward_rule.method.value} is not allowed") forward_rule = trim_forward_rule(forward_rule) if forward_rule.method == MethodEnum.GOST: forward_rule = verify_gost_config(db_port, forward_rule) updated = edit_forward_rule(db, server_id, port_id, forward_rule) trigger_forward_rule(updated) return updated
async def forward_rule_edit( response: Response, server_id: int, port_id: int, forward_rule: PortForwardRuleEdit, db=Depends(get_db), user=Depends(get_current_active_user), ): """ Edit a port forward rule """ db_port = get_port(db, server_id, port_id) if not user.is_admin() and not any(u.user_id == user.id for u in db_port.allowed_users): raise HTTPException( status_code=403, detail="User not allowed to create forward rule on this port", ) update_gost = False if forward_rule.method == MethodEnum.IPTABLES: forward_rule = verify_iptables_config(forward_rule) elif forward_rule.method == MethodEnum.GOST: forward_rule = verify_gost_config(db_port, forward_rule) update_gost = len(get_all_gost_rules(db, server_id)) == 0 old, updated = edit_forward_rule(db, server_id, port_id, forward_rule) trigger_forward_rule(updated, updated.port, old, updated, update_gost=update_gost) return updated
async def port_edit( request: Request, server_id: int, port_id: int, port: PortEdit, db=Depends(get_db), user=Depends(get_current_active_user), ): """ Update an existing port """ db_port = get_port(db, server_id, port_id) if not db_port: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Port not found") if not user.is_admin(): if not any(u.user_id == user.id for u in db_port.allowed_users): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Operation not allowed", ) port = PortEditBase(**port.dict(exclude_unset=True)) db_port = edit_port(db, db_port, port) trigger_tc(db_port) return db_port
async def port_get( response: Response, server_id: int, port_id: int, db=Depends(get_db), user=Depends(get_current_active_user), ): """ Get port by id """ port = get_port(db, server_id, port_id) if not port: raise HTTPException(status_code=404, detail="Port not found") if user.is_admin(): return PortOpsOut(**jsonable_encoder(port)) if not any(user.id == u["user_id"] for u in port.allowed_users): raise HTTPException(status_code=404, detail="Port not found") return PortOut(**jsonable_encoder(port))
async def port_delete( request: Request, server_id: int, port_id: int, db=Depends(get_db), current_user=Depends(get_current_active_admin), ): """ Delete an existing port on server """ db_port = get_port(db, server_id, port_id) if db_port: if db_port.forward_rule: trigger_forward_rule( db_port.forward_rule, db_port, old=db_port.forward_rule ) delete_port(db, server_id, port_id) remove_tc(server_id, db_port.num) return db_port
async def port_delete( request: Request, server_id: int, port_id: int, db=Depends(get_db), current_user=Depends(get_current_active_admin), ): """ Delete an existing port on server """ db_port = get_port(db, server_id, port_id) if not db_port: raise HTTPException(status_code=404, detail="Port not found") if db_port.forward_rule: trigger_port_clean(db_port.server, db_port) delete_port(db, server_id, port_id) remove_tc(server_id, db_port.num) return db_port
async def port_get( response: Response, server_id: int, port_id: int, db=Depends(get_db), user=Depends(get_current_active_user), ): """ Get port by id """ port = get_port(db, server_id, port_id) if not port: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Port not found") if user.is_admin(): return PortOpsOut(**port.__dict__) if not any(user.id == u.user_id for u in port.allowed_users): raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Port not found") return PortOut(**port.__dict__)