Skip to content

Commit 78089ea

Browse files
committed
Add SOCKS auth to --manage menu, add negative auth tests
- New option 6 in --manage: Configure SOCKS auth (enable/disable/change) - do_configure_socks_auth: interactive flow with current state display, credential validation, auth enforcement verification - Remove 2>/dev/null from dnstm backend auth call (show errors to user) - Add post-auth health check (verify microsocks restarted) - Add negative auth test in step 9: verify unauthenticated connections rejected - Add negative auth test in step 11: same verification in final test suite - Shift hardening to option 7, uninstall to option 8
1 parent c7c738b commit 78089ea

1 file changed

Lines changed: 160 additions & 6 deletions

File tree

dnstm-setup.sh

Lines changed: 160 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,124 @@ detect_socks_auth() {
584584
return 1
585585
}
586586

587+
# ─── Configure SOCKS Auth (manage menu) ──────────────────────────────────────
588+
589+
do_configure_socks_auth() {
590+
banner
591+
print_header "Configure SOCKS5 Authentication"
592+
593+
if [[ $EUID -ne 0 ]]; then
594+
print_fail "Not running as root."
595+
exit 1
596+
fi
597+
598+
if ! command -v dnstm &>/dev/null; then
599+
print_fail "dnstm is not installed."
600+
exit 1
601+
fi
602+
603+
# Show current state
604+
echo ""
605+
detect_socks_auth || true
606+
if [[ "$SOCKS_AUTH" == true ]]; then
607+
echo -e " ${BOLD}Current status:${NC} ${GREEN}Enabled${NC}"
608+
echo -e " ${DIM}Username: ${SOCKS_USER}${NC}"
609+
echo ""
610+
echo -e " ${BOLD}1)${NC} Change credentials"
611+
echo -e " ${BOLD}2)${NC} Disable authentication"
612+
echo -e " ${BOLD}0)${NC} Cancel"
613+
echo ""
614+
local choice=""
615+
read -rp " Select [0-2]: " choice || exit 0
616+
case "$choice" in
617+
1)
618+
echo ""
619+
;;
620+
2)
621+
echo ""
622+
print_info "Disabling SOCKS5 authentication..."
623+
if dnstm backend auth -t socks --disable; then
624+
print_ok "SOCKS5 authentication disabled"
625+
sleep 2
626+
if pgrep -x microsocks &>/dev/null || systemctl is-active --quiet microsocks 2>/dev/null; then
627+
print_ok "microsocks restarted without authentication"
628+
else
629+
print_warn "microsocks may not have restarted — check: systemctl status microsocks"
630+
fi
631+
else
632+
print_fail "Failed to disable authentication"
633+
fi
634+
exit 0
635+
;;
636+
*)
637+
exit 0
638+
;;
639+
esac
640+
else
641+
echo -e " ${BOLD}Current status:${NC} ${RED}Disabled (open proxy)${NC}"
642+
echo ""
643+
if ! prompt_yn "Enable SOCKS5 authentication?" "y"; then
644+
print_info "Cancelled."
645+
exit 0
646+
fi
647+
echo ""
648+
fi
649+
650+
# Collect credentials
651+
local new_user new_pass
652+
new_user=$(prompt_input "Enter SOCKS proxy username" "proxy")
653+
new_user=$(echo "$new_user" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
654+
if [[ -z "$new_user" ]]; then
655+
print_fail "Username cannot be empty"
656+
exit 1
657+
fi
658+
if [[ "$new_user" == *"|"* || "$new_user" == *":"* ]]; then
659+
print_fail "Username cannot contain | or : characters"
660+
exit 1
661+
fi
662+
663+
new_pass=$(prompt_input "Enter SOCKS proxy password")
664+
new_pass=$(echo "$new_pass" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
665+
if [[ -z "$new_pass" ]]; then
666+
print_fail "Password cannot be empty"
667+
exit 1
668+
fi
669+
if [[ "$new_pass" == *"|"* ]]; then
670+
print_fail "Password cannot contain the | character"
671+
exit 1
672+
fi
673+
674+
echo ""
675+
print_info "Applying SOCKS5 authentication..."
676+
if dnstm backend auth -t socks -u "$new_user" -p "$new_pass"; then
677+
print_ok "SOCKS5 authentication enabled (user: ${new_user})"
678+
sleep 2
679+
if pgrep -x microsocks &>/dev/null || systemctl is-active --quiet microsocks 2>/dev/null; then
680+
print_ok "microsocks restarted with authentication"
681+
else
682+
print_warn "microsocks may not have restarted — check: systemctl status microsocks"
683+
fi
684+
685+
# Verify auth enforcement
686+
local socks_port=""
687+
socks_port=$(ss -tlnp 2>/dev/null | grep microsocks | awk '{for(i=1;i<=NF;i++) if($i ~ /:[0-9]+$/) {split($i,a,":"); print a[length(a)]; exit}}' || true)
688+
if [[ -z "$socks_port" ]]; then
689+
socks_port="19801"
690+
fi
691+
local noauth_test
692+
noauth_test=$(curl -s --max-time 5 --socks5 "127.0.0.1:${socks_port}" https://api.ipify.org 2>/dev/null || true)
693+
if [[ -z "$noauth_test" ]]; then
694+
print_ok "Auth enforced: unauthenticated connections are rejected"
695+
else
696+
print_warn "Auth NOT enforced: proxy still works without credentials!"
697+
print_info "Try restarting: systemctl restart microsocks"
698+
fi
699+
else
700+
print_fail "Failed to configure SOCKS5 authentication"
701+
print_info "Try manually: dnstm backend auth -t socks -u ${new_user} -p <password>"
702+
fi
703+
}
704+
587705
# ─── --status ───────────────────────────────────────────────────────────────────
588706

589707
do_status() {
@@ -1709,16 +1827,17 @@ do_manage() {
17091827
echo -e " ${BOLD}3)${NC} Remove tunnel ${DIM}(pick one to remove)${NC}"
17101828
echo -e " ${BOLD}4)${NC} Add backup domain ${DIM}(new domain → 4 more tunnels)${NC}"
17111829
echo -e " ${BOLD}5)${NC} Manage SSH users ${DIM}(add, list, update, delete)${NC}"
1712-
echo -e " ${BOLD}6)${NC} Apply hardening ${DIM}(systemd security for all services)${NC}"
1830+
echo -e " ${BOLD}6)${NC} Configure SOCKS auth ${DIM}(enable, disable, or change credentials)${NC}"
1831+
echo -e " ${BOLD}7)${NC} Apply hardening ${DIM}(systemd security for all services)${NC}"
17131832
echo ""
17141833
echo -e " ${DIM}──────────────────────────────────────────────${NC}"
1715-
echo -e " ${BOLD}${RED}7)${NC} ${RED}Uninstall everything${NC}"
1834+
echo -e " ${BOLD}${RED}8)${NC} ${RED}Uninstall everything${NC}"
17161835
echo ""
17171836
echo -e " ${BOLD}0)${NC} Exit"
17181837
echo ""
17191838

17201839
local choice=""
1721-
read -rp " Select [0-7]: " choice || break
1840+
read -rp " Select [0-8]: " choice || break
17221841

17231842
case "$choice" in
17241843
1)
@@ -1737,9 +1856,12 @@ do_manage() {
17371856
( trap - INT; do_manage_users ) || true
17381857
;;
17391858
6)
1740-
( trap - INT; do_harden ) || true
1859+
( trap - INT; do_configure_socks_auth ) || true
17411860
;;
17421861
7)
1862+
( trap - INT; do_harden ) || true
1863+
;;
1864+
8)
17431865
( trap - INT; do_uninstall ) || true
17441866
# If uninstall succeeded, dnstm is gone — exit menu
17451867
hash -d dnstm 2>/dev/null || true
@@ -1758,7 +1880,7 @@ do_manage() {
17581880
continue
17591881
;;
17601882
*)
1761-
print_warn "Invalid choice. Enter 0-7."
1883+
print_warn "Invalid choice. Enter 0-8."
17621884
sleep 1
17631885
continue
17641886
;;
@@ -2503,8 +2625,16 @@ step_verify_microsocks() {
25032625
# Apply SOCKS authentication via dnstm (v0.6.8+) — only if microsocks is running
25042626
if [[ "$microsocks_running" == true && "$SOCKS_AUTH" == true && -n "$SOCKS_USER" && -n "$SOCKS_PASS" ]]; then
25052627
print_info "Configuring SOCKS5 authentication via dnstm..."
2506-
if dnstm backend auth -t socks -u "$SOCKS_USER" -p "$SOCKS_PASS" 2>/dev/null; then
2628+
if dnstm backend auth -t socks -u "$SOCKS_USER" -p "$SOCKS_PASS"; then
25072629
print_ok "SOCKS5 authentication enabled (user: ${SOCKS_USER})"
2630+
# dnstm backend auth rewrites ExecStart and restarts microsocks;
2631+
# give it a moment to come back up
2632+
sleep 2
2633+
if pgrep -x microsocks &>/dev/null || systemctl is-active --quiet microsocks 2>/dev/null; then
2634+
print_ok "microsocks restarted with authentication"
2635+
else
2636+
print_warn "microsocks may not have restarted — check: systemctl status microsocks"
2637+
fi
25082638
else
25092639
print_warn "Failed to configure SOCKS5 authentication via dnstm"
25102640
print_info "Try manually: dnstm backend auth -t socks -u ${SOCKS_USER} -p <password>"
@@ -2546,6 +2676,18 @@ step_verify_microsocks() {
25462676
print_warn "SOCKS proxy test failed (this may be OK if internet is restricted)"
25472677
print_info "The proxy may still work for DNS tunnel clients"
25482678
fi
2679+
2680+
# Negative test: verify unauthenticated access is rejected when auth is enabled
2681+
if [[ "$SOCKS_AUTH" == true && -n "$test_ip" ]]; then
2682+
local noauth_ip
2683+
noauth_ip=$(curl -s --max-time 5 --socks5 "127.0.0.1:${socks_port}" https://api.ipify.org 2>/dev/null || true)
2684+
if [[ -z "$noauth_ip" ]]; then
2685+
print_ok "Auth enforced: unauthenticated connections are rejected"
2686+
else
2687+
print_warn "Auth NOT enforced: proxy works without credentials!"
2688+
print_info "Try: dnstm backend auth -t socks -u ${SOCKS_USER} -p <password>"
2689+
fi
2690+
fi
25492691
}
25502692

25512693
# ─── STEP 10: SSH User (Optional) ──────────────────────────────────────────────
@@ -2662,6 +2804,18 @@ step_tests() {
26622804
if [[ -n "$socks_result" ]]; then
26632805
print_ok "SOCKS proxy: PASS (IP: ${socks_result}) on port ${socks_port}"
26642806
pass=$((pass + 1))
2807+
# Verify auth enforcement
2808+
if [[ "$SOCKS_AUTH" == true ]]; then
2809+
local noauth_result
2810+
noauth_result=$(curl -s --max-time 5 --socks5 "127.0.0.1:${socks_port}" https://api.ipify.org 2>/dev/null || true)
2811+
if [[ -z "$noauth_result" ]]; then
2812+
print_ok "SOCKS auth enforcement: PASS (unauthenticated rejected)"
2813+
pass=$((pass + 1))
2814+
else
2815+
print_fail "SOCKS auth enforcement: FAIL (works without credentials!)"
2816+
fail=$((fail + 1))
2817+
fi
2818+
fi
26652819
elif ss -tlnp 2>/dev/null | grep -q "microsocks"; then
26662820
print_warn "SOCKS proxy: LISTENING on port ${socks_port} but connectivity test failed"
26672821
print_info "microsocks is running but outbound may be blocked or tunnels not ready"

0 commit comments

Comments
 (0)