From 03e56bb3b9ad1373e970babd275eab54140fa5f4 Mon Sep 17 00:00:00 2001 From: "Nanang F. Rozi" Date: Wed, 15 Jul 2026 18:29:02 +0700 Subject: [PATCH 1/3] feat: add PROMETHEUS_ALLOWLIST for specific firewall IP rules - Add logic in install.sh to apply firewall rules only to specific IPs/CIDRs if PROMETHEUS_ALLOWLIST is defined. - Update README.md environment variables table. - Add 'proto' to cspell.json to fix spelling check failure. --- README.md | 1 + cspell.json | 1 + install.sh | 55 +++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6017334..4516e6a 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ curl ... | INSTALL_NODE_EXPORTER_VERSION="v1.5.0" INSTALL_NODE_EXPORTER_SKIP_STA | `INSTALL_NODE_EXPORTER_VERSION` | Version of Node exporter to download | `latest` | | `INSTALL_NODE_EXPORTER_BIN_DIR` | Directory to install Node exporter binary and uninstall script | `/usr/local/bin` or `/opt/bin` | | `INSTALL_NODE_EXPORTER_SYSTEMD_DIR` | Directory to install systemd service files | `/etc/systemd/system` | +| `PROMETHEUS_ALLOWLIST` | Comma-separated list of IPs or CIDRs to allow in the firewall (e.g., `10.10.10.5,10.20.0.0/24`) | | | `INSTALL_NODE_EXPORTER_EXEC` | Node exporter arguments | ## Contributing diff --git a/cspell.json b/cspell.json index 524480f..aec5244 100644 --- a/cspell.json +++ b/cspell.json @@ -26,6 +26,7 @@ "openrc", "pidfile", "policycoreutils", + "proto", "respawn", "restorecon", "runlevels", diff --git a/install.sh b/install.sh index c2ad785..a77712e 100644 --- a/install.sh +++ b/install.sh @@ -597,22 +597,45 @@ systemd_disable() { firewall_rule() { _firewall_path=$(command -v "$FIREWALL" 2>&1 || :) - case $FIREWALL in - firewall-cmd) - printf "%s\n%s\n" \ - "$_firewall_path --add-port=$NODE_EXPORTER_PORT/tcp --permanent" \ - "$_firewall_path --reload" - ;; - ufw) - printf "%s\n" \ - "$_firewall_path allow $NODE_EXPORTER_PORT/tcp" - ;; - iptables) - printf "%s\n" \ - "$_firewall_path -A INPUT -p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" - ;; - *) fatal "Unknown firewall '$FIREWALL'" ;; - esac + if [ -n "$PROMETHEUS_ALLOWLIST" ]; then + _ips=$(echo "$PROMETHEUS_ALLOWLIST" | tr ',' ' ') + case $FIREWALL in + firewall-cmd) + for _ip in $_ips; do + printf "%s\n" "$_firewall_path --add-rich-rule=\"rule family='ipv4' source address='$_ip' port port='$NODE_EXPORTER_PORT' protocol='tcp' accept\" --permanent" + done + printf "%s\n" "$_firewall_path --reload" + ;; + ufw) + for _ip in $_ips; do + printf "%s\n" "$_firewall_path allow from $_ip to any port $NODE_EXPORTER_PORT proto tcp" + done + ;; + iptables) + for _ip in $_ips; do + printf "%s\n" "$_firewall_path -A INPUT -s $_ip -p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" + done + ;; + *) fatal "Unknown firewall '$FIREWALL'" ;; + esac + else + case $FIREWALL in + firewall-cmd) + printf "%s\n%s\n" \ + "$_firewall_path --add-port=$NODE_EXPORTER_PORT/tcp --permanent" \ + "$_firewall_path --reload" + ;; + ufw) + printf "%s\n" \ + "$_firewall_path allow $NODE_EXPORTER_PORT/tcp" + ;; + iptables) + printf "%s\n" \ + "$_firewall_path -A INPUT -p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" + ;; + *) fatal "Unknown firewall '$FIREWALL'" ;; + esac + fi } # Write openrc service file From 03417373c13f4d0a34bb1b6d9a54bfb62a89a273 Mon Sep 17 00:00:00 2001 From: "Nanang F. Rozi" Date: Thu, 16 Jul 2026 08:32:38 +0700 Subject: [PATCH 2/3] fix: Refine the code and consistency --- README.md | 26 +++++++++---------- install.sh | 73 +++++++++++++++++++++++++++--------------------------- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 4516e6a..df014ec 100644 --- a/README.md +++ b/README.md @@ -42,19 +42,19 @@ curl ... | INSTALL_NODE_EXPORTER_VERSION="v1.5.0" INSTALL_NODE_EXPORTER_SKIP_STA ## Environment variables -| **Name** | **Description** | **Default** | -| ------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------ | -| `INSTALL_NODE_EXPORTER_SKIP_DOWNLOAD` | Skip downloading Node exporter. There must already be an executable binary at `/node_exporter` | `false` | -| `INSTALL_NODE_EXPORTER_FORCE_RESTART` | Force restarting Node exporter service | `false` | -| `INSTALL_NODE_EXPORTER_SKIP_ENABLE` | Skip enabling Node exporter service at startup | `false` | -| `INSTALL_NODE_EXPORTER_SKIP_START` | Skip starting Node exporter service | `false` | -| `INSTALL_NODE_EXPORTER_SKIP_FIREWALL` | Skip firewall rules. Supported firewalls are `firewall-cmd`, `ufw` and `iptables` | `false` | -| `INSTALL_NODE_EXPORTER_SKIP_SELINUX` | Skip changing `SELinux` context for Node exporter binary | `false` | -| `INSTALL_NODE_EXPORTER_VERSION` | Version of Node exporter to download | `latest` | -| `INSTALL_NODE_EXPORTER_BIN_DIR` | Directory to install Node exporter binary and uninstall script | `/usr/local/bin` or `/opt/bin` | -| `INSTALL_NODE_EXPORTER_SYSTEMD_DIR` | Directory to install systemd service files | `/etc/systemd/system` | -| `PROMETHEUS_ALLOWLIST` | Comma-separated list of IPs or CIDRs to allow in the firewall (e.g., `10.10.10.5,10.20.0.0/24`) | | -| `INSTALL_NODE_EXPORTER_EXEC` | Node exporter arguments | +| **Name** | **Description** | **Default** | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------ | +| `INSTALL_NODE_EXPORTER_SKIP_DOWNLOAD` | Skip downloading Node exporter. There must already be an executable binary at `/node_exporter` | `false` | +| `INSTALL_NODE_EXPORTER_FORCE_RESTART` | Force restarting Node exporter service | `false` | +| `INSTALL_NODE_EXPORTER_SKIP_ENABLE` | Skip enabling Node exporter service at startup | `false` | +| `INSTALL_NODE_EXPORTER_SKIP_START` | Skip starting Node exporter service | `false` | +| `INSTALL_NODE_EXPORTER_SKIP_FIREWALL` | Skip firewall rules. Supported firewalls are `firewall-cmd`, `ufw` and `iptables` | `false` | +| `INSTALL_NODE_EXPORTER_SKIP_SELINUX` | Skip changing `SELinux` context for Node exporter binary | `false` | +| `INSTALL_NODE_EXPORTER_VERSION` | Version of Node exporter to download | `latest` | +| `INSTALL_NODE_EXPORTER_BIN_DIR` | Directory to install Node exporter binary and uninstall script | `/usr/local/bin` or `/opt/bin` | +| `INSTALL_NODE_EXPORTER_SYSTEMD_DIR` | Directory to install systemd service files | `/etc/systemd/system` | +| `INSTALL_NODE_EXPORTER_FIREWALL_ALLOWLIST` | Comma-separated list of Prometheus server IPs or CIDRs allowed to scrape metrics (e.g., `10.10.10.5,10.20.0.0/24`) | | +| `INSTALL_NODE_EXPORTER_EXEC` | Node exporter arguments | ## Contributing diff --git a/install.sh b/install.sh index a77712e..0ee6f68 100644 --- a/install.sh +++ b/install.sh @@ -597,45 +597,44 @@ systemd_disable() { firewall_rule() { _firewall_path=$(command -v "$FIREWALL" 2>&1 || :) - if [ -n "$PROMETHEUS_ALLOWLIST" ]; then - _ips=$(echo "$PROMETHEUS_ALLOWLIST" | tr ',' ' ') - case $FIREWALL in - firewall-cmd) - for _ip in $_ips; do - printf "%s\n" "$_firewall_path --add-rich-rule=\"rule family='ipv4' source address='$_ip' port port='$NODE_EXPORTER_PORT' protocol='tcp' accept\" --permanent" - done - printf "%s\n" "$_firewall_path --reload" - ;; - ufw) - for _ip in $_ips; do - printf "%s\n" "$_firewall_path allow from $_ip to any port $NODE_EXPORTER_PORT proto tcp" - done - ;; - iptables) - for _ip in $_ips; do - printf "%s\n" "$_firewall_path -A INPUT -s $_ip -p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" - done - ;; - *) fatal "Unknown firewall '$FIREWALL'" ;; - esac + _ips="" + if [ -n "$INSTALL_NODE_EXPORTER_FIREWALL_ALLOWLIST" ]; then + _ips=$(echo "$INSTALL_NODE_EXPORTER_FIREWALL_ALLOWLIST" | tr ',' ' ') + fi + + # Ensure the loop executes at least once even if _ips is empty + if [ -z "$_ips" ]; then + set -- "" else - case $FIREWALL in - firewall-cmd) - printf "%s\n%s\n" \ - "$_firewall_path --add-port=$NODE_EXPORTER_PORT/tcp --permanent" \ - "$_firewall_path --reload" - ;; - ufw) - printf "%s\n" \ - "$_firewall_path allow $NODE_EXPORTER_PORT/tcp" - ;; - iptables) - printf "%s\n" \ - "$_firewall_path -A INPUT -p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" - ;; - *) fatal "Unknown firewall '$FIREWALL'" ;; - esac + # shellcheck disable=SC2086 + set -- $_ips fi + + case $FIREWALL in + firewall-cmd) + for _ip in "$@"; do + _source="" + [ -n "$_ip" ] && _source="source address='$_ip' " + printf "%s\n" "$_firewall_path --add-rich-rule=\"rule family='ipv4' ${_source}port port='$NODE_EXPORTER_PORT' protocol='tcp' accept\" --permanent" + done + printf "%s\n" "$_firewall_path --reload" + ;; + ufw) + for _ip in "$@"; do + _source="any" + [ -n "$_ip" ] && _source="$_ip" + printf "%s\n" "$_firewall_path allow from $_source to any port $NODE_EXPORTER_PORT proto tcp" + done + ;; + iptables) + for _ip in "$@"; do + _source="" + [ -n "$_ip" ] && _source="-s $_ip " + printf "%s\n" "$_firewall_path -A INPUT ${_source}-p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" + done + ;; + *) fatal "Unknown firewall '$FIREWALL'" ;; + esac } # Write openrc service file From 4edf3eb1d053944b4fbccafaaa556a2b8428aa94 Mon Sep 17 00:00:00 2001 From: "Nanang F. Rozi" Date: Thu, 16 Jul 2026 09:01:58 +0700 Subject: [PATCH 3/3] fix: re-test --- install.sh | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/install.sh b/install.sh index 0ee6f68..509c8ab 100644 --- a/install.sh +++ b/install.sh @@ -602,35 +602,24 @@ firewall_rule() { _ips=$(echo "$INSTALL_NODE_EXPORTER_FIREWALL_ALLOWLIST" | tr ',' ' ') fi - # Ensure the loop executes at least once even if _ips is empty - if [ -z "$_ips" ]; then - set -- "" - else - # shellcheck disable=SC2086 - set -- $_ips - fi + # shellcheck disable=SC2086 + set -- $_ips case $FIREWALL in firewall-cmd) for _ip in "$@"; do - _source="" - [ -n "$_ip" ] && _source="source address='$_ip' " - printf "%s\n" "$_firewall_path --add-rich-rule=\"rule family='ipv4' ${_source}port port='$NODE_EXPORTER_PORT' protocol='tcp' accept\" --permanent" + printf "%s\n" "$_firewall_path --add-rich-rule=\"rule family='ipv4' source address='$_ip' port port='$NODE_EXPORTER_PORT' protocol='tcp' accept\" --permanent" done - printf "%s\n" "$_firewall_path --reload" + [ $# -gt 0 ] && printf "%s\n" "$_firewall_path --reload" ;; ufw) for _ip in "$@"; do - _source="any" - [ -n "$_ip" ] && _source="$_ip" - printf "%s\n" "$_firewall_path allow from $_source to any port $NODE_EXPORTER_PORT proto tcp" + printf "%s\n" "$_firewall_path allow from $_ip to any port $NODE_EXPORTER_PORT proto tcp" done ;; iptables) for _ip in "$@"; do - _source="" - [ -n "$_ip" ] && _source="-s $_ip " - printf "%s\n" "$_firewall_path -A INPUT ${_source}-p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" + printf "%s\n" "$_firewall_path -A INPUT -s $_ip -p tcp --dport $NODE_EXPORTER_PORT -m state --state NEW -j ACCEPT" done ;; *) fatal "Unknown firewall '$FIREWALL'" ;;