@chain305/x-security 0.2.6 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/bin/scripts/README.md +39 -39
- package/bin/scripts/{writ-refresh.service → x-security-refresh.service} +4 -4
- package/bin/scripts/{writ-refresh.sh → x-security-refresh.sh} +11 -11
- package/bin/scripts/{writ-refresh.timer → x-security-refresh.timer} +3 -3
- package/bin/scripts/{writ-resolve.sh → x-security-resolve.sh} +19 -19
- package/bin/scripts/{writ.logrotate → x-security.logrotate} +3 -3
- package/bin/xsecurity.mjs +2165 -2158
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright 2026
|
|
189
|
+
Copyright 2026 x-security contributors
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
package/README.md
CHANGED
|
@@ -126,7 +126,7 @@ How much of each class a target can **enforce natively**. 🟢 full · 🟡 part
|
|
|
126
126
|
| API9 · Improper Inventory Management | 🔴 | 🔴 | 🟡 |
|
|
127
127
|
| API10 · Unsafe Consumption of APIs | 🟡 | 🟡 | 🟡 |
|
|
128
128
|
|
|
129
|
-
Only these three targets are independently **measured** today; Kong, Coraza, NGINX, Envoy and OpenAppSec compile the same policy but aren't yet published with a per-class measurement (⚪). Cells like **🔴→🟢** are the same control stateless vs. with a JWT identity wired — ownership checks (BOLA/BFLA) need to know who the caller is, so a stateless WAF can't enforce them. A **🟡** means the target enforces most of the class natively, not all. Full per-field matrix (incl. the
|
|
129
|
+
Only these three targets are independently **measured** today; Kong, Coraza, NGINX, Envoy and OpenAppSec compile the same policy but aren't yet published with a per-class measurement (⚪). Cells like **🔴→🟢** are the same control stateless vs. with a JWT identity wired — ownership checks (BOLA/BFLA) need to know who the caller is, so a stateless WAF can't enforce them. A **🟡** means the target enforces most of the class natively, not all. Full per-field matrix (incl. the x-security-native injection / prompt-injection / audit classes): **[usewaf.com/coverage](https://usewaf.com/coverage)**.
|
|
130
130
|
|
|
131
131
|
## License
|
|
132
132
|
|
package/bin/scripts/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# XSecurity firewall — deploy-time DNS wrapper
|
|
2
2
|
|
|
3
3
|
The generator emits `iptables.rules` and `ip6tables.rules` with placeholder
|
|
4
|
-
tokens of the form `@@
|
|
4
|
+
tokens of the form `@@X_SECURITY_RESOLVE:<fqdn>@@` wherever a
|
|
5
5
|
`request.schema.<field>.domainAllowlist` entry must be turned into a
|
|
6
6
|
concrete `-d <addr>` clause. iptables itself has no DNS; resolution must
|
|
7
7
|
happen on the host at deploy time and be refreshed periodically.
|
|
@@ -12,54 +12,54 @@ These scripts complete that flow.
|
|
|
12
12
|
|
|
13
13
|
| File | Destination | Purpose |
|
|
14
14
|
|------|-------------|---------|
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
15
|
+
| `x-security-resolve.sh` | `/usr/local/sbin/x-security-resolve.sh` | One-shot resolver. Reads a template, emits a resolved ruleset. |
|
|
16
|
+
| `x-security-refresh.sh` | `/usr/local/sbin/x-security-refresh.sh` | Periodic re-resolve + `iptables-restore` apply with flap detection. |
|
|
17
|
+
| `x-security-refresh.service` | `/etc/systemd/system/x-security-refresh.service` | systemd `Type=oneshot` unit. |
|
|
18
|
+
| `x-security-refresh.timer` | `/etc/systemd/system/x-security-refresh.timer` | systemd timer; runs every 5 minutes. |
|
|
19
|
+
| `x-security.logrotate` | `/etc/logrotate.d/x-security` | Optional logrotate config for the refresh log. |
|
|
20
20
|
|
|
21
21
|
## Installation
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
24
|
# 1. Place the scripts.
|
|
25
|
-
install -m 0755
|
|
26
|
-
install -m 0755
|
|
25
|
+
install -m 0755 x-security-resolve.sh /usr/local/sbin/x-security-resolve.sh
|
|
26
|
+
install -m 0755 x-security-refresh.sh /usr/local/sbin/x-security-refresh.sh
|
|
27
27
|
|
|
28
28
|
# 2. Place the rule templates emitted by `lazy generate`.
|
|
29
|
-
install -d /etc/
|
|
30
|
-
install -m 0644 iptables.rules /etc/
|
|
31
|
-
install -m 0644 ip6tables.rules /etc/
|
|
29
|
+
install -d /etc/x-security
|
|
30
|
+
install -m 0644 iptables.rules /etc/x-security/rules.template
|
|
31
|
+
install -m 0644 ip6tables.rules /etc/x-security/rules6.template
|
|
32
32
|
|
|
33
|
-
# 3. Replace the ${
|
|
33
|
+
# 3. Replace the ${X_SECURITY_APP_UID} placeholder in both templates with
|
|
34
34
|
# the numeric uid of the application user (e.g. `id -u app-user`).
|
|
35
35
|
APP_UID=$(id -u app-user)
|
|
36
|
-
sed -i "s/\${
|
|
37
|
-
/etc/
|
|
36
|
+
sed -i "s/\${X_SECURITY_APP_UID}/${APP_UID}/g" \
|
|
37
|
+
/etc/x-security/rules.template /etc/x-security/rules6.template
|
|
38
38
|
|
|
39
39
|
# 4. Install + enable the systemd unit.
|
|
40
|
-
install -m 0644
|
|
41
|
-
install -m 0644
|
|
40
|
+
install -m 0644 x-security-refresh.service /etc/systemd/system/
|
|
41
|
+
install -m 0644 x-security-refresh.timer /etc/systemd/system/
|
|
42
42
|
systemctl daemon-reload
|
|
43
|
-
systemctl enable --now
|
|
43
|
+
systemctl enable --now x-security-refresh.timer
|
|
44
44
|
|
|
45
45
|
# 5. (Optional) install logrotate snippet.
|
|
46
|
-
install -m 0644
|
|
46
|
+
install -m 0644 x-security.logrotate /etc/logrotate.d/x-security
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
The timer runs `
|
|
49
|
+
The timer runs `x-security-refresh.sh` on boot and every 5 minutes
|
|
50
50
|
thereafter. The first run resolves the template, applies via
|
|
51
|
-
`iptables-restore`, and snapshots to `/etc/
|
|
51
|
+
`iptables-restore`, and snapshots to `/etc/x-security/rules.applied`.
|
|
52
52
|
|
|
53
53
|
## Environment variables
|
|
54
54
|
|
|
55
55
|
| Variable | Default | Effect |
|
|
56
56
|
|----------|---------|--------|
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
57
|
+
| `X_SECURITY_APP_UID` | (none — required) | Numeric uid the rules scope to via `-m owner --uid-owner`. Substitute into the template before installing. |
|
|
58
|
+
| `X_SECURITY_LOG` | `/var/log/x-security-resolve.log` | Resolver + refresh log path. Append-only. |
|
|
59
|
+
| `X_SECURITY_CONF_DIR` | `/etc/x-security` | Where templates/current/applied/flap-history live. |
|
|
60
|
+
| `X_SECURITY_FLAP_MAX` | `5` | Max ruleset changes within the flap window before holding previous rules. |
|
|
61
|
+
| `X_SECURITY_FLAP_WINDOW` | `900` | Flap detection window in seconds (15 min default). |
|
|
62
|
+
| `X_SECURITY_RESOLVER` | `/usr/local/sbin/x-security-resolve.sh` | Path to the resolver script (refresh wrapper uses this). |
|
|
63
63
|
| `IPTABLES_RESTORE` | `/sbin/iptables-restore` | Override path to `iptables-restore`. |
|
|
64
64
|
| `IP6TABLES_RESTORE` | `/sbin/ip6tables-restore` | Override path to `ip6tables-restore`. |
|
|
65
65
|
|
|
@@ -67,17 +67,17 @@ thereafter. The first run resolves the template, applies via
|
|
|
67
67
|
|
|
68
68
|
```sh
|
|
69
69
|
# stdin → stdout
|
|
70
|
-
cat /etc/
|
|
70
|
+
cat /etc/x-security/rules.template | /usr/local/sbin/x-security-resolve.sh
|
|
71
71
|
|
|
72
72
|
# file → file, strict mode (default — exit 1 on any failed FQDN)
|
|
73
|
-
/usr/local/sbin/
|
|
74
|
-
--rules-file /etc/
|
|
75
|
-
--out /etc/
|
|
73
|
+
/usr/local/sbin/x-security-resolve.sh \
|
|
74
|
+
--rules-file /etc/x-security/rules.template \
|
|
75
|
+
--out /etc/x-security/rules.current
|
|
76
76
|
|
|
77
77
|
# Lenient: drop only the unresolved rules, keep the rest.
|
|
78
|
-
/usr/local/sbin/
|
|
79
|
-
--rules-file /etc/
|
|
80
|
-
--out /etc/
|
|
78
|
+
/usr/local/sbin/x-security-resolve.sh --lenient \
|
|
79
|
+
--rules-file /etc/x-security/rules.template \
|
|
80
|
+
--out /etc/x-security/rules.current
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
## Security model
|
|
@@ -97,14 +97,14 @@ cat /etc/writ/rules.template | /usr/local/sbin/writ-resolve.sh
|
|
|
97
97
|
script detects rapid change and freezes the previously-applied
|
|
98
98
|
ruleset rather than thrashing iptables. Threshold is tunable.
|
|
99
99
|
5. **Log integrity.** All resolution outcomes are written append-only to
|
|
100
|
-
`$
|
|
100
|
+
`$X_SECURITY_LOG` with ISO-8601 timestamps. Rotation via logrotate
|
|
101
101
|
(NOT `copytruncate`) preserves append-only semantics.
|
|
102
102
|
|
|
103
103
|
## Troubleshooting
|
|
104
104
|
|
|
105
|
-
- `systemctl status
|
|
106
|
-
- `journalctl -u
|
|
107
|
-
- `tail -f /var/log/
|
|
108
|
-
- `iptables-save | grep
|
|
105
|
+
- `systemctl status x-security-refresh.timer` — is the timer scheduled?
|
|
106
|
+
- `journalctl -u x-security-refresh.service` — last few run outcomes.
|
|
107
|
+
- `tail -f /var/log/x-security-resolve.log` — per-FQDN resolution traces.
|
|
108
|
+
- `iptables-save | grep x-security` — what's actually in the kernel.
|
|
109
109
|
- If you see the flap-throttle WARN: investigate DNS instability first;
|
|
110
110
|
the wrapper is doing its job by refusing to apply churn.
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
[Unit]
|
|
2
|
-
Description=
|
|
3
|
-
Documentation=https://github.com/
|
|
2
|
+
Description=XSecurity firewall refresh (DNS-resolved allowlist apply)
|
|
3
|
+
Documentation=https://github.com/x-security/x-security
|
|
4
4
|
After=network-online.target
|
|
5
5
|
Wants=network-online.target
|
|
6
6
|
|
|
7
7
|
[Service]
|
|
8
8
|
Type=oneshot
|
|
9
|
-
ExecStart=/usr/local/sbin/
|
|
9
|
+
ExecStart=/usr/local/sbin/x-security-refresh.sh
|
|
10
10
|
# Fail-closed: a failure here MUST NOT clear existing rules. The script
|
|
11
11
|
# itself is responsible for that (it exits 0 on resolver failure to avoid
|
|
12
12
|
# triggering systemd-restart loops that could thrash iptables).
|
|
13
13
|
SuccessExitStatus=0
|
|
14
14
|
# Hardening: the script only needs network + iptables. No private tmp
|
|
15
|
-
# because the resolver writes /etc/
|
|
15
|
+
# because the resolver writes /etc/x-security/rules.current.
|
|
16
16
|
ProtectSystem=false
|
|
17
17
|
ProtectHome=true
|
|
18
18
|
PrivateDevices=true
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
#
|
|
2
|
+
# x-security-refresh.sh — periodic re-resolution + apply for XSecurity rules.
|
|
3
3
|
#
|
|
4
4
|
# Designed to run from a systemd timer (every 5 min by default). On each
|
|
5
5
|
# tick:
|
|
6
|
-
# 1. Resolve /etc/
|
|
7
|
-
# into /etc/
|
|
8
|
-
# 2. Diff against /etc/
|
|
6
|
+
# 1. Resolve /etc/x-security/rules.template via x-security-resolve.sh
|
|
7
|
+
# into /etc/x-security/rules.current.
|
|
8
|
+
# 2. Diff against /etc/x-security/rules.applied — if unchanged, no-op.
|
|
9
9
|
# 3. If changed, apply via `iptables-restore` and snapshot
|
|
10
|
-
# /etc/
|
|
10
|
+
# /etc/x-security/rules.applied.
|
|
11
11
|
# 4. Flap detection: if the resolved output changes more than
|
|
12
|
-
# $
|
|
12
|
+
# $X_SECURITY_FLAP_MAX times within $X_SECURITY_FLAP_WINDOW seconds,
|
|
13
13
|
# hold the previous rules (do NOT apply the new ones) and warn.
|
|
14
14
|
# This protects against DNS instability (round-robin churn,
|
|
15
15
|
# misconfigured TTLs, or active DNS attacks).
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
set -eu
|
|
23
23
|
|
|
24
|
-
CONF_DIR="${
|
|
24
|
+
CONF_DIR="${X_SECURITY_CONF_DIR:-/etc/x-security}"
|
|
25
25
|
TEMPLATE="${CONF_DIR}/rules.template"
|
|
26
26
|
TEMPLATE6="${CONF_DIR}/rules6.template"
|
|
27
27
|
CURRENT="${CONF_DIR}/rules.current"
|
|
@@ -29,13 +29,13 @@ CURRENT6="${CONF_DIR}/rules6.current"
|
|
|
29
29
|
APPLIED="${CONF_DIR}/rules.applied"
|
|
30
30
|
APPLIED6="${CONF_DIR}/rules6.applied"
|
|
31
31
|
FLAP_LOG="${CONF_DIR}/.flap-history"
|
|
32
|
-
LOG_FILE="${
|
|
32
|
+
LOG_FILE="${X_SECURITY_LOG:-/var/log/x-security-resolve.log}"
|
|
33
33
|
|
|
34
34
|
# Flap thresholds.
|
|
35
|
-
FLAP_MAX="${
|
|
36
|
-
FLAP_WINDOW="${
|
|
35
|
+
FLAP_MAX="${X_SECURITY_FLAP_MAX:-5}"
|
|
36
|
+
FLAP_WINDOW="${X_SECURITY_FLAP_WINDOW:-900}" # 15 minutes default
|
|
37
37
|
|
|
38
|
-
RESOLVER="${
|
|
38
|
+
RESOLVER="${X_SECURITY_RESOLVER:-/usr/local/sbin/x-security-resolve.sh}"
|
|
39
39
|
IPTABLES_RESTORE="${IPTABLES_RESTORE:-/sbin/iptables-restore}"
|
|
40
40
|
IP6TABLES_RESTORE="${IP6TABLES_RESTORE:-/sbin/ip6tables-restore}"
|
|
41
41
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[Unit]
|
|
2
|
-
Description=
|
|
3
|
-
Documentation=https://github.com/
|
|
2
|
+
Description=XSecurity firewall refresh timer (every 5 minutes)
|
|
3
|
+
Documentation=https://github.com/x-security/x-security
|
|
4
4
|
|
|
5
5
|
[Timer]
|
|
6
6
|
# Run shortly after boot, then every 5 minutes thereafter. AccuracySec
|
|
@@ -9,7 +9,7 @@ OnBootSec=30s
|
|
|
9
9
|
OnUnitActiveSec=5min
|
|
10
10
|
AccuracySec=30s
|
|
11
11
|
Persistent=true
|
|
12
|
-
Unit=
|
|
12
|
+
Unit=x-security-refresh.service
|
|
13
13
|
|
|
14
14
|
[Install]
|
|
15
15
|
WantedBy=timers.target
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
#
|
|
2
|
+
# x-security-resolve.sh — deploy-time DNS resolver for XSecurity firewall rules.
|
|
3
3
|
#
|
|
4
|
-
# Reads an iptables-save-format ruleset containing @@
|
|
4
|
+
# Reads an iptables-save-format ruleset containing @@X_SECURITY_RESOLVE:<fqdn>@@
|
|
5
5
|
# tokens (produced by `lazy generate --target firewall`) and rewrites
|
|
6
6
|
# each token into one or more concrete `-d <addr>` clauses by resolving the
|
|
7
7
|
# FQDN against the host's system resolver.
|
|
8
8
|
#
|
|
9
|
-
# Generated by
|
|
9
|
+
# Generated by XSecurity — DO NOT EDIT in place. If you need to customize
|
|
10
10
|
# behavior, override via the environment variables documented in the
|
|
11
11
|
# accompanying README.md.
|
|
12
12
|
#
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
# via the provided logrotate.d snippet.
|
|
28
28
|
#
|
|
29
29
|
# Usage:
|
|
30
|
-
#
|
|
31
|
-
# ... |
|
|
30
|
+
# x-security-resolve.sh [--rules-file PATH] [--out PATH] [--lenient]
|
|
31
|
+
# ... | x-security-resolve.sh > resolved.rules
|
|
32
32
|
#
|
|
33
33
|
# Exit codes:
|
|
34
34
|
# 0 success — all tokens resolved
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
set -eu
|
|
40
40
|
|
|
41
|
-
LOG_FILE="${
|
|
41
|
+
LOG_FILE="${X_SECURITY_LOG:-/var/log/x-security-resolve.log}"
|
|
42
42
|
LENIENT=0
|
|
43
43
|
RULES_FILE=""
|
|
44
44
|
OUT_FILE=""
|
|
@@ -52,7 +52,7 @@ log() {
|
|
|
52
52
|
|
|
53
53
|
usage() {
|
|
54
54
|
cat >&2 <<'EOF'
|
|
55
|
-
|
|
55
|
+
x-security-resolve.sh [--rules-file PATH] [--out PATH] [--lenient]
|
|
56
56
|
|
|
57
57
|
--rules-file PATH Read template from PATH instead of stdin.
|
|
58
58
|
--out PATH Write resolved ruleset to PATH instead of stdout.
|
|
@@ -60,7 +60,7 @@ writ-resolve.sh [--rules-file PATH] [--out PATH] [--lenient]
|
|
|
60
60
|
Default is strict: any failed resolution => exit 1.
|
|
61
61
|
|
|
62
62
|
Environment:
|
|
63
|
-
|
|
63
|
+
X_SECURITY_LOG Override log path (default /var/log/x-security-resolve.log)
|
|
64
64
|
EOF
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -102,14 +102,14 @@ else
|
|
|
102
102
|
INPUT=$(cat)
|
|
103
103
|
fi
|
|
104
104
|
|
|
105
|
-
# Pass 1: extract every @@
|
|
105
|
+
# Pass 1: extract every @@X_SECURITY_RESOLVE:<fqdn>@@ token. Skip comment
|
|
106
106
|
# lines (the generator's header documents the token format with a literal
|
|
107
|
-
# `@@
|
|
107
|
+
# `@@X_SECURITY_RESOLVE:<fqdn>@@` example — we must not try to resolve
|
|
108
108
|
# `<fqdn>` as a real hostname).
|
|
109
109
|
FQDNS=$(printf '%s\n' "$INPUT" \
|
|
110
110
|
| grep -v '^[[:space:]]*#' \
|
|
111
|
-
| grep -oE '@@
|
|
112
|
-
| sed -e 's/^@@
|
|
111
|
+
| grep -oE '@@X_SECURITY_RESOLVE:[^@]+@@' \
|
|
112
|
+
| sed -e 's/^@@X_SECURITY_RESOLVE://' -e 's/@@$//' \
|
|
113
113
|
| sort -u)
|
|
114
114
|
|
|
115
115
|
TOTAL=0
|
|
@@ -132,7 +132,7 @@ if [ -n "$FQDNS" ]; then
|
|
|
132
132
|
addrs=$(resolve_fqdn "$fqdn" || true)
|
|
133
133
|
if [ -z "$addrs" ]; then
|
|
134
134
|
log "WARN: failed to resolve $fqdn"
|
|
135
|
-
printf '%s\
|
|
135
|
+
printf '%s\t__X_SECURITY_UNRESOLVED__\n' "$fqdn" >> "$TMP_MAP"
|
|
136
136
|
else
|
|
137
137
|
log "INFO: resolved $fqdn -> $(echo "$addrs" | tr '\n' ' ')"
|
|
138
138
|
echo "$addrs" | while IFS= read -r addr; do
|
|
@@ -148,7 +148,7 @@ fi
|
|
|
148
148
|
# it with `|| echo 0` (that would emit two lines). Use a wc-based count and
|
|
149
149
|
# always trim to a single integer.
|
|
150
150
|
TOTAL=$(printf '%s\n' "$FQDNS" | grep -v '^$' | wc -l | tr -d ' \n')
|
|
151
|
-
FAILED=$(grep -c '
|
|
151
|
+
FAILED=$(grep -c '__X_SECURITY_UNRESOLVED__' "$TMP_MAP" 2>/dev/null | head -n 1 | tr -d ' \n')
|
|
152
152
|
[ -z "$FAILED" ] && FAILED=0
|
|
153
153
|
RESOLVED=$((TOTAL - FAILED))
|
|
154
154
|
|
|
@@ -162,7 +162,7 @@ if [ "$FAILED" -gt 0 ] && [ "$LENIENT" -eq 0 ]; then
|
|
|
162
162
|
exit 1
|
|
163
163
|
fi
|
|
164
164
|
|
|
165
|
-
# Pass 2: substitute. For every line containing a @@
|
|
165
|
+
# Pass 2: substitute. For every line containing a @@X_SECURITY_RESOLVE:X@@
|
|
166
166
|
# token, emit one copy per resolved address (with `-d <addr>` replacing the
|
|
167
167
|
# token). Lines for unresolved FQDNs are dropped (in lenient mode), which is
|
|
168
168
|
# fail-closed: those destinations remain unreachable.
|
|
@@ -171,7 +171,7 @@ OUTPUT=$(printf '%s\n' "$INPUT" | awk -v mapfile="$TMP_MAP" '
|
|
|
171
171
|
while ((getline line < mapfile) > 0) {
|
|
172
172
|
n = split(line, f, "\t")
|
|
173
173
|
if (n < 2) continue
|
|
174
|
-
if (f[2] == "
|
|
174
|
+
if (f[2] == "__X_SECURITY_UNRESOLVED__") {
|
|
175
175
|
unresolved[f[1]] = 1
|
|
176
176
|
continue
|
|
177
177
|
}
|
|
@@ -190,10 +190,10 @@ OUTPUT=$(printf '%s\n' "$INPUT" | awk -v mapfile="$TMP_MAP" '
|
|
|
190
190
|
close(mapfile)
|
|
191
191
|
}
|
|
192
192
|
{
|
|
193
|
-
if (match($0, /@@
|
|
193
|
+
if (match($0, /@@X_SECURITY_RESOLVE:[^@]+@@/)) {
|
|
194
194
|
token = substr($0, RSTART, RLENGTH)
|
|
195
195
|
fqdn = token
|
|
196
|
-
sub(/^@@
|
|
196
|
+
sub(/^@@X_SECURITY_RESOLVE:/, "", fqdn)
|
|
197
197
|
sub(/@@$/, "", fqdn)
|
|
198
198
|
if (fqdn in unresolved) {
|
|
199
199
|
# Drop the rule — fail-closed.
|
|
@@ -203,7 +203,7 @@ OUTPUT=$(printf '%s\n' "$INPUT" | awk -v mapfile="$TMP_MAP" '
|
|
|
203
203
|
m = split(addrs[fqdn], a, "\n")
|
|
204
204
|
for (i = 1; i <= m; i++) {
|
|
205
205
|
line = $0
|
|
206
|
-
sub(/@@
|
|
206
|
+
sub(/@@X_SECURITY_RESOLVE:[^@]+@@/, "-d " a[i], line)
|
|
207
207
|
print line
|
|
208
208
|
}
|
|
209
209
|
next
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# /etc/logrotate.d/
|
|
2
|
-
# Copy to /etc/logrotate.d/
|
|
3
|
-
/var/log/
|
|
1
|
+
# /etc/logrotate.d/x-security — sample logrotate config for XSecurity refresh log.
|
|
2
|
+
# Copy to /etc/logrotate.d/x-security and adjust paths/retention to taste.
|
|
3
|
+
/var/log/x-security-resolve.log {
|
|
4
4
|
weekly
|
|
5
5
|
rotate 8
|
|
6
6
|
compress
|