From 0daffec79c2cdfda05a1f7d885dd09a22c4ac04b Mon Sep 17 00:00:00 2001 From: Angel Stoyanov Date: Thu, 26 Jun 2025 17:57:18 +0100 Subject: [PATCH] Update README.md --- README.md | 155 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 78b123a..4a1d7e0 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,134 @@ # zabbix-domain-expiry -## Description +Monitor domain expiration dates using RDAP or WHOIS protocols. -Zabbix template to check domain registration expiry +
-Tested on: -* Zabbix 6.4 +## Features +- **(NEW) RDAP and WHOIS Support**: Queries domain expiration via RDAP (preferred) with fallback to WHOIS. +- **(NEW) JSON Output**: Script outputs JSON for easy parsing by Zabbix. +- **(NEW) Debug Mode**: Detailed debug output for troubleshooting. -## Requirements: -* Zabbix v6.4 or later -* whois installed on zabbix server (GNU utils) +## Requirements +- **Zabbix Server/Agent**: Version 6.4 or higher +- **OS**: GNU/Linux systems +- **Shell Script Dependencies**: + - `curl`: For RDAP queries. + - `mktemp`: For temporary files. + - `date`: For date calculations. + - `whois`: For WHOIS queries. + - `grep`: For parsing output. + - `awk`: For parsing WHOIS and RDAP data. + - `jq`: For parsing RDAP JSON responses. -## Setup: +## Tested on +- **OS**: RHEL/Rocky (bash) and Debian/Ubuntu (dash) +- **Zabbix Server**: 6.4 +- **Note**: Shell script is *mostly* POSIX compliant so should be widely compatible -1. Copy shell script check_domain.sh to your Zabbix server external scripts dir (default: /usr/lib/zabbix/externalscripts/) -2. Make it executable (e.g. chmod +x /usr/lib/zabbix/externalscripts/check_domain.sh) -2. Import yaml template to your zabbix server -3. Create a host with a domain name as the Host name and attach the template to the host. Make sure required macros are filled out +## Installation (Zabbix server) -## Required macros: +### Install Dependencies +Ensure the required dependencies are installed on your system. -|Macro|Default Value|Description| -|-----|-------------|-----------| -|{$EXP_CRIT}|7|Threshold value of days remaining before triggering a HIGH alert| -|{$EXP_WARN}|30|Threshold value of days remaining before triggering a WARNING alert| -|{$WHOIS_SERVER}|""|Specify the whois service to use (e.g whois.godaddy.com). Default value "" uses the whois util config default| +**For RHEL/Rocky**: +```bash +sudo dnf install -y epel-release +sudo dnf install -y curl coreutils whois grep gawk jq +``` -## Items: +**For Debian/Ubuntu**: +```bash +sudo apt update +sudo apt install -y curl coreutils whois grep gawk jq +``` -|Name|Description|Type|Key and additional info| -|----|-----------|----|----| -|Domain Check Expiry|Run external script to check domain registration status|External check|check_domain.sh["-d",{HOST.NAME},"-s",{$WHOIS_SERVER},"-w",{$EXP_WARN},"-c",{$EXP_CRIT}], Update interval: 1d| -|Domain Check Expiry: Status|Get "State:" from script output|Dependant item|domain_check_expiry.status| -|Domain Check Expiry: Expire Date|Get "Expire date:" from script output|Dependant item|domain_check_expiry.expire_date| -|Domain Check Expiry: Days Since Expired|Get "Days since expired:" from script output|Dependant item|domain_check_expiry.days_since_expired| -|Domain Check Expiry: Days Left|Get "Days left:" from script output|Dependant item|domain_check_expiry.days_left| +### Setup Steps +1. **Clone the Repository**: + ```bash + git clone https://github.com/a-stoyanov/zabbix-domain-expiry.git + cd zabbix-domain-expiry + ``` +2. Copy shell script `check_domain.sh` to your Zabbix server external scripts dir (default: `/usr/lib/zabbix/externalscripts/`) +3. Make it executable (e.g. `chmod +x /usr/lib/zabbix/externalscripts/check_domain.sh`) +4. Import yaml template `zbx_domain_expiry.yaml` to your zabbix server +5. Create a host with a domain name (e.g: `example.com`) as the Host name and attach the template to the host -## Triggers: -Note: There is operational data included in the triggers to display live data from checks. You can include this in your "Problems" dashboard widget > Show operational data > With problem name +## Upgrading -|Name|Description|Expression|Severity| -|----|-----------|----------|--------| -|Domain Expiry: {HOST.NAME} - {ITEM.LASTVALUE1}|Raise alert in case of script output error|find(/Domain Expiry/domain_check_expiry.status,#1,"like","UNKNOWN")=1|Not classified| -|Domain Expiry: {HOST.NAME} will expire soon|Raise alert when number days remaining is below threshold|last(/Domain Expiry/domain_check_expiry.days_left)<={$EXP_WARN} and last(/Domain Expiry/domain_check_expiry.expire_date)<>0|Warning| -|Domain Expiry: {HOST.NAME} will expire soon|Raise alert when number days remaining is below threshold|last(/Domain Expiry/domain_check_expiry.days_left)<={$EXP_CRIT} and last(/Domain Expiry/domain_check_expiry.expire_date)<>0|High| -|Domain Expiry: {HOST.NAME} has expired|Raise alert domain registarion has expired|find(/Domain Expiry/domain_check_expiry.status,#1,"like","EXPIRED")=1 and last(/Domain Expiry/domain_check_expiry.days_since_expired)>=0 and last(/Domain Expiry/domain_check_expiry.expire_date)<>0|Disaster| +If you are upgrading from the old version just import/overwrite the existing template and copy/overwite the old shell script with new version + +## Configuration + +### Template Macros +The template uses the following macros, configurable at the host or template level: + +| Macro | Default Value | Description | +|------------------|---------------|-----------------------------------------------------------------------------| +| `{$EXP_CRIT}` | 7 | Days remaining before triggering a HIGH (critical) alert. | +| `{$EXP_WARN}` | 30 | Days remaining before triggering a WARNING alert. | +| `{$RDAP_SERVER}` | (empty) | Specify which RDAP server to use. Default empty value will use IANA lookup. | +| `{$WHOIS_SERVER}`| (empty) | Specify which WHOIS server to use. Default empty value will use rfc-3912 lookup. | + +### Template Items +The template includes the following items to monitor domain expiration: + +| Name | Key | Type | Value Type | Description | +|---------------------|----------------------------------------|------------|------------|-----------------------------------------------------------------------------| +| Days Left | `check_domain.days_left` | Dependent | Float | Number of days until the domain expires. | +| Days Since Expired | `check_domain.days_since_expired` | Dependent | Float | Number of days since the domain expired (0 if not expired). | +| Expire Date | `check_domain.expire_date` | Dependent | Text | Domain expiration date in YYYY-MM-DD format. | +| Message | `check_domain.message` | Dependent | Text | Status message returned by the script. | +| State | `check_domain.state` | Dependent | Text | Domain status: OK, WARNING, CRITICAL, or UNKNOWN. | +| Check Domain | `check_domain.sh[...]` | External | Text | Executes the external script to check domain status. | + +### Template Triggers +The template defines the following triggers for alerting: + +| Name | Expression | Priority | Description | +|-----------------------------------------|---------------------------------------------------------------------------|-----------|-----------------------------------------------------------------------------| +| Domain Expiry: {HOST.HOST} - {ITEM.LASTVALUE2} | `last(/Domain Expiry/check_domain.state)="UNKNOWN" and last(/Domain Expiry/check_domain.message)<>0` | Not Classified | Alerts if the script cannot determine the domain's expiration status. | +| Domain Expiry: {HOST.HOST} has expired | `last(/Domain Expiry/check_domain.state)="CRITICAL" and last(/Domain Expiry/check_domain.days_since_expired)>0 and last(/Domain Expiry/check_domain.expire_date)<>0` | Disaster | Alerts if the domain has expired. | +| Domain Expiry: {HOST.HOST} will expire soon (Critical) | `last(/Domain Expiry/check_domain.state)="CRITICAL" and last(/Domain Expiry/check_domain.days_left)<={$EXP_CRIT} and last(/Domain Expiry/check_domain.expire_date)<>0` | High | Alerts if days remaining are below the critical threshold (`{$EXP_CRIT}`). | +| Domain Expiry: {HOST.HOST} will expire soon (Warning) | `last(/Domain Expiry/check_domain.state)="WARNING" and last(/Domain Expiry/check_domain.days_left)<={$EXP_WARN} and last(/Domain Expiry/check_domain.expire_date)<>0` | Warning | Alerts if days remaining are below the warning threshold (`{$EXP_WARN}`). | + +### Script Usage +The `check_domain.sh` script can be run manually for testing: + +```bash +./check_domain.sh -d example.com +./check_domain.sh -d example.com -w 30 -c 7 -r '' -s '' +``` + +**Options**: +- `-d, --domain`: Domain name to check (required). +- `-w, --warning`: Warning threshold in days (default: 30). +- `-c, --critical`: Critical threshold in days (default: 7). +- `-r, --rdap-server`: RDAP server URL (use `""` for IANA lookup). +- `-s, --whois-server`: WHOIS server hostname (use `""` for default lookup). +- `-P, --path`: Path to `whois` executable. +- `-z, --debug`: Enable debug output to stderr. +- `-h, --help`: Display help. +- `-V, --version`: Display version in JSON format. + +**Example Output**: +```json +{"state":"OK","days_left":365,"days_since_expired":0,"expire_date":"2026-06-24","message":"State: OK ; Days left: 365 ; Expire date: 2026-06-24"} +``` + +## Debugging +- Enable debug mode in the script with `-z`: + ```bash + ./check_domain.sh -d example.com -z + ``` +- Check Zabbix logs for issues with script execution. +- Verify RDAP/WHOIS server availability and response format outside of script + +## Notes +- The script prioritizes RDAP for faster, structured queries but falls back to WHOIS if RDAP fails. +- WHOIS awk parsing supports various date formats but may fail if whois query returns non-standard responses (no awk pattern match). +- Rate limits on WHOIS servers may trigger UNKNOWN states; increase or use custom check interval to mitigate (the default 1d is very reasonable). +- For some specific TLDs (e.g: `.uk`, `.br`) RDAP URL paths may have to be adjusted due to non-standard URL format. See `adjust_rdap_url()` function, which already handles /uk/ path adjustment. + +## License +This project is licensed under the Apache License 2.0