feat: block/unblock --service, fw::has_rule wrappers, restricted status, net annotations, block system tests, 64 tests passing
This commit is contained in:
parent
c1d0a9ddd4
commit
16b4351313
5 changed files with 80 additions and 51 deletions
|
|
@ -113,6 +113,7 @@ function cmd::block::run() {
|
|||
ip::require_valid "$ip"
|
||||
fw::block_ip "$client_ip" "$ip"
|
||||
block::add_rule "$name" "$client_ip" "ip" "${block_name:-}" "$ip"
|
||||
$quiet || log::wg_success "${ip} has been blocked for ${name}"
|
||||
done
|
||||
|
||||
# Block specific subnets
|
||||
|
|
@ -120,6 +121,7 @@ function cmd::block::run() {
|
|||
ip::require_valid "$subnet"
|
||||
fw::block_subnet "$client_ip" "$subnet"
|
||||
block::add_rule "$name" "$client_ip" "subnet" "${block_name:-}" "$subnet"
|
||||
$quiet || log::wg_success "${subnet} has been blocked for ${name}"
|
||||
done
|
||||
|
||||
# Block specific ports
|
||||
|
|
@ -130,6 +132,7 @@ function cmd::block::run() {
|
|||
fw::block_port "$client_ip" "$b_target" "$b_port" "${b_proto:-tcp}"
|
||||
block::add_rule "$name" "$client_ip" "port" "${block_name:-}" \
|
||||
"$b_target" "$b_port" "${b_proto:-tcp}"
|
||||
$quiet || log::wg_success "${client_ip}:${b_port}:${b_proto:-tcp} has been blocked for ${name}"
|
||||
done
|
||||
|
||||
# Block services
|
||||
|
|
@ -147,7 +150,7 @@ function cmd::block::run() {
|
|||
if [[ "$resolved" == *:*:* ]]; then
|
||||
local b_ip b_port b_proto
|
||||
IFS=":" read -r b_ip b_port b_proto <<< "$resolved"
|
||||
fw::has_block_rule "$client_ip" "$b_ip" "$b_proto" "$b_port" 2>/dev/null || \
|
||||
fw::has_block_rule "$client_ip" "$b_ip" "$b_port" "$b_proto" 2>/dev/null || \
|
||||
{ already_blocked=false; break; }
|
||||
else
|
||||
fw::has_block_rule "$client_ip" "$resolved" 2>/dev/null || \
|
||||
|
|
|
|||
|
|
@ -130,18 +130,16 @@ function cmd::list::show_client() {
|
|||
subtype=$(peers::get_meta "$name" "subtype")
|
||||
|
||||
local endpoint="—"
|
||||
local ep
|
||||
ep=$(monitor::endpoint_for_key "$public_key")
|
||||
[[ -z "$ep" ]] && ep=$(monitor::last_endpoint "$name")
|
||||
[[ -n "$ep" ]] && endpoint="$ep"
|
||||
|
||||
local is_blocked="false"
|
||||
peers::is_blocked "$name" && is_blocked="true"
|
||||
|
||||
if [[ "$is_blocked" == "true" ]]; then
|
||||
local ep
|
||||
ep=$(monitor::last_endpoint "$name")
|
||||
[[ -n "$ep" ]] && endpoint="$ep"
|
||||
else
|
||||
local ep
|
||||
ep=$(monitor::endpoint_for_key "$public_key")
|
||||
[[ -n "$ep" ]] && endpoint="$ep"
|
||||
fi
|
||||
local is_restricted="false"
|
||||
peers::is_restricted "$name" && is_restricted="true"
|
||||
|
||||
local handshake_ts
|
||||
handshake_ts=$(monitor::get_handshake_ts "$public_key")
|
||||
|
|
@ -151,7 +149,7 @@ function cmd::list::show_client() {
|
|||
|
||||
local status
|
||||
status=$(peers::format_status "$name" "$public_key" \
|
||||
"$is_blocked" "false" "$handshake_ts" "$last_ts")
|
||||
"$is_blocked" "$is_restricted" "$handshake_ts" "$last_ts")
|
||||
|
||||
local last_seen
|
||||
last_seen=$(peers::format_last_seen "$name" "$public_key" \
|
||||
|
|
|
|||
|
|
@ -67,7 +67,9 @@ function cmd::test::run_cmd() {
|
|||
fi
|
||||
|
||||
if [[ -n "$expected" ]] && ! grep -qF "$expected" "$tmp"; then
|
||||
test::fail "${desc} (expected '${expected}' in output)"
|
||||
local actual
|
||||
actual=$(head -3 "$tmp" | tr '\n' ' ' | sed 's/ */ /g' | cut -c1-100)
|
||||
test::fail "${desc} (expected '${expected}', got: '${actual}')"
|
||||
rm -f "$tmp"
|
||||
return 1
|
||||
fi
|
||||
|
|
@ -240,18 +242,44 @@ function cmd::test::section_destructive() {
|
|||
"$WGCTL_BINARY" remove --name phone-testunit --force > /dev/null 2>&1 || true
|
||||
"$WGCTL_BINARY" group remove --name testgroup --force > /dev/null 2>&1 || true
|
||||
"$WGCTL_BINARY" group remove --name testgroup2 --force > /dev/null 2>&1 || true
|
||||
|
||||
"$WGCTL_BINARY" net rm --name test-block-svc --force > /dev/null 2>&1 || true
|
||||
"$WGCTL_BINARY" unblock --name phone-testunit > /dev/null 2>&1 || true
|
||||
|
||||
# ── Add test peer ──────────────────────────
|
||||
cmd::test::run_cmd "add phone peer" "added successfully" \
|
||||
add --name testunit --type phone
|
||||
|
||||
# ── Direct block/unblock ───────────────────
|
||||
cmd::test::run_cmd "block peer" "blocked" \
|
||||
block --name phone-testunit
|
||||
cmd::test::run_cmd "list shows blocked" "blocked" \
|
||||
list --blocked
|
||||
cmd::test::run_cmd "unblock peer" "unblocked" \
|
||||
unblock --name phone-testunit
|
||||
cmd::test::run_cmd "block peer" "blocked" block --name phone-testunit
|
||||
cmd::test::run_cmd "list shows blocked" "blocked" list --blocked
|
||||
cmd::test::run_cmd "unblock peer" "unblocked" unblock --name phone-testunit
|
||||
|
||||
# ── Specific IP block/unblock ──────────────
|
||||
cmd::test::run_cmd "block peer --ip" "blocked for" \
|
||||
block --name phone-testunit --ip 10.0.0.99
|
||||
cmd::test::run_cmd "list shows restricted" "restricted" \
|
||||
list --name phone-testunit
|
||||
cmd::test::run_cmd "unblock peer --ip" "unblocked" \
|
||||
unblock --name phone-testunit --ip 10.0.0.99
|
||||
|
||||
# ── Service block/unblock ──────────────────
|
||||
"$WGCTL_BINARY" net add --name test-block-svc \
|
||||
--ip 10.0.0.99 > /dev/null 2>&1
|
||||
"$WGCTL_BINARY" net add --name test-block-svc:web \
|
||||
--port 9999:tcp > /dev/null 2>&1
|
||||
cmd::test::run_cmd "block peer --service (ip)" "blocked" \
|
||||
block --name phone-testunit --service test-block-svc
|
||||
cmd::test::run_cmd "block already blocked service" "already" \
|
||||
block --name phone-testunit --service test-block-svc
|
||||
cmd::test::run_cmd "unblock peer --service (ip)" "unblocked" \
|
||||
unblock --name phone-testunit --service test-block-svc
|
||||
cmd::test::run_cmd "unblock not blocked service" "not blocked" \
|
||||
unblock --name phone-testunit --service test-block-svc
|
||||
cmd::test::run_cmd "block peer --service (port)" "blocked" \
|
||||
block --name phone-testunit --service test-block-svc:web
|
||||
cmd::test::run_cmd "unblock peer --service (port)" "unblocked" \
|
||||
unblock --name phone-testunit --service test-block-svc:web
|
||||
"$WGCTL_BINARY" net rm --name test-block-svc --force > /dev/null 2>&1 || true
|
||||
|
||||
# ── Rule assign/unassign ───────────────────
|
||||
cmd::test::run_cmd "rule assign" "Assigned" \
|
||||
|
|
@ -272,24 +300,20 @@ function cmd::test::section_destructive() {
|
|||
group unblock --name testgroup
|
||||
|
||||
# ── M:N group block tracking ───────────────
|
||||
# Setup: add testunit to a second group
|
||||
"$WGCTL_BINARY" group add --name testgroup2 \
|
||||
--desc "Test group 2" > /dev/null 2>&1
|
||||
"$WGCTL_BINARY" group peer add --name testgroup2 \
|
||||
--peer phone-testunit > /dev/null 2>&1
|
||||
|
||||
# Block from both groups
|
||||
cmd::test::run_cmd "group block first group" "blocked" \
|
||||
cmd::test::run_cmd "group block first group" "blocked" \
|
||||
group block --name testgroup
|
||||
cmd::test::run_cmd "group block second group" "blocked" \
|
||||
group block --name testgroup2
|
||||
|
||||
# Unblock from first — should stay blocked (second group still blocking)
|
||||
"$WGCTL_BINARY" group unblock --name testgroup > /dev/null 2>&1
|
||||
cmd::test::run_cmd "peer stays blocked after partial unblock" "blocked" \
|
||||
list --blocked
|
||||
|
||||
# Unblock from second — should now be fully unblocked
|
||||
"$WGCTL_BINARY" group unblock --name testgroup2 > /dev/null 2>&1
|
||||
cmd::test::run_cmd "peer unblocked after all groups unblock" "phone-testunit" \
|
||||
list --allowed
|
||||
|
|
@ -299,12 +323,11 @@ function cmd::test::section_destructive() {
|
|||
cmd::test::run_cmd "direct unblock overrides group block" "unblocked" \
|
||||
unblock --name phone-testunit
|
||||
|
||||
# ── Cleanup groups ─────────────────────────
|
||||
# ── Cleanup ────────────────────────────────
|
||||
cmd::test::run_cmd "group remove" "removed" \
|
||||
group remove --name testgroup --force
|
||||
"$WGCTL_BINARY" group remove --name testgroup2 --force > /dev/null 2>&1 || true
|
||||
|
||||
# ── Remove test peer ───────────────────────
|
||||
cmd::test::run_cmd "remove phone peer" "removed" \
|
||||
remove --name phone-testunit --force
|
||||
}
|
||||
|
|
@ -406,9 +429,6 @@ function cmd::test::fn_rule_assign() {
|
|||
|
||||
"$WGCTL_BINARY" remove --name phone-testunit --force > /dev/null 2>&1 || true
|
||||
"$WGCTL_BINARY" add --name testunit --type phone > /dev/null 2>&1
|
||||
|
||||
# Verify peer exists
|
||||
echo "DEBUG peer exists: $("$WGCTL_BINARY" list | grep phone-testunit)"
|
||||
|
||||
cmd::test::run_cmd "rule assign" "Assigned" \
|
||||
rule assign --name admin --peer phone-testunit
|
||||
|
|
|
|||
|
|
@ -110,6 +110,30 @@ function cmd::unblock::run() {
|
|||
return 0
|
||||
fi
|
||||
|
||||
# Unblock specific IPs
|
||||
for ip in "${ips[@]}"; do
|
||||
fw::unblock_ip "$client_ip" "$ip"
|
||||
block::remove_rule "$name" "ip" "$ip"
|
||||
$quiet || log::wg_success "${ip} has been unblocked for ${name}"
|
||||
done
|
||||
|
||||
# Unblock specific subnets
|
||||
for subnet in "${subnets[@]}"; do
|
||||
fw::unblock_subnet "$client_ip" "$subnet"
|
||||
block::remove_rule "$name" "subnet" "$subnet"
|
||||
$quiet || log::wg_success "${subnet} has been unblocked for ${name}"
|
||||
done
|
||||
|
||||
# Unblock specific ports
|
||||
for entry in "${ports[@]}"; do
|
||||
local target port proto
|
||||
IFS=":" read -r target port proto <<< "$entry"
|
||||
proto="${proto:-tcp}"
|
||||
fw::unblock_port "$client_ip" "$target" "$port" "$proto"
|
||||
block::remove_rule "$name" "port" "$b_target" "$b_port" "$b_proto"
|
||||
$quiet || log::wg_success "${client_ip}:${b_port}:${b_proto:-tcp} has been unblocked for ${name}"
|
||||
done
|
||||
|
||||
# Unblock services
|
||||
for svc in "${services[@]}"; do
|
||||
local resolved_lines=()
|
||||
|
|
@ -125,7 +149,7 @@ function cmd::unblock::run() {
|
|||
if [[ "$resolved" == *:*:* ]]; then
|
||||
local b_ip b_port b_proto
|
||||
IFS=":" read -r b_ip b_port b_proto <<< "$resolved"
|
||||
fw::has_block_rule "$client_ip" "$b_ip" "$b_proto" "$b_port" 2>/dev/null && \
|
||||
fw::has_block_rule "$client_ip" "$b_ip" "$b_port" "$b_proto" 2>/dev/null && \
|
||||
{ is_blocked=true; break; }
|
||||
else
|
||||
fw::has_block_rule "$client_ip" "$resolved" 2>/dev/null && \
|
||||
|
|
@ -153,27 +177,6 @@ function cmd::unblock::run() {
|
|||
$quiet || log::wg_success "${svc} has been unblocked for ${name}"
|
||||
done
|
||||
|
||||
# Unblock specific IPs
|
||||
for ip in "${ips[@]}"; do
|
||||
fw::unblock_ip "$client_ip" "$ip"
|
||||
block::remove_rule "$name" "ip" "$ip"
|
||||
done
|
||||
|
||||
# Unblock specific subnets
|
||||
for subnet in "${subnets[@]}"; do
|
||||
fw::unblock_subnet "$client_ip" "$subnet"
|
||||
block::remove_rule "$name" "subnet" "$subnet"
|
||||
done
|
||||
|
||||
# Unblock specific ports
|
||||
for entry in "${ports[@]}"; do
|
||||
local target port proto
|
||||
IFS=":" read -r target port proto <<< "$entry"
|
||||
proto="${proto:-tcp}"
|
||||
fw::unblock_port "$client_ip" "$target" "$port" "$proto"
|
||||
block::remove_rule "$name" "port" "$b_target" "$b_port" "$b_proto"
|
||||
done
|
||||
|
||||
# Clean up block file if now empty
|
||||
block::cleanup "$name"
|
||||
|
||||
|
|
|
|||
|
|
@ -170,6 +170,11 @@ function peers::is_blocked() {
|
|||
block::is_blocked "$name"
|
||||
}
|
||||
|
||||
function peers::is_restricted() {
|
||||
local name="${1:-}"
|
||||
block::has_specific_rules "$name" 2>/dev/null
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Default Rule
|
||||
# ============================================
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue