mirror of
https://github.com/fosrl/docs.git
synced 2025-05-12 13:20:43 +01:00
standarize code block formatting with prettier
This commit is contained in:
parent
8d980307e0
commit
e301452e0d
42 changed files with 832 additions and 813 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"tabWidth": 4,
|
"tabWidth": 2,
|
||||||
"printWidth": 80,
|
"printWidth": 80,
|
||||||
"trailingComma": "none"
|
"trailingComma": "none"
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,32 +30,26 @@ Note that these guides may be out of date, as the project is still in active dev
|
||||||
Fossorial has a couple major components:
|
Fossorial has a couple major components:
|
||||||
|
|
||||||
### [**Pangolin**](https://github.com/fosrl/pangolin) (Management Application & Central Server)
|
### [**Pangolin**](https://github.com/fosrl/pangolin) (Management Application & Central Server)
|
||||||
The central hub for managing the application. Pangolin includes:
|
|
||||||
- Most business logic.
|
The central hub for managing the application. Pangolin includes: - Most business logic. - External facing rest API. - WebSocket server for managing Newt sites. - Internal facing rest API for communication between components on the VPS. - Frontend server for the web interface. - Main database for storing data. - Authentication system.
|
||||||
- External facing rest API.
|
|
||||||
- WebSocket server for managing Newt sites.
|
|
||||||
- Internal facing rest API for communication between components on the VPS.
|
|
||||||
- Frontend server for the web interface.
|
|
||||||
- Main database for storing data.
|
|
||||||
- Authentication system.
|
|
||||||
|
|
||||||
### [**Gerbil**](https://github.com/fosrl/gerbil) (WireGuard Interface Management)
|
### [**Gerbil**](https://github.com/fosrl/gerbil) (WireGuard Interface Management)
|
||||||
Acts as the intermediary for managing WireGuard configurations. It creates and maintains the secure tunnels between sites and the Pangolin server.
|
|
||||||
|
Acts as the intermediary for managing WireGuard configurations. It creates and maintains the secure tunnels between sites and the Pangolin server.
|
||||||
|
|
||||||
### [**Traefik**](https://github.com/traefik/traefik) (Reverse Proxy)
|
### [**Traefik**](https://github.com/traefik/traefik) (Reverse Proxy)
|
||||||
A high-performance, modular reverse proxy that routes requests to private resources. Traefik is widely adopted, and its plugin system allows further customization and security enhancements. For example:
|
|
||||||
- Out-of-the-box compatibility with plugins like [Fail2Ban](https://plugins.traefik.io/plugins/628c9ebcffc0cd18356a979f/fail2-ban) or [CrowdSec](https://plugins.traefik.io/plugins/6335346ca4caa9ddeffda116/crowdsec-bouncer-traefik-plugin).
|
A high-performance, modular reverse proxy that routes requests to private resources. Traefik is widely adopted, and its plugin system allows further customization and security enhancements. For example: - Out-of-the-box compatibility with plugins like [Fail2Ban](https://plugins.traefik.io/plugins/628c9ebcffc0cd18356a979f/fail2-ban) or [CrowdSec](https://plugins.traefik.io/plugins/6335346ca4caa9ddeffda116/crowdsec-bouncer-traefik-plugin). - Enhanced security via our custom Traefik plugin Badger, which acts as an authentication bouncer.
|
||||||
- Enhanced security via our custom Traefik plugin Badger, which acts as an authentication bouncer.
|
|
||||||
|
|
||||||
### [**Badger**](https://github.com/fosrl/badger) (Traefik Plugin Middleware):
|
### [**Badger**](https://github.com/fosrl/badger) (Traefik Plugin Middleware):
|
||||||
|
|
||||||
A custom Traefik plugin that acts as an authentication bouncer. Badger:
|
A custom Traefik plugin that acts as an authentication bouncer. Badger:
|
||||||
- Intercepts requests to the Traefik reverse proxy.
|
- Intercepts requests to the Traefik reverse proxy.
|
||||||
- Redirects unauthenticated requests to the Pangolin server for authentication.
|
- Redirects unauthenticated requests to the Pangolin server for authentication.
|
||||||
|
|
||||||
### [**Newt**](https://github.com/fosrl/newt) (Minimal User Space WireGuard Client)
|
### [**Newt**](https://github.com/fosrl/newt) (Minimal User Space WireGuard Client)
|
||||||
A lightweight client designed to run on the private network. Newt:
|
|
||||||
- Connects to the Pangolin server via WebSocket and Gerbil via fully user space WireGuard
|
A lightweight client designed to run on the private network. Newt: - Connects to the Pangolin server via WebSocket and Gerbil via fully user space WireGuard - Facilitates networking through its connection to Gerbil and creating TCP proxies
|
||||||
- Facilitates networking through its connection to Gerbil and creating TCP proxies
|
|
||||||
|
|
||||||
## System Diagram
|
## System Diagram
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ Docker automatically creates iptables NAT rules when container ports are publish
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|
||||||
Following ports should be exposed on Operating system level.
|
Following ports should be exposed on Operating system level.
|
||||||
|
|
||||||
### TCP 80
|
### TCP 80
|
||||||
|
|
|
@ -57,7 +57,7 @@ For example on a Linux client, you can write your copied config to a wg0.conf fi
|
||||||
|
|
||||||
1. Head to the **Resources** tab and select the `Add Resource` button (or use the tab in the setup workflow)
|
1. Head to the **Resources** tab and select the `Add Resource` button (or use the tab in the setup workflow)
|
||||||
2. Give your resource a name like "Bitwarden"
|
2. Give your resource a name like "Bitwarden"
|
||||||
3. Choose a subdomain for this resource. The subdomain must be ***globally unique** across all orgs and sites
|
3. Choose a subdomain for this resource. The subdomain must be **\*globally unique** across all orgs and sites
|
||||||
4. Choose the site that this resource is at. The resource target must be accessible behind the tunnel attached to this site.
|
4. Choose the site that this resource is at. The resource target must be accessible behind the tunnel attached to this site.
|
||||||
5. Press `Create Resource`
|
5. Press `Create Resource`
|
||||||
|
|
||||||
|
@ -68,9 +68,9 @@ For example on a Linux client, you can write your copied config to a wg0.conf fi
|
||||||
1. You should now be on the **Connectivity** page under your new resource
|
1. You should now be on the **Connectivity** page under your new resource
|
||||||
2. If you would like to secure this site with https, leave the `Enable SSL` toggle enabled
|
2. If you would like to secure this site with https, leave the `Enable SSL` toggle enabled
|
||||||
3. Add a target for this resource. If your resource is accessible on your internal network at `http://192.168.1.24:8080` for example, then choose the following
|
3. Add a target for this resource. If your resource is accessible on your internal network at `http://192.168.1.24:8080` for example, then choose the following
|
||||||
Method: HTTP
|
Method: HTTP
|
||||||
IP Address: 192.168.1.24
|
IP Address: 192.168.1.24
|
||||||
Port: 8080
|
Port: 8080
|
||||||
4. Press `Add Target` and you will see the target added to the list and enabled.
|
4. Press `Add Target` and you will see the target added to the list and enabled.
|
||||||
5. Press `Save Changes`
|
5. Press `Save Changes`
|
||||||
6. Try to access your resource by clicking the url at the top
|
6. Try to access your resource by clicking the url at the top
|
||||||
|
|
|
@ -80,7 +80,6 @@ You can [buy a cheap domain at Namecheap](https://namecheap.pxf.io/c/6099916/386
|
||||||
**Use Case Example - IoT Networks**:
|
**Use Case Example - IoT Networks**:
|
||||||
IoT networks are often fragmented and difficult to manage. By deploying Pangolin on a central server, you can connect all your IoT sites via Newt or another WireGuard client. This creates a simple, secure, and centralized way to access IoT resources without the need for intricate networking setups.
|
IoT networks are often fragmented and difficult to manage. By deploying Pangolin on a central server, you can connect all your IoT sites via Newt or another WireGuard client. This creates a simple, secure, and centralized way to access IoT resources without the need for intricate networking setups.
|
||||||
|
|
||||||
|
|
||||||
<img src={require("./img/resources.png").default} alt="Resources"/>
|
<img src={require("./img/resources.png").default} alt="Resources"/>
|
||||||
|
|
||||||
_Resources page of Pangolin dashboard (dark mode) showing HTTPS and TCP resources with access control rules._
|
_Resources page of Pangolin dashboard (dark mode) showing HTTPS and TCP resources with access control rules._
|
||||||
|
|
|
@ -16,7 +16,9 @@ It is highly reccommended that you read the [official Traefik documentation](htt
|
||||||
|
|
||||||
1. Wildcard certificates allow you to secure your all subdomains with a single certificate. This reduces the number of certificates you need to manage.
|
1. Wildcard certificates allow you to secure your all subdomains with a single certificate. This reduces the number of certificates you need to manage.
|
||||||
2. You can add new subdomains to resources without needing to generate a new certificate each time. Without a wildcard certificate, you would need to wait (up to a few minutes usually) for a new certificate to be generated and loaded by Traefik.
|
2. You can add new subdomains to resources without needing to generate a new certificate each time. Without a wildcard certificate, you would need to wait (up to a few minutes usually) for a new certificate to be generated and loaded by Traefik.
|
||||||
|
|
||||||
- For example: A wildcard cert `*.example.com` could protect `api.example.com`, `blog.example.com`, and another `*.subdomain.example.com` could protect `api.subdomain.example.com`, `blog.subdomain.example.com`, etc.
|
- For example: A wildcard cert `*.example.com` could protect `api.example.com`, `blog.example.com`, and another `*.subdomain.example.com` could protect `api.subdomain.example.com`, `blog.subdomain.example.com`, etc.
|
||||||
|
|
||||||
3. The [rate limits](https://letsencrypt.org/docs/rate-limits/) for Let's Encrypt are per domain. Using a wildcard certificate reduces the number of domains you have, which can help you avoid hitting these limits.
|
3. The [rate limits](https://letsencrypt.org/docs/rate-limits/) for Let's Encrypt are per domain. Using a wildcard certificate reduces the number of domains you have, which can help you avoid hitting these limits.
|
||||||
|
|
||||||
## Setting Up Wildcard Certificates
|
## Setting Up Wildcard Certificates
|
||||||
|
@ -24,6 +26,7 @@ It is highly reccommended that you read the [official Traefik documentation](htt
|
||||||
1. Make sure the stack is not running.
|
1. Make sure the stack is not running.
|
||||||
2. Update the Traefik configuration to use the DNS-01 challenge instead of the HTTP-01 challenge. This tells Traefik to use your DNS provider to create the DNS records needed for the challenge.
|
2. Update the Traefik configuration to use the DNS-01 challenge instead of the HTTP-01 challenge. This tells Traefik to use your DNS provider to create the DNS records needed for the challenge.
|
||||||
3. Set the `prefer_wildcard_cert` flag to `true` in the Pangolin configuration file for your domain.
|
3. Set the `prefer_wildcard_cert` flag to `true` in the Pangolin configuration file for your domain.
|
||||||
|
|
||||||
- This settings will try to encourage Traefik to request one wildcard certificate for each level of the domain used by your existing resources.
|
- This settings will try to encourage Traefik to request one wildcard certificate for each level of the domain used by your existing resources.
|
||||||
- For example: If you have two resources `blog.example.com` and `blog.subdomain.example.com`, Traefik should try to request a wildcard certificate for `*.example.com` and `*.subdomain.example.com` automatically for you.
|
- For example: If you have two resources `blog.example.com` and `blog.subdomain.example.com`, Traefik should try to request a wildcard certificate for `*.example.com` and `*.subdomain.example.com` automatically for you.
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ You can also use "local" sites to expose resources on the same VPS as Pangolin i
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
You can use Pangolin without Gerbil and tunneling. In this configuration Pangolin is essentially acting as a normal reverse proxy and authentication manager and can be deployed on the *local* network in order to provide access to resources.
|
You can use Pangolin without Gerbil and tunneling. In this configuration Pangolin is essentially acting as a normal reverse proxy and authentication manager and can be deployed on the _local_ network in order to provide access to resources.
|
||||||
|
|
||||||
All setup remains the same, except Pangolin and Traefik must now be on the same network you want to proxy targets to and you do not need to install Gerbil.
|
All setup remains the same, except Pangolin and Traefik must now be on the same network you want to proxy targets to and you do not need to install Gerbil.
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
Initial API documentation for pangolin. This documentation includes public endpoints, request/response formats, usage examples, and any limitations or constraints. This document is not complete but will be added to over time to compass more of the API.
|
Initial API documentation for pangolin. This documentation includes public endpoints, request/response formats, usage examples, and any limitations or constraints. This document is not complete but will be added to over time to compass more of the API.
|
||||||
|
|
||||||
### Base URL
|
### Base URL
|
||||||
|
|
||||||
```
|
```
|
||||||
https://pangolin.yourdomain.com/api/v1/
|
https://pangolin.yourdomain.com/api/v1/
|
||||||
```
|
```
|
||||||
|
@ -93,6 +94,7 @@ https://pangolin.yourdomain.com/api/v1/
|
||||||
### 1.3 Resource Management
|
### 1.3 Resource Management
|
||||||
|
|
||||||
- **Create Resource**
|
- **Create Resource**
|
||||||
|
|
||||||
- **Endpoint:** `PUT /org/{orgId}/site/{siteId}/resource`
|
- **Endpoint:** `PUT /org/{orgId}/site/{siteId}/resource`
|
||||||
- **Description:** Creates a new resource for a specific organization and site.
|
- **Description:** Creates a new resource for a specific organization and site.
|
||||||
- **Authentication:** Session cookie required
|
- **Authentication:** Session cookie required
|
||||||
|
|
|
@ -7,7 +7,7 @@ Rules allow you to either "allow" and bypass the Pangolin auth system (no pin, l
|
||||||
This table compiles paths that need to be allowed for various apps to work with Pangolin authentication.
|
This table compiles paths that need to be allowed for various apps to work with Pangolin authentication.
|
||||||
|
|
||||||
| App | Required Bypass Rules |
|
| App | Required Bypass Rules |
|
||||||
|-----|------------------------|
|
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| **Media Management** | |
|
| **Media Management** | |
|
||||||
| Radarr | `/api/*` |
|
| Radarr | `/api/*` |
|
||||||
| Sonarr | `/api/*` |
|
| Sonarr | `/api/*` |
|
||||||
|
|
|
@ -10,7 +10,6 @@ This Home Assistant add-on allows you to easily run **Newt** directly in Home As
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
||||||
- Easy installation via Home Assistant Add-on Store
|
- Easy installation via Home Assistant Add-on Store
|
||||||
- Automated setup and execution of the Newt container
|
- Automated setup and execution of the Newt container
|
||||||
- Supports `amd64`, `armv7`, `armhf`, and `aarch64` architectures
|
- Supports `amd64`, `armv7`, `armhf`, and `aarch64` architectures
|
||||||
|
@ -18,19 +17,15 @@ This Home Assistant add-on allows you to easily run **Newt** directly in Home As
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
||||||
### **1. Add the GitHub Repository as an Add-on Source**
|
### **1. Add the GitHub Repository as an Add-on Source**
|
||||||
|
|
||||||
|
|
||||||
- Go to **Settings → Add-ons → Add-on Store**.
|
- Go to **Settings → Add-ons → Add-on Store**.
|
||||||
- Click the menu (three dots in the top right) and select **Repositories**.
|
- Click the menu (three dots in the top right) and select **Repositories**.
|
||||||
- Add the following URL:
|
- Add the following URL:
|
||||||
|
|
||||||
```
|
```
|
||||||
https://github.com/Ferdinand99/home-assistant-newt-addon
|
https://github.com/Ferdinand99/home-assistant-newt-addon
|
||||||
```
|
```
|
||||||
or
|
or
|
||||||
|
|
||||||
```
|
```
|
||||||
https://git.opland.net/Ferdinand99/home-assistant-newt-addon/
|
https://git.opland.net/Ferdinand99/home-assistant-newt-addon/
|
||||||
```
|
```
|
||||||
|
@ -39,7 +34,6 @@ This Home Assistant add-on allows you to easily run **Newt** directly in Home As
|
||||||
|
|
||||||
### **2. Install and Start the Add-on**
|
### **2. Install and Start the Add-on**
|
||||||
|
|
||||||
|
|
||||||
1. Find **Newt Add-on** in the list and click **Install**.
|
1. Find **Newt Add-on** in the list and click **Install**.
|
||||||
2. Go to the **Configuration** tab and enter your values for:
|
2. Go to the **Configuration** tab and enter your values for:
|
||||||
- **PANGOLIN_ENDPOINT** (e.g., `https://example.com`)
|
- **PANGOLIN_ENDPOINT** (e.g., `https://example.com`)
|
||||||
|
@ -50,7 +44,6 @@ This Home Assistant add-on allows you to easily run **Newt** directly in Home As
|
||||||
|
|
||||||
## **Configuration**
|
## **Configuration**
|
||||||
|
|
||||||
|
|
||||||
After installation, you can configure the add-on via the Home Assistant UI:
|
After installation, you can configure the add-on via the Home Assistant UI:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -69,7 +62,6 @@ The following environment variables are passed to the `Newt` container:
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
|
||||||
#### **Add-on does not start?**
|
#### **Add-on does not start?**
|
||||||
|
|
||||||
- Check the logs in Home Assistant (`Settings → Add-ons → Newt → Logs`).
|
- Check the logs in Home Assistant (`Settings → Add-ons → Newt → Logs`).
|
||||||
|
@ -85,18 +77,15 @@ The following environment variables are passed to the `Newt` container:
|
||||||
docker rm newt
|
docker rm newt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
- Then start the add-on again.
|
- Then start the add-on again.
|
||||||
|
|
||||||
#### **Docker not available?**
|
#### **Docker not available?**
|
||||||
|
|
||||||
- Home Assistant OS manages Docker automatically, but check if the system has access to Docker by running:
|
- Home Assistant OS manages Docker automatically, but check if the system has access to Docker by running:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker info
|
docker info
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
If this fails, there may be a restriction in Home Assistant OS.
|
If this fails, there may be a restriction in Home Assistant OS.
|
||||||
|
|
||||||
## Useful Links
|
## Useful Links
|
||||||
|
|
|
@ -7,12 +7,15 @@ This guide provides essential information for developers working on the Gerbil p
|
||||||
To get started with the Gerbil project, follow these setup instructions:
|
To get started with the Gerbil project, follow these setup instructions:
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- **Go**: Ensure that you have Go installed on your system. The project uses Go version 1.23.1 or later. You can download it from [golang.org](https://golang.org/dl/).
|
- **Go**: Ensure that you have Go installed on your system. The project uses Go version 1.23.1 or later. You can download it from [golang.org](https://golang.org/dl/).
|
||||||
- **Docker**: Install Docker to build and run the application in a containerized environment.
|
- **Docker**: Install Docker to build and run the application in a containerized environment.
|
||||||
- **Git**: Make sure Git is installed to clone the repository.
|
- **Git**: Make sure Git is installed to clone the repository.
|
||||||
|
|
||||||
### Installation Steps
|
### Installation Steps
|
||||||
|
|
||||||
1. **Clone the Repository**:
|
1. **Clone the Repository**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/fosrl/gerbil.git
|
git clone https://github.com/fosrl/gerbil.git
|
||||||
cd gerbil
|
cd gerbil
|
||||||
|
@ -20,12 +23,14 @@ To get started with the Gerbil project, follow these setup instructions:
|
||||||
|
|
||||||
2. **Install Dependencies**:
|
2. **Install Dependencies**:
|
||||||
Run the following command to download all required Go dependencies:
|
Run the following command to download all required Go dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go mod download
|
go mod download
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Build the Application**:
|
3. **Build the Application**:
|
||||||
You can build the application using Docker or directly using Go:
|
You can build the application using Docker or directly using Go:
|
||||||
|
|
||||||
- **Using Docker**:
|
- **Using Docker**:
|
||||||
```bash
|
```bash
|
||||||
docker build -t gerbil .
|
docker build -t gerbil .
|
||||||
|
@ -75,6 +80,7 @@ gerbil/
|
||||||
The development workflow for contributing to Gerbil involves several key steps:
|
The development workflow for contributing to Gerbil involves several key steps:
|
||||||
|
|
||||||
1. **Branching**: Create a new branch for your feature or bug fix.
|
1. **Branching**: Create a new branch for your feature or bug fix.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout -b feature/my-feature-name
|
git checkout -b feature/my-feature-name
|
||||||
```
|
```
|
||||||
|
@ -84,11 +90,13 @@ The development workflow for contributing to Gerbil involves several key steps:
|
||||||
3. **Testing Locally**: Run tests locally to ensure your changes do not break existing functionality.
|
3. **Testing Locally**: Run tests locally to ensure your changes do not break existing functionality.
|
||||||
|
|
||||||
4. **Committing Changes**: Commit your changes with a descriptive message.
|
4. **Committing Changes**: Commit your changes with a descriptive message.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git commit -m "Add feature X"
|
git commit -m "Add feature X"
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **Pushing Changes**: Push your branch to the remote repository.
|
5. **Pushing Changes**: Push your branch to the remote repository.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git push origin feature/my-feature-name
|
git push origin feature/my-feature-name
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,6 +7,7 @@ This document outlines the system architecture of the Gerbil project, a Go appli
|
||||||
The Gerbil project is structured around a central application that interacts with the WireGuard VPN service to create, manage, and configure tunnels. The application is built using Go and leverages various libraries for logging, networking, and configuration management.
|
The Gerbil project is structured around a central application that interacts with the WireGuard VPN service to create, manage, and configure tunnels. The application is built using Go and leverages various libraries for logging, networking, and configuration management.
|
||||||
|
|
||||||
### Key Features:
|
### Key Features:
|
||||||
|
|
||||||
- **WireGuard Management**: Create and manage WireGuard interfaces and peers.
|
- **WireGuard Management**: Create and manage WireGuard interfaces and peers.
|
||||||
- **Logging**: Centralized logging functionality to track application behavior.
|
- **Logging**: Centralized logging functionality to track application behavior.
|
||||||
- **Configuration**: JSON-based configuration management for easy setup and modification.
|
- **Configuration**: JSON-based configuration management for easy setup and modification.
|
||||||
|
@ -21,6 +22,7 @@ The main components of the Gerbil project include:
|
||||||
- **Dockerfile**: Defines how to build and run the application in a containerized environment.
|
- **Dockerfile**: Defines how to build and run the application in a containerized environment.
|
||||||
|
|
||||||
### Interaction Flow:
|
### Interaction Flow:
|
||||||
|
|
||||||
1. The main application starts and initializes the logger.
|
1. The main application starts and initializes the logger.
|
||||||
2. It reads configuration from `config_example.json` or an equivalent file or a remote http api hosted in Pangolin.
|
2. It reads configuration from `config_example.json` or an equivalent file or a remote http api hosted in Pangolin.
|
||||||
3. Based on the configuration, it interacts with the WireGuard API using the `wgctrl` library and netlink to set up tunnels and peers.
|
3. Based on the configuration, it interacts with the WireGuard API using the `wgctrl` library and netlink to set up tunnels and peers.
|
||||||
|
@ -53,6 +55,7 @@ The main components of the Gerbil project include:
|
||||||
```
|
```
|
||||||
|
|
||||||
### Description:
|
### Description:
|
||||||
|
|
||||||
- **Configuration**: The application reads from a configuration file that specifies settings like private keys, listen ports, and peers.
|
- **Configuration**: The application reads from a configuration file that specifies settings like private keys, listen ports, and peers.
|
||||||
- **Main Application**: Orchestrates the flow by initializing components and executing commands based on user input.
|
- **Main Application**: Orchestrates the flow by initializing components and executing commands based on user input.
|
||||||
- **Logger**: Captures events during execution for later review.
|
- **Logger**: Captures events during execution for later review.
|
||||||
|
@ -61,6 +64,7 @@ The main components of the Gerbil project include:
|
||||||
## 4. Design Decisions and Rationale
|
## 4. Design Decisions and Rationale
|
||||||
|
|
||||||
### Key Design Decisions:
|
### Key Design Decisions:
|
||||||
|
|
||||||
- **Use of Go**: Chosen for its performance, concurrency support, and ease of deployment.
|
- **Use of Go**: Chosen for its performance, concurrency support, and ease of deployment.
|
||||||
- **JSON Configuration**: Provides a human-readable format that is easy to modify without requiring recompilation.
|
- **JSON Configuration**: Provides a human-readable format that is easy to modify without requiring recompilation.
|
||||||
- **Modular Logging**: Encapsulated logging functionality allows for consistent logging practices across different parts of the application.
|
- **Modular Logging**: Encapsulated logging functionality allows for consistent logging practices across different parts of the application.
|
||||||
|
@ -68,5 +72,6 @@ The main components of the Gerbil project include:
|
||||||
## 5. System Constraints and Limitations
|
## 5. System Constraints and Limitations
|
||||||
|
|
||||||
### Constraints:
|
### Constraints:
|
||||||
|
|
||||||
- **Platform Dependency**: The application relies on Linux-based systems due to its use of netlink sockets for network management.
|
- **Platform Dependency**: The application relies on Linux-based systems due to its use of netlink sockets for network management.
|
||||||
- **Privileged Operations**: Requires elevated permissions to create network interfaces and modify routing tables.
|
- **Privileged Operations**: Requires elevated permissions to create network interfaces and modify routing tables.
|
|
@ -14,6 +14,7 @@ When installing Crowdsec via the Pangolin installer, the Crowdsec Traefik Bounce
|
||||||
The CrowdSec Bouncer plugin for Traefik integrates CrowdSec’s security engine to block malicious traffic in real time. It runs as middleware within a Traefik container and enforces decisions based on CrowdSec’s threat intelligence. This helps protect services from bots, attackers, and abusive IPs dynamically.
|
The CrowdSec Bouncer plugin for Traefik integrates CrowdSec’s security engine to block malicious traffic in real time. It runs as middleware within a Traefik container and enforces decisions based on CrowdSec’s threat intelligence. This helps protect services from bots, attackers, and abusive IPs dynamically.
|
||||||
|
|
||||||
For additional information, consult the following resources:
|
For additional information, consult the following resources:
|
||||||
|
|
||||||
- [Traefik Plugin Catalog](https://plugins.traefik.io/plugins/6335346ca4caa9ddeffda116/crowdsec-bouncer-traefik-plugin)
|
- [Traefik Plugin Catalog](https://plugins.traefik.io/plugins/6335346ca4caa9ddeffda116/crowdsec-bouncer-traefik-plugin)
|
||||||
- [Github Repository](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin)
|
- [Github Repository](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin)
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ For additional information, consult the following resources:
|
||||||
The GeoBlock plugin for Traefik is a middleware that restricts access based on the client’s geographic location. It runs within a Traefik container and uses IP-based geolocation to allow or block traffic from specific countries. This is useful for security, compliance, or access control in Traefik-managed services.
|
The GeoBlock plugin for Traefik is a middleware that restricts access based on the client’s geographic location. It runs within a Traefik container and uses IP-based geolocation to allow or block traffic from specific countries. This is useful for security, compliance, or access control in Traefik-managed services.
|
||||||
|
|
||||||
For more details, please refer to the following resources:
|
For more details, please refer to the following resources:
|
||||||
|
|
||||||
- [Github Repository](https://github.com/PascalMinder/geoblock)
|
- [Github Repository](https://github.com/PascalMinder/geoblock)
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
@ -33,6 +35,7 @@ Currently you can claim metric data from Traefik and Crowdsec with Prometheus an
|
||||||
Prometheus is an open-source monitoring and alerting toolkit designed for collecting and querying time-series metrics. It runs as a Docker container and uses a pull-based model to scrape data from configured endpoints. Prometheus integrates well with Grafana for visualization and Alertmanager for alert handling.
|
Prometheus is an open-source monitoring and alerting toolkit designed for collecting and querying time-series metrics. It runs as a Docker container and uses a pull-based model to scrape data from configured endpoints. Prometheus integrates well with Grafana for visualization and Alertmanager for alert handling.
|
||||||
|
|
||||||
For more details, please refer to the following resources:
|
For more details, please refer to the following resources:
|
||||||
|
|
||||||
- [Homepage](https://prometheus.io/)
|
- [Homepage](https://prometheus.io/)
|
||||||
- [Github Repository](https://github.com/prometheus/prometheus)
|
- [Github Repository](https://github.com/prometheus/prometheus)
|
||||||
|
|
||||||
|
@ -41,5 +44,6 @@ For more details, please refer to the following resources:
|
||||||
Grafana is an open-source analytics and visualization platform used to monitor and display time-series data. It runs as a Docker container and supports multiple data sources, including Prometheus, InfluxDB, and MySQL. Grafana provides interactive dashboards, alerting, and extensive customization options for data visualization.
|
Grafana is an open-source analytics and visualization platform used to monitor and display time-series data. It runs as a Docker container and supports multiple data sources, including Prometheus, InfluxDB, and MySQL. Grafana provides interactive dashboards, alerting, and extensive customization options for data visualization.
|
||||||
|
|
||||||
For more details, please refer to the following resources:
|
For more details, please refer to the following resources:
|
||||||
|
|
||||||
- [Homepage](https://grafana.com/)
|
- [Homepage](https://grafana.com/)
|
||||||
- [Github Repository](https://github.com/grafana/grafana)
|
- [Github Repository](https://github.com/grafana/grafana)
|
||||||
|
|
|
@ -15,6 +15,7 @@ By default, Crowdsec is installed with a basic configuration, which includes the
|
||||||
#### Syslog
|
#### Syslog
|
||||||
|
|
||||||
For systems utilizing Syslog, the following volumes should be added to the `docker-compose.yml` file:
|
For systems utilizing Syslog, the following volumes should be added to the `docker-compose.yml` file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service:
|
service:
|
||||||
crowdsec:
|
crowdsec:
|
||||||
|
@ -24,6 +25,7 @@ service:
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a `syslog.yaml` file under `/config/crowdsec/acquis.d` with the following content:
|
Create a `syslog.yaml` file under `/config/crowdsec/acquis.d` with the following content:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
filenames:
|
filenames:
|
||||||
- /var/log/auth.log
|
- /var/log/auth.log
|
||||||
|
@ -35,11 +37,13 @@ labels:
|
||||||
#### Journalctl
|
#### Journalctl
|
||||||
|
|
||||||
To log iptables to journalctl, execute the following command on your host system:
|
To log iptables to journalctl, execute the following command on your host system:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
iptables -A INPUT -j LOG --log-prefix "iptables: "
|
iptables -A INPUT -j LOG --log-prefix "iptables: "
|
||||||
```
|
```
|
||||||
|
|
||||||
Update the `docker-compose.yml` file as follows:
|
Update the `docker-compose.yml` file as follows:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service:
|
service:
|
||||||
crowdsec:
|
crowdsec:
|
||||||
|
@ -54,6 +58,7 @@ service:
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a `journalctl.yaml` file under `/config/crowdsec/acquis.d` with the following content:
|
Create a `journalctl.yaml` file under `/config/crowdsec/acquis.d` with the following content:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
source: journalctl
|
source: journalctl
|
||||||
journalctl_filter:
|
journalctl_filter:
|
||||||
|
@ -67,31 +72,37 @@ labels:
|
||||||
By default, only Traefik requests are secured through the Crowdsec bouncer. To extend protection to your host system (e.g., SSH), follow these steps to add a firewall bouncer:
|
By default, only Traefik requests are secured through the Crowdsec bouncer. To extend protection to your host system (e.g., SSH), follow these steps to add a firewall bouncer:
|
||||||
|
|
||||||
1. Install the Crowdsec repositories. Refer to the [installation documentation](https://docs.crowdsec.net/docs/next/getting_started/install_crowdsec/#install-our-repositories):
|
1. Install the Crowdsec repositories. Refer to the [installation documentation](https://docs.crowdsec.net/docs/next/getting_started/install_crowdsec/#install-our-repositories):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -s https://install.crowdsec.net | sudo sh
|
curl -s https://install.crowdsec.net | sudo sh
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Install the firewall bouncer. For Debian/Ubuntu systems using IPTables, refer to the [documentation](https://docs.crowdsec.net/u/bouncers/firewall/):
|
2. Install the firewall bouncer. For Debian/Ubuntu systems using IPTables, refer to the [documentation](https://docs.crowdsec.net/u/bouncers/firewall/):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install crowdsec-firewall-bouncer-iptables
|
sudo apt install crowdsec-firewall-bouncer-iptables
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Create an API key for the firewall bouncer to communicate with your CrowdSec Docker container. ("vps-firewall" is a placeholder name for the key):
|
3. Create an API key for the firewall bouncer to communicate with your CrowdSec Docker container. ("vps-firewall" is a placeholder name for the key):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec -it crowdsec cscli bouncers add vps-firewall
|
docker exec -it crowdsec cscli bouncers add vps-firewall
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Copy the dispalyed API key and insert it into the bouncer's configuration file:
|
4. Copy the dispalyed API key and insert it into the bouncer's configuration file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
|
nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Restart the firewall bouncer:
|
5. Restart the firewall bouncer:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl restart crowdsec-firewall-bouncer
|
systemctl restart crowdsec-firewall-bouncer
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Update the `docker-compose.yml` file to expose communication port `8080` for the CrowdSec container and restart the container:
|
6. Update the `docker-compose.yml` file to expose communication port `8080` for the CrowdSec container and restart the container:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service:
|
service:
|
||||||
crowdsec:
|
crowdsec:
|
||||||
|
@ -101,11 +112,13 @@ service:
|
||||||
```
|
```
|
||||||
|
|
||||||
7. Verify communication between the firewall bouncer and the CrowdSec container by running:
|
7. Verify communication between the firewall bouncer and the CrowdSec container by running:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec crowdsec cscli metrics
|
docker exec crowdsec cscli metrics
|
||||||
```
|
```
|
||||||
|
|
||||||
The output should look like this:
|
The output should look like this:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
+------------------------------------------------------------------+
|
+------------------------------------------------------------------+
|
||||||
| Local API Bouncers Metrics |
|
| Local API Bouncers Metrics |
|
||||||
|
@ -123,11 +136,13 @@ The output should look like this:
|
||||||
To display a custom ban page to attackers, follow these steps:
|
To display a custom ban page to attackers, follow these steps:
|
||||||
|
|
||||||
1. Place a `ban.html` page in the `/config/traefik` directory. If you prefer not to create your own, you can download the official example:
|
1. Place a `ban.html` page in the `/config/traefik` directory. If you prefer not to create your own, you can download the official example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/ban.html
|
wget https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/ban.html
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Update the `/config/traefik/dynamic_config.yml` file to include the following:
|
2. Update the `/config/traefik/dynamic_config.yml` file to include the following:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
http:
|
http:
|
||||||
middlewares:
|
middlewares:
|
||||||
|
@ -142,11 +157,13 @@ http:
|
||||||
To use a custom captcha page, follow these steps:
|
To use a custom captcha page, follow these steps:
|
||||||
|
|
||||||
1. Place a `captcha.html` page in the `/config/traefik` directory. If you don't want to create your own, you can download the official example:
|
1. Place a `captcha.html` page in the `/config/traefik` directory. If you don't want to create your own, you can download the official example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/captcha.html
|
wget https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/captcha.html
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Update the `/config/traefik/dynamic_config.yml` file with the following configuration, replacing `<SERVICE>` with your captcha provider (e.g. hCaptcha, reCaptcha, Turnstile), and `<KEY>` with the appropriate site and secret keys:
|
2. Update the `/config/traefik/dynamic_config.yml` file with the following configuration, replacing `<SERVICE>` with your captcha provider (e.g. hCaptcha, reCaptcha, Turnstile), and `<KEY>` with the appropriate site and secret keys:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
http:
|
http:
|
||||||
middlewares:
|
middlewares:
|
||||||
|
@ -165,11 +182,13 @@ http:
|
||||||
You can test your configuration by adding a temporary ban or captcha for your IP. The ban will last for one minute.
|
You can test your configuration by adding a temporary ban or captcha for your IP. The ban will last for one minute.
|
||||||
|
|
||||||
To add a ban:
|
To add a ban:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec crowdsec cscli decisions add --ip <YOUR IP> -d 1m --type ban
|
docker exec crowdsec cscli decisions add --ip <YOUR IP> -d 1m --type ban
|
||||||
```
|
```
|
||||||
|
|
||||||
To trigger a captcha challenge:
|
To trigger a captcha challenge:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec crowdsec cscli decisions add --ip <YOUR IP> -d 1m --type captcha
|
docker exec crowdsec cscli decisions add --ip <YOUR IP> -d 1m --type captcha
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,6 +7,7 @@ GeoBlock is a Traefik middleware that uses IP-based geolocation to allow or bloc
|
||||||
To integrate GeoBlock into your Traefik setup, follow the steps below:
|
To integrate GeoBlock into your Traefik setup, follow the steps below:
|
||||||
|
|
||||||
1. Add the following configuration to your `/config/traefik/traefik_config.yml` file:
|
1. Add the following configuration to your `/config/traefik/traefik_config.yml` file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
entryPoints:
|
entryPoints:
|
||||||
websecure:
|
websecure:
|
||||||
|
@ -22,6 +23,7 @@ experimental:
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Add the following configuration to your `/config/traefik/dynamic_config.yml` file. Setting `blackListMode: false` enables GeoBlock in whitelist mode, allowing only the specified countries. Remember to add the appropriate countries when traveling. A list of country codes can be found in the [documentation](https://github.com/PascalMinder/geoblock#full-plugin-sample-configuration).
|
2. Add the following configuration to your `/config/traefik/dynamic_config.yml` file. Setting `blackListMode: false` enables GeoBlock in whitelist mode, allowing only the specified countries. Remember to add the appropriate countries when traveling. A list of country codes can be found in the [documentation](https://github.com/PascalMinder/geoblock#full-plugin-sample-configuration).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
http:
|
http:
|
||||||
middlewares:
|
middlewares:
|
||||||
|
@ -45,6 +47,7 @@ http:
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Restart Traefik to apply the changes:
|
3. Restart Traefik to apply the changes:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker restart traefik
|
docker restart traefik
|
||||||
```
|
```
|
||||||
|
@ -52,8 +55,9 @@ docker restart traefik
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
To monitor GeoBlock activities in the Traefik logs, enable logging by setting the following options to `true`:
|
To monitor GeoBlock activities in the Traefik logs, enable logging by setting the following options to `true`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
logLocalRequests: true
|
logLocalRequests: true
|
||||||
logAllowedRequests: true
|
logAllowedRequests: true
|
||||||
logApiRequests: true
|
logApiRequests: true
|
||||||
```
|
```
|
||||||
|
|
|
@ -29,7 +29,7 @@ service:
|
||||||
```yaml
|
```yaml
|
||||||
entryPoints:
|
entryPoints:
|
||||||
metrics:
|
metrics:
|
||||||
address: ':8082'
|
address: ":8082"
|
||||||
|
|
||||||
metrics:
|
metrics:
|
||||||
prometheus:
|
prometheus:
|
||||||
|
@ -102,11 +102,11 @@ scrape_configs:
|
||||||
|
|
||||||
- job_name: traefik
|
- job_name: traefik
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ['172.17.0.1:8082']
|
- targets: ["172.17.0.1:8082"]
|
||||||
|
|
||||||
- job_name: crowdsec
|
- job_name: crowdsec
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ['172.17.0.1:6060']
|
- targets: ["172.17.0.1:6060"]
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Create a folder `data` in `/config/prometheus` and change the ower and owning group:
|
3. Create a folder `data` in `/config/prometheus` and change the ower and owning group:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
|
import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";
|
||||||
|
|
||||||
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
|
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
|
||||||
*/
|
*/
|
||||||
const sidebars: SidebarsConfig = {
|
const sidebars: SidebarsConfig = {
|
||||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
tutorialSidebar: [{ type: "autogenerated", dirName: "." }]
|
||||||
|
|
||||||
// But you can create a sidebar manually
|
// But you can create a sidebar manually
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import CodeBlock from '@theme/CodeBlock';
|
import CodeBlock from "@theme/CodeBlock";
|
||||||
|
|
||||||
const DynamicTraefikConfig: React.FC = () => {
|
const DynamicTraefikConfig: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import CodeBlock from '@theme/CodeBlock';
|
import CodeBlock from "@theme/CodeBlock";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { fetchLatestRelease } from "../lib/fetchLatestRelease";
|
import { fetchLatestRelease } from "../lib/fetchLatestRelease";
|
||||||
|
|
||||||
|
@ -56,11 +56,7 @@ serversTransport:
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return <CodeBlock language="yml">{text}</CodeBlock>;
|
||||||
<CodeBlock language="yml">
|
|
||||||
{text}
|
|
||||||
</CodeBlock>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default StaticTraefikConfig;
|
export default StaticTraefikConfig;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
--ifm-color-primary-lightest: hsl(24.6, 95%, 68%);
|
--ifm-color-primary-lightest: hsl(24.6, 95%, 68%);
|
||||||
|
|
||||||
/* Additional custom variables */
|
/* Additional custom variables */
|
||||||
--ifm-background-color: #FFFFFF;
|
--ifm-background-color: #ffffff;
|
||||||
--ifm-font-color-base: hsl(20, 0%, 10%);
|
--ifm-font-color-base: hsl(20, 0%, 10%);
|
||||||
--ifm-code-font-size: 85%;
|
--ifm-code-font-size: 85%;
|
||||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
--ifm-color-primary-lighter: hsl(20.5, 90.2%, 58%);
|
--ifm-color-primary-lighter: hsl(20.5, 90.2%, 58%);
|
||||||
--ifm-color-primary-lightest: hsl(20.5, 90.2%, 63%);
|
--ifm-color-primary-lightest: hsl(20.5, 90.2%, 63%);
|
||||||
|
|
||||||
--ifm-background-color: #1A1A1A;
|
--ifm-background-color: #1a1a1a;
|
||||||
|
|
||||||
/* Additional custom variables for dark mode */
|
/* Additional custom variables for dark mode */
|
||||||
--ifm-font-color-base: hsl(60, 9.1%, 97.8%);
|
--ifm-font-color-base: hsl(60, 9.1%, 97.8%);
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
--chart-color-4: hsl(280, 65%, 60%);
|
--chart-color-4: hsl(280, 65%, 60%);
|
||||||
--chart-color-5: hsl(340, 75%, 55%);
|
--chart-color-5: hsl(340, 75%, 55%);
|
||||||
|
|
||||||
--ifm-navbar-background-color: #1A1A1A;
|
--ifm-navbar-background-color: #1a1a1a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
|
@ -127,7 +127,6 @@ aside {
|
||||||
border: 1px solid rgb(218, 221, 225);
|
border: 1px solid rgb(218, 221, 225);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
html[data-theme="dark"] .theme-admonition {
|
html[data-theme="dark"] .theme-admonition {
|
||||||
border: 0px solid #333333;
|
border: 0px solid #333333;
|
||||||
}
|
}
|
||||||
|
@ -192,10 +191,10 @@ div[class^="announcementBarContent"] a:hover {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumbs li:nth-child(2) .breadcrumbs__link{
|
.breadcrumbs li:nth-child(2) .breadcrumbs__link {
|
||||||
padding-left: 0px !important;
|
padding-left: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-theme="dark"] {
|
html[data-theme="dark"] {
|
||||||
background-color: #1A1A1A !important;
|
background-color: #1a1a1a !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@ export async function fetchLatestRelease(repo: string) {
|
||||||
`https://api.github.com/repos/${repo}/releases/latest`
|
`https://api.github.com/repos/${repo}/releases/latest`
|
||||||
);
|
);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(
|
throw new Error(`Failed to fetch release info: ${response.statusText}`);
|
||||||
`Failed to fetch release info: ${response.statusText}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
const latestVersion = data.tag_name;
|
const latestVersion = data.tag_name;
|
||||||
|
|
|
@ -10,5 +10,5 @@ export default {
|
||||||
},
|
},
|
||||||
stacks(app) {
|
stacks(app) {
|
||||||
app.stack(DocusaurusStack);
|
app.stack(DocusaurusStack);
|
||||||
}
|
},
|
||||||
} satisfies SSTConfig;
|
} satisfies SSTConfig;
|
||||||
|
|
Loading…
Reference in a new issue