예제 #1
0
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()
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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))
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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__)