Skip to content

A REST API developed with FastAPI for managing network routes on a Linux machine using the ip command. It allows you to query active routes, create new routes, and delete existing routes, with token-based authentication and persistence of scheduled routes to ensure their availability even after service restarts.

License

Notifications You must be signed in to change notification settings

6G-SANDBOX/route-manager-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Route Manager API

A REST API developed with FastAPI for managing network routes on a Linux machine using the ip command. It allows you to query active routes, create new routes, update or pause existing ones, and delete routes. The system includes route scheduling based on timestamps, persistence using SQLite, and lifecycle management through a background loop.

Table of Contents

Features

  • Query Active Routes: Retrieve all routes currently active in the system and stored in the database.
  • Create Routes: Add new routes with options to schedule their creation and deletion.
  • Lifecycle Management: A background task checks and updates route states based on timestamps.
  • Route Status: Each route can be in one of five states: pending, active, paused, expired, or deleted.
  • Pause/Resume Routes: Temporarily pause or resume active routes via dedicated endpoints.
  • Delete Routes: Remove existing routes and unschedule their deletion.
  • Deleted Routes History: A separate table Deleted_Routes tracks all expired or manually deleted routes.
  • Authentication: Protect endpoints using a Bearer token for authentication.
  • Persistence: Store scheduled routes in a SQLite database to ensure they are reloaded after service restarts.
  • Service: Integrate with systemd to run the API as a system service.
  • Logging: Detailed logging of operations and errors for monitoring and debugging.

Repository Layout

├── LICENSE                # Licensing information for the repository
├── README.md              # The documentation you are reading right now
├── .devcontainer/         # (Optional) Configuration for devcontainers.
├── .env                   # (Optional) Sample configuration values to overwrite the defaults
├── app/                   # Main directory for the application code
│   ├── __init__.py            # Makes "app" a "Python package" (ignore it)
│   ├── core/                  # Configurations and global logic.
│   │   ├── __init__.py
│   │   ├── config.py              # Global application settings
│   │   ├── logging.py             # Global logging settings
│   ├── db/                    # Database-related modules and utilities
│   │   ├── __init__.py
│   │   ├── database.py            # Handles database connection and initialization
│   │   ├── models/                # Database models
│   │   │   ├── __init__.py
│   │   │   ├── routes.py              # SQLModel for stored routes
│   │   │   └── deleted_routes.py      # SQLModel for deleted routes
│   │   └── routes.py              # Utilities for interaction with the routes database
│   ├── routers/               # Manage application routes
│   │   ├── __init__.py
│   │   └── routes.py              # Defines API endpoints for routes
│   ├── schemas/               # Pydantic models for data validation and serialization
│   │   ├── __init__.py
│   │   └── routes.py              # Main schemas for routes
│   ├── services/              # Auxiliary utilities and services for the API endpoints
│   │   ├── __init__.py
│   │   ├── auth.py                # Functions related to user authentication and authorization
│   │   ├── lifecycle.py           # Loop wich validate the routes status
│   │   ├── routes.py              # Service functions for routes
│   │   └── utils.py               # Miscellaneous utility functions
│   ├── tests/                 # (Not yet implemented) Contains test modules
│   │   ├── __init__.py
│   │   └─── test_routes.py        # (Not yet implemented) Tests for the Routes module
│   ├── __init__.py
│   └── main.py                # Initializes the FastAPI application.
├── app_flow.drawio        # Visual representation of the API endpoints and expected behaviour of the app
├── pyproject.toml         # Python project configuration file used by tools like Poetry or uv (uv in our case)
└── uv.lock                # Lock file where uv manages app dependencies


Prerequisites

  • Operating System: Linux-based. Tested on Ubuntu 22.04 and Debian 12.
  • Python: Version 3.12 or higher
  • Permissions: Superuser permissions to manage network routes (capability NET_ADMIN) and to configure systemd services

Installation

All steps are intended to be run as root.

1. Clone the Repository

Clone this repository to your local machine:

git https://github.com/6G-SANDBOX/route-manager-api /opt/route-manager-api
cd route-manager-api

2. Install uv

The tool uv will take care for everything python-releated, from python versions, to virtual enviroments and dependencies.

curl -LsSf https://astral.sh/uv/install.sh | sh

3. Create a Virtual Environment

Download all necessary dependencies in a virtual environment as specified in the pyproject.toml file using uv

uv sync

4. (Optional) Create a systemd service

To run the API as a system service, create a systemd unit file. Uf you want to directly try the tool, run:

uv run fastapi run --port 8172  # Default port is 8000

4.1. Create the Unit File

Create a file named route-manager-api.service in /etc/systemd/system/:

cat > /etc/systemd/system/route-manager-api.service << 'EOF'
[Unit]
Description=A REST API developed with FastAPI for managing network routes on a Linux machine using the ip command. It allows you to query active routes, create new routes, and delete existing routes, with token-based authentication and persistence of scheduled routes to ensure their availability even after service restarts.
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/root/.local/bin/uv --directory /opt/route-manager-api/ run fastapi run --port 8172
StandardOutput=append:/var/log/route_manager.log
StandardError=append:/var/log/route_manager.log
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

4.2. Reload systemd and start the service

systemctl daemon-reload
systemctl enable route-manager-api.service
systemctl start route-manager-api.service

4.3. Verify the service Status

systemctl status route-manager.service

You should see that the service is active and running. If there are any errors, they will appear in the output of this command.

Usage

Available Endpoints

The API offers the following endpoints:

Method Path Description
GET /routes/ Fetch current system & DB routes
PUT /routes/ Add a new route (scheduled or now)
PATCH /routes/ Update route fields
DELETE /routes/ Remove a route manually
PATCH /routes/pause Pause an active route
PATCH /routes/activate Resume a paused route
GET /routes/deleted Show deleted or expired routes

WARNING: Beware the trailing slash

Route's Loop

Each route progresses through the following states:

  • pending: Waiting for create_at to be reached
  • active: Between create_at and delete_at
  • paused: Manually paused by user during active state
  • expired: Automatically marked after delete_at
  • deleted: Manually removed by the user

The background lifecycle loop (runs every 10 seconds):

  • Activates pending routes when their create_at is reached
  • Expires active routes when delete_at is reached
  • Ignores paused routes

Usage Examples with curl

Retrieve Routes

curl -X 'GET' \
  'http://localhost:8172/routes/' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer this_is_something_secret'

Successful Response: Code: 200

{
  "database_routes": [
    {
      "via": "192.168.215.100",
      "create_at": "2025-01-27T03:03:44.501824+00:00",
      "to": "10.10.2.10/32",
      "active": true,
      "dev": null,
      "delete_at": null
    },
    {
      "via": null,
      "create_at": "2027-01-30T09:38:59.284000+00:00",
      "to": "10.20.30.0/24",
      "active": false,
      "dev": "eth0",
      "delete_at": "2027-02-4T09:38:59.284000+00:00"
    }
  ],
  "system_routes": [
    "default via 192.168.215.1 dev eth0",
    "10.10.2.10/32 via 192.168.215.100 scope link",
    "192.168.215.0/24 dev eth0 proto kernel scope link src 192.168.215.2"
  ]
}

Add a Route

curl -X 'PUT' \
  'http://localhost:8172/routes/' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer this_is_something_secret' \
  -H 'Content-Type: application/json' \
  -d '{
  "to": "10.10.2.10/32",
  "via": "192.168.215.100",
  "create_at": "2025-01-27T03:03:44.501824+00:00"
}'

Successful Response: Code: 201

{
  "message": "Route succesfully added or scheduled"
}

Route already exists: Also succesful to achieve idempotency Code: 200

{
  "message": "A route to 10.10.2.10/32 already exists in the system"
}

Delete a Route

curl -X 'DELETE' \
  'http://localhost:8172/routes/' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer this_is_something_secret' \
  -H 'Content-Type: application/json' \
  -d '{
  "to": "10.10.2.10"
}'

Successful Response: Code: 200

{
  "message": "Route succesfully deleted"
}

Route Not Found: Code: 404

{
  "detail": "Route to 10.10.2.10/32 not found in the database."
}

Update a Route

curl -X 'PATCH' \
  'http://localhost:8172/routes/' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer this_is_something_secret' \
  -H 'Content-Type: application/json' \
  -d '{
    "to": "10.10.2.10/32",
    "delete_at": "2025-01-27T03:03:44.501824+00:00"
}'

Successful Response: Code: 200

{
  "message": "Route succesfully updated"
}

Route Not Found: Code: 404

{
  "detail": "Route to 10.10.2.10/32 not found in the database."
}

Retrieve Deleted Routes

curl -X 'GET' \
  'http://localhost:8172/routes/deleted' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer this_is_something_secret'

Successful Response: Code: 200

{
  "deleted_routes": [
    {
      "create_at": "2025-03-19T18:40:00",
      "to": "10.10.20.0/24",
      "via": null,
      "removed_at": "2025-03-24T18:11:06.458151+00:00",
      "id": 1,
      "dev": "eth0",
      "delete_at": "2025-03-24T18:11:00",
      "status": "expired"
    },
    {
      "create_at": "2025-03-19T18:40:00",
      "to": "10.10.20.0/24",
      "via": null,
      "removed_at": "2025-03-24T18:13:06.628571+00:00",
      "id": 2,
      "dev": "eth0",
      "delete_at": "2025-03-24T18:13:00",
      "status": "expired"
    },
  ]
}

Pause a Route

curl -X PATCH http://localhost:8172/routes/pause \
  -H 'Authorization: Bearer your_token' \
  -H 'Content-Type: application/json' \
  -d '{"to": "10.10.2.10/32"}'

Successful Response: Code: 200

{
  "message": "Route succesfully paused"
}

Route Not Found: Code: 404

{
  "detail": "Route to 10.10.2.10/32 not found in the database."
}

Reactivate a Route

curl -X PATCH http://localhost:8172/routes/activate \
  -H 'Authorization: Bearer your_token' \
  -H 'Content-Type: application/json' \
  -d '{"to": "10.10.2.10/32"}'

Successful Response: Code: 200

{
  "message": "Route succesfully activated"
}

Route Not Found: Code: 404

{
  "detail": "Route to 10.10.2.10/32 not found in the database."
}

API Documentation

FastAPI automatically generates interactive API documentation accessible at:

Logging

The application logs detailed information about its operations and errors using Python's standard logging module. Logs include:

  • Executed commands and their outputs.
  • Route existence checks.
  • Route creation and deletion operations.
  • Database interactions.
  • Authentication events.

Log File Location

By default, logs are displayed in the console where the service is running. To redirect logs to a file, modify the logging configuration in app/core/logging.py:

logging.basicConfig(
    filename='app.log',
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

Future development

Validation Loop

As seen in the app_flow.drawio, an internal loop will manage the lifecycle of routes stored in the database.

Exit Function

By default, the app will remove all routes added by it when terminating the service. This will be an optional feature, that can be disabled with an envvar.

nftables exceptions

When using this component inside the 6G-Sandbox bastion, added routes should also create exceptions for the highly restrictive firewall of the bastion.

Future iptools2 options

Currently, the integration of the following ip route subcommands:

  • metric
  • table
  • scope
  • proto
  • src
  • nexthop
  • onlink is not an urgent task, but the tool may be expanded to include them

Improve Documentation

Help is always welcomed, but yeah, some stuff might be improcise/wrong

Security Considerations

  • Authentication Token: The API uses a static token for Bearer authentication. Ensure you protect this token and change it to a secure value before deploying to production.
  • Input Validation: While pydantic is used for data validation, consider implementing additional security measures as needed for your environment.

License

This project is licensed under the MIT License. See the LICENSE file for more details.


Note: This project is designed for Linux environments with appropriate permissions to manage network routes. Ensure you understand the commands and configurations used before deploying to a production environment.

About

A REST API developed with FastAPI for managing network routes on a Linux machine using the ip command. It allows you to query active routes, create new routes, and delete existing routes, with token-based authentication and persistence of scheduled routes to ensure their availability even after service restarts.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages