Compare commits

...

5 Commits
v1.2 ... main

Author SHA1 Message Date
13379a3419 Merge branch 'wip-python' 2025-06-06 12:40:32 +00:00
fedbe1e227 Fixed wrong repo url 2025-06-06 12:39:59 +00:00
15ba895b04 Merge pull request 'v1.3 - Excluding list (all countries except the specified ones)' (#6) from wip-python into main
Reviewed-on: #6
2025-06-06 14:17:11 +02:00
7676d34a39 Excluding list 2025-06-06 12:09:41 +00:00
c8451688ca Github notice 2025-06-06 11:12:15 +00:00
2 changed files with 61 additions and 17 deletions

View File

@ -7,7 +7,10 @@
**Adguard CIDRE Sync** - A bot to synchronize adguard clients disallow list with countries CIDR list of your choices. **Adguard CIDRE Sync** - A bot to synchronize adguard clients disallow list with countries CIDR list of your choices.
*The code is partially generated by AI* > [!NOTE]
>_The code was partially written and structured using a generative AI._
>
>_Github repo is a mirror of https://git.djeex.fr/Djeex/adguard-cidre. You'll find full package, history and release note there._
## Sommaire ## Sommaire
@ -34,7 +37,7 @@
| Variable | Description | Example | Possible Values | | Variable | Description | Example | Possible Values |
|--------------------------|--------------------------------------------------------------------------|-----------------------------|---------------------------------------------| |--------------------------|--------------------------------------------------------------------------|-----------------------------|---------------------------------------------|
| `TZ` | Timezone of the container to correctly schedule updates | `Europe/Paris` | Any valid timezone (e.g., `UTC`, `America/New_York`, etc.) | | `TZ` | Timezone of the container to correctly schedule updates | `Europe/Paris` | Any valid timezone (e.g., `UTC`, `America/New_York`, etc.) |
| `BLOCK_COUNTRIES` | List of country codes for CIDR lists, separated by commas | `cn,ru,ir` | ISO 2-letter country codes | | `BLOCK_COUNTRIES` | List of country codes for CIDR lists, separated by commas. You can also define an exclude list (all countries except the specified ones) by prefixing each country code with !. Mixing inclusion and exclusion codes is not supported. | including list : `cn,ru,ir`, excluding list : `!cn,!ru,!ir` | ISO 2-letter country codes |
| `BLOCKLIST_CRON_TYPE` | Scheduling type: `daily` or `weekly` | `daily` | `daily`, `weekly` | | `BLOCKLIST_CRON_TYPE` | Scheduling type: `daily` or `weekly` | `daily` | `daily`, `weekly` |
| `BLOCKLIST_CRON_TIME` | Time to run update in `HH:MM` 24-hour format | `06:00` | 24-hour time format | | `BLOCKLIST_CRON_TIME` | Time to run update in `HH:MM` 24-hour format | `06:00` | 24-hour time format |
| `BLOCKLIST_CRON_DAY` | Day of the week for weekly schedule (e.g., `mon`, `tue`, etc.) | `mon` | `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun` | | `BLOCKLIST_CRON_DAY` | Day of the week for weekly schedule (e.g., `mon`, `tue`, etc.) | `mon` | `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun` |

View File

@ -6,6 +6,7 @@ import requests
import yaml import yaml
import schedule import schedule
import time import time
import re
from pathlib import Path from pathlib import Path
logging.basicConfig( logging.basicConfig(
@ -18,14 +19,15 @@ ADGUARD_YAML = Path("/adguard/AdGuardHome.yaml")
TMP_YAML = ADGUARD_YAML.parent / (ADGUARD_YAML.name + ".tmp") TMP_YAML = ADGUARD_YAML.parent / (ADGUARD_YAML.name + ".tmp")
MANUAL_IPS_FILE = Path("/adguard/manually_blocked_ips.conf") MANUAL_IPS_FILE = Path("/adguard/manually_blocked_ips.conf")
CIDR_BASE_URL = "https://raw.githubusercontent.com/vulnebify/cidre/main/output/cidr/ipv4" CIDR_BASE_URL = "https://raw.githubusercontent.com/vulnebify/cidre/main/output/cidr/ipv4"
COUNTRY_LIST_URL = "https://raw.githubusercontent.com/vulnebify/cidre/refs/heads/main/cidre/countries.py"
FIRST_BACKUP = ADGUARD_YAML.parent / "AdGuardHome.yaml.first-start.bak" FIRST_BACKUP = ADGUARD_YAML.parent / "AdGuardHome.yaml.first-start.bak"
LAST_UPDATE_BACKUP = ADGUARD_YAML.parent / "AdGuardHome.yaml.last-update.bak" LAST_UPDATE_BACKUP = ADGUARD_YAML.parent / "AdGuardHome.yaml.last-update.bak"
BLOCK_COUNTRIES = os.getenv("BLOCK_COUNTRIES", "") BLOCK_COUNTRIES = os.getenv("BLOCK_COUNTRIES", "")
BLOCKLIST_CRON_TYPE = os.getenv("BLOCKLIST_CRON_TYPE", "daily").lower() # daily or weekly BLOCKLIST_CRON_TYPE = os.getenv("BLOCKLIST_CRON_TYPE", "daily").lower()
BLOCKLIST_CRON_TIME = os.getenv("BLOCKLIST_CRON_TIME", "06:00") # HH:MM format BLOCKLIST_CRON_TIME = os.getenv("BLOCKLIST_CRON_TIME", "06:00")
BLOCKLIST_CRON_DAY = os.getenv("BLOCKLIST_CRON_DAY", "mon").lower() # only if weekly BLOCKLIST_CRON_DAY = os.getenv("BLOCKLIST_CRON_DAY", "mon").lower()
ADGUARD_CONTAINER_NAME = os.getenv("ADGUARD_CONTAINER_NAME", "adguardhome") ADGUARD_CONTAINER_NAME = os.getenv("ADGUARD_CONTAINER_NAME", "adguardhome")
DOCKER_API_URL = os.getenv("DOCKER_API_URL", "http://socket-proxy-adguard:2375") DOCKER_API_URL = os.getenv("DOCKER_API_URL", "http://socket-proxy-adguard:2375")
@ -41,6 +43,44 @@ def backup_last_update():
logging.info(f"Creating last update backup: {LAST_UPDATE_BACKUP}") logging.info(f"Creating last update backup: {LAST_UPDATE_BACKUP}")
LAST_UPDATE_BACKUP.write_text(ADGUARD_YAML.read_text()) LAST_UPDATE_BACKUP.write_text(ADGUARD_YAML.read_text())
def fetch_all_country_codes():
try:
resp = requests.get(COUNTRY_LIST_URL, timeout=15)
resp.raise_for_status()
matches = re.findall(r'"([A-Z]{2})"', resp.text)
return set(code.lower() for code in matches)
except Exception as e:
logging.error(f"Failed to fetch available country codes: {e}")
return set()
def get_selected_countries():
if not BLOCK_COUNTRIES:
logging.error("BLOCK_COUNTRIES is not set. Skipping update.")
return []
raw_codes = [c.strip() for c in BLOCK_COUNTRIES.split(",") if c.strip()]
if not raw_codes:
logging.error("No valid country codes provided.")
return []
is_exclusion = all(c.startswith("!") for c in raw_codes)
is_inclusion = all(not c.startswith("!") for c in raw_codes)
if not (is_exclusion or is_inclusion):
logging.error("Mixed syntax in BLOCK_COUNTRIES. Use only inclusion (e.g. 'fr,de') or only exclusion (e.g. '!fr,!de').")
sys.exit(1)
available = fetch_all_country_codes()
selected = {c.lstrip("!") for c in raw_codes}
unknown = selected - available
if unknown:
logging.warning(f"Unknown country codes: {', '.join(sorted(unknown))}")
if is_exclusion:
return sorted(available - selected)
else:
return sorted(selected & available)
def download_cidr_lists(countries): def download_cidr_lists(countries):
combined_ips = [] combined_ips = []
for code in countries: for code in countries:
@ -76,12 +116,15 @@ def update_yaml_with_ips(ips):
logging.error(f"{ADGUARD_YAML} does not exist. Cannot update.") logging.error(f"{ADGUARD_YAML} does not exist. Cannot update.")
return False return False
data = None try:
with ADGUARD_YAML.open() as f: with ADGUARD_YAML.open() as f:
data = yaml.safe_load(f) data = yaml.safe_load(f)
except Exception as e:
logging.error(f"Failed to parse YAML file: {e}")
return False
if data is None: if not isinstance(data, dict):
logging.error(f"Failed to parse YAML file {ADGUARD_YAML}") logging.error("Invalid YAML format.")
return False return False
data['dns']['disallowed_clients'] = ips data['dns']['disallowed_clients'] = ips
@ -106,12 +149,12 @@ def restart_adguard_container():
logging.error(f"Error restarting container: {e}") logging.error(f"Error restarting container: {e}")
def update_blocklist(): def update_blocklist():
if not BLOCK_COUNTRIES: countries = get_selected_countries()
logging.error("No countries specified in BLOCK_COUNTRIES environment variable. Skipping update.") if not countries:
logging.error("No valid countries to process. Skipping update.")
return return
countries_list = [c.strip() for c in BLOCK_COUNTRIES.split(",") if c.strip()] cidr_ips = download_cidr_lists(countries)
cidr_ips = download_cidr_lists(countries_list)
manual_ips = read_manual_ips() manual_ips = read_manual_ips()
combined_ips = cidr_ips + manual_ips combined_ips = cidr_ips + manual_ips
@ -146,9 +189,7 @@ def schedule_job():
def main(): def main():
logging.info("Starting blocklist scheduler...") logging.info("Starting blocklist scheduler...")
backup_first_start() backup_first_start()
update_blocklist() update_blocklist()
schedule_job() schedule_job()
while True: while True: