docs: add readme and example of template.json
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,5 @@
|
||||
/target
|
||||
/rules
|
||||
/config
|
||||
template.json
|
||||
config/*
|
||||
!config/template.json
|
||||
default.json
|
91
README.md
Normal file
91
README.md
Normal file
@ -0,0 +1,91 @@
|
||||
# sbrs — sing-box rules sync
|
||||
|
||||
A containerized Rust utility to synchronize and self-host remote rule sets for `sing-box`.
|
||||
|
||||
## Core Workflow
|
||||
|
||||
1. **Reads** a source JSON configuration (`config/template.json`) containing remote URLs (e.g., from GitHub).
|
||||
2. **Downloads** all rule files specified in the source config to a local directory (for example, `./rules`).
|
||||
3. **Cleans up** stale rule files from the local directory that are no longer present in the source config.
|
||||
4. **Generates** a new, client-facing configuration (`config/default.json`) where all remote URLs are rewritten to point to a self-hosted domain.
|
||||
|
||||
The original `template.json` is never modified by this application.
|
||||
|
||||
Upon container start, the utility performs an initial synchronization immediately and then sets up a cron job for subsequent, scheduled runs.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker
|
||||
- Docker Compose
|
||||
|
||||
## Usage via Docker
|
||||
|
||||
**1. Example of possible directory structure**
|
||||
|
||||
Create the following directory structure in your project root before the first run:
|
||||
|
||||
```
|
||||
.
|
||||
├── config/
|
||||
│ └── template.json # Your input config with original URLs
|
||||
├── rules/ # Empty directory for downloaded rule files
|
||||
├── docker/
|
||||
│ ├── Dockerfile
|
||||
│ └── entrypoint.sh
|
||||
└── docker-compose.yml
|
||||
```
|
||||
*Note: `config/default.json` will be generated by the application on the first run.*
|
||||
|
||||
**2. Configuration**
|
||||
|
||||
Edit `docker-compose.yml` to set the required environment variables:
|
||||
|
||||
- `PUID`/`PGID`: Set to your host user's ID (`id -u`) and group ID (`id -g`) to prevent volume permission issues.
|
||||
- `DOMAIN`: The public domain that will serve the rule files (e.g., `rules.mydomain.com`).
|
||||
- `RULE_PATH`: The path on the domain where the files are located (e.g., `/` or `/files`).
|
||||
- `TZ`: The timezone for container logs (e.g., `Etc/UTC`).
|
||||
- `CRON_SCHEDULE`: The schedule for the sync task.
|
||||
|
||||
**3. Run the Service**
|
||||
|
||||
```bash
|
||||
# Build the image and start the service in detached mode
|
||||
docker-compose up --build -d
|
||||
```
|
||||
|
||||
The service will run the sync task immediately upon starting and then again on the schedule defined by `CRON_SCHEDULE`.
|
||||
|
||||
### Common Commands
|
||||
|
||||
```bash
|
||||
# View live logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Trigger a manual sync immediately (without restarting)
|
||||
docker-compose exec sbrs entrypoint.sh manual
|
||||
|
||||
# Stop and remove the container
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
## Local Development
|
||||
|
||||
Requires the [Rust toolchain](https://rustup.rs/).
|
||||
|
||||
**1. Build**
|
||||
```bash
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
**2. Run**
|
||||
|
||||
All arguments are required.
|
||||
|
||||
```bash
|
||||
./target/release/sbrs \
|
||||
--input-config ./config/template.json \
|
||||
--rules-dir ./rules \
|
||||
--output-config ./config/default.json \
|
||||
--domain my.server.com \
|
||||
--rule-path rules
|
||||
```
|
322
config/template.json
Normal file
322
config/template.json
Normal file
@ -0,0 +1,322 @@
|
||||
{
|
||||
"log": {
|
||||
"level": "error",
|
||||
"timestamp": true
|
||||
},
|
||||
"dns": {
|
||||
"cache_capacity": 16384,
|
||||
"servers": [
|
||||
{
|
||||
"tag": "dns-remote",
|
||||
"address": "tls://208.67.222.222",
|
||||
"client_subnet": "{{ ansible_host }}"
|
||||
},
|
||||
{
|
||||
"tag": "dns-local",
|
||||
"address": "195.208.4.1"
|
||||
},
|
||||
{
|
||||
"tag": "dns-block",
|
||||
"address": "rcode://success"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"rule_set": [
|
||||
"category-ads-all",
|
||||
"adobe"
|
||||
],
|
||||
"server": "dns-block",
|
||||
"disable_cache": true
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
"habr.com"
|
||||
],
|
||||
"rule_set": [
|
||||
"telegram",
|
||||
"google"
|
||||
],
|
||||
"server": "dns-remote"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
".ru",
|
||||
".su",
|
||||
".ru.com",
|
||||
".ru.net",
|
||||
"{{ marzban_domain }}",
|
||||
"wikipedia.org"
|
||||
],
|
||||
"domain_keyword": [
|
||||
"xn--",
|
||||
"ozon",
|
||||
"wildberries",
|
||||
"aliexpress"
|
||||
],
|
||||
"rule_set": [
|
||||
"gov-ru",
|
||||
"yandex",
|
||||
"vk",
|
||||
"mailru",
|
||||
"duckduckgo",
|
||||
"mozilla",
|
||||
"category-android-app-download",
|
||||
"gitlab",
|
||||
"debian",
|
||||
"canonical",
|
||||
"torrent-clients"
|
||||
],
|
||||
"server": "dns-local"
|
||||
},
|
||||
{
|
||||
"process_name": [
|
||||
"qbittorrent.exe",
|
||||
"thunderbird.exe",
|
||||
"Obsidian.exe",
|
||||
"javaw.exe"
|
||||
],
|
||||
"server": "dns-local"
|
||||
},
|
||||
{
|
||||
"inbound": [
|
||||
"tun-in"
|
||||
],
|
||||
"server": "dns-remote"
|
||||
}
|
||||
],
|
||||
"final": "dns-local"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tun",
|
||||
"tag": "tun-in",
|
||||
"interface_name": "tun0",
|
||||
"stack": "system",
|
||||
"address": "172.19.0.1/28",
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"sniff_override_destination": true
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"tag": "proxy",
|
||||
"outbounds": null
|
||||
},
|
||||
{
|
||||
"type": "urltest",
|
||||
"tag": "Fastest",
|
||||
"outbounds": null,
|
||||
"url": "https://www.gstatic.com/generate_204",
|
||||
"interval": "15m0s"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
},
|
||||
{
|
||||
"ip_is_private": true,
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": [
|
||||
"category-ads-all",
|
||||
"adobe"
|
||||
],
|
||||
"action": "reject",
|
||||
"method": "drop"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
"habr.com"
|
||||
],
|
||||
"rule_set": [
|
||||
"telegram",
|
||||
"google"
|
||||
],
|
||||
"outbound": "proxy"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
".ru",
|
||||
".su",
|
||||
".ru.com",
|
||||
".ru.net",
|
||||
"{{ marzban_domain }}",
|
||||
"wikipedia.org"
|
||||
],
|
||||
"domain_keyword": [
|
||||
"xn--",
|
||||
"ozon",
|
||||
"wildberries",
|
||||
"aliexpress"
|
||||
],
|
||||
"ip_cidr": [
|
||||
"{{ ansible_host }}"
|
||||
],
|
||||
"rule_set": [
|
||||
"gov-ru",
|
||||
"yandex",
|
||||
"vk",
|
||||
"mailru",
|
||||
"duckduckgo",
|
||||
"mozilla",
|
||||
"category-android-app-download",
|
||||
"gitlab",
|
||||
"debian",
|
||||
"canonical",
|
||||
"torrent-clients"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"action": "resolve",
|
||||
"strategy": "prefer_ipv4"
|
||||
},
|
||||
{
|
||||
"rule_set": [
|
||||
"geoip-ru"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"process_name": [
|
||||
"qbittorrent.exe",
|
||||
"thunderbird.exe",
|
||||
"Obsidian.exe",
|
||||
"javaw.exe"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
"deb.home.net"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"inbound": [
|
||||
"tun-in"
|
||||
],
|
||||
"outbound": "proxy"
|
||||
}
|
||||
],
|
||||
"rule_set": [
|
||||
{
|
||||
"tag": "torrent-clients",
|
||||
"type": "remote",
|
||||
"format": "source",
|
||||
"url": "https://raw.githubusercontent.com/FPPweb3/sb-rule-sets/main/torrent-clients.json"
|
||||
},
|
||||
{
|
||||
"tag": "geoip-ru",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geoip/raw/rule-set/geoip-ru.srs"
|
||||
},
|
||||
{
|
||||
"tag": "gov-ru",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-category-gov-ru.srs"
|
||||
},
|
||||
{
|
||||
"tag": "yandex",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-yandex.srs"
|
||||
},
|
||||
{
|
||||
"tag": "google",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-google.srs"
|
||||
},
|
||||
{
|
||||
"tag": "telegram",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-telegram.srs"
|
||||
},
|
||||
{
|
||||
"tag": "vk",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-vk.srs"
|
||||
},
|
||||
{
|
||||
"tag": "mailru",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-mailru.srs"
|
||||
},
|
||||
{
|
||||
"tag": "duckduckgo",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-duckduckgo.srs"
|
||||
},
|
||||
{
|
||||
"tag": "mozilla",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-mozilla.srs"
|
||||
},
|
||||
{
|
||||
"tag": "category-android-app-download",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-category-android-app-download.srs"
|
||||
},
|
||||
{
|
||||
"tag": "adobe",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-adobe.srs"
|
||||
},
|
||||
{
|
||||
"tag": "gitlab",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-gitlab.srs"
|
||||
},
|
||||
{
|
||||
"tag": "debian",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-debian.srs"
|
||||
},
|
||||
{
|
||||
"tag": "canonical",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-canonical.srs"
|
||||
},
|
||||
{
|
||||
"tag": "category-ads-all",
|
||||
"type": "remote",
|
||||
"format": "binary",
|
||||
"url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-category-ads-all.srs"
|
||||
}
|
||||
],
|
||||
"auto_detect_interface": true,
|
||||
"override_android_vpn": true
|
||||
},
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user