Skip to content

Commit 1141427

Browse files
committed
Migrate SOCKS auth to dnstm backend auth, harden credential validation
- Replace manual microsocks ExecStart patching with dnstm backend auth (v0.6.8+) - Add detect_socks_auth() helper using dnstm backend status - Remove GLIBC check / build-from-source block (dnstm manages microsocks) - Validate pipe | char in all credential inputs (SOCKS + SSH) to prevent corrupted slipnet:// URLs from pipe-delimited format injection - Trim trailing whitespace from dnstm backend status parsed values - Skip auth config + proxy test when microsocks fails to start - Update README: replace systemctl edit instructions with dnstm backend auth
1 parent 184e727 commit 1141427

2 files changed

Lines changed: 85 additions & 133 deletions

File tree

README.md

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,10 @@ The wizard has **12 steps**. Here's what each one does:
250250

251251
- **Asks if you want SOCKS5 authentication** — recommended for security
252252
- If yes: prompts for username (default: `proxy`) and password
253-
- Modifies the microsocks systemd service to require credentials
253+
- Configures auth via `dnstm backend auth` (dnstm v0.6.8+)
254254
- If no: proxy runs open (anyone who knows the domain can connect)
255255
- Checks if microsocks is running (process or systemd service)
256256
- Starts it if not running
257-
- Applies SOCKS5 auth to microsocks if enabled (adds `-u`/`-P` flags to service)
258257
- Tests the SOCKS proxy by detecting the microsocks port and making a request through it
259258
</details>
260259

@@ -561,40 +560,27 @@ When enabled, microsocks requires a **username and password** for every SOCKS5 c
561560
- The `slipnet://` share URLs automatically include the credentials (clients auto-configure)
562561
- The `authMode` field in SlipNet is set to `1` (username/password)
563562

564-
The credentials are applied by adding `-u user -P pass` flags to the microsocks systemd service.
563+
Authentication is configured via `dnstm backend auth` (requires dnstm v0.6.8+).
565564

566565
### Without Authentication
567566

568567
When disabled, the proxy is **open** — anyone who can resolve the DNS tunnel domain can connect. Security relies solely on the domain being secret.
569568

570569
### Changing Auth After Setup
571570

572-
To **add** authentication to an existing open proxy:
571+
To **add or change** authentication:
573572

574573
```bash
575-
# 1. Edit the microsocks service
576-
sudo systemctl edit --full microsocks.service
577-
578-
# 2. Find the ExecStart line and append: -u youruser -P yourpass
579-
# Example: ExecStart=/usr/local/bin/microsocks -p 19801 -u proxy -P s3cret
580-
581-
# 3. Reload and restart
582-
sudo systemctl daemon-reload
583-
sudo systemctl restart microsocks
574+
sudo dnstm backend auth -t socks -u youruser -p yourpassword
584575
```
585576

586577
To **remove** authentication:
587578

588579
```bash
589-
# 1. Edit the service and remove the -u and -P flags from ExecStart
590-
sudo systemctl edit --full microsocks.service
591-
592-
# 2. Reload and restart
593-
sudo systemctl daemon-reload
594-
sudo systemctl restart microsocks
580+
sudo dnstm backend auth -t socks --disable
595581
```
596582

597-
> **Note:** When adding a backup domain with `--add-domain`, the script auto-detects existing SOCKS authentication from the microsocks service and includes the credentials in the generated share URLs.
583+
> **Note:** When adding a backup domain with `--add-domain`, the script auto-detects existing SOCKS authentication via `dnstm backend status` and includes the credentials in the generated share URLs.
598584
599585
---
600586

dnstm-setup.sh

Lines changed: 79 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,36 @@ show_about() {
554554
echo ""
555555
}
556556

557+
# ─── SOCKS Auth Detection Helper ──────────────────────────────────────────────
558+
559+
# Detect SOCKS5 auth state from dnstm backend status.
560+
# Sets globals: SOCKS_AUTH (true/false), SOCKS_USER, SOCKS_PASS
561+
# Returns 0 if auth is enabled, 1 otherwise.
562+
detect_socks_auth() {
563+
local status_output
564+
status_output=$(dnstm backend status -t socks 2>/dev/null || true)
565+
local detected_user detected_pass
566+
detected_user=$(echo "$status_output" | sed -n 's/^[[:space:]]*User:[[:space:]]*//p' | sed 's/[[:space:]]*$//' || true)
567+
detected_pass=$(echo "$status_output" | sed -n 's/^[[:space:]]*Password:[[:space:]]*//p' | sed 's/[[:space:]]*$//' || true)
568+
if [[ -n "$detected_user" && -n "$detected_pass" ]]; then
569+
# Reject credentials with pipe chars (would corrupt slipnet URL format)
570+
if [[ "$detected_user" == *"|"* || "$detected_pass" == *"|"* ]]; then
571+
SOCKS_AUTH=false
572+
SOCKS_USER=""
573+
SOCKS_PASS=""
574+
return 1
575+
fi
576+
SOCKS_AUTH=true
577+
SOCKS_USER="$detected_user"
578+
SOCKS_PASS="$detected_pass"
579+
return 0
580+
fi
581+
SOCKS_AUTH=false
582+
SOCKS_USER=""
583+
SOCKS_PASS=""
584+
return 1
585+
}
586+
557587
# ─── --status ───────────────────────────────────────────────────────────────────
558588

559589
do_status() {
@@ -595,18 +625,9 @@ do_status() {
595625
fi
596626
echo ""
597627

598-
# ─── Detect SOCKS auth ───
599-
local socks_user="" socks_pass="" socks_auth=false
600-
local svc_file="/etc/systemd/system/microsocks.service"
601-
if [[ -f "$svc_file" ]]; then
602-
local exec_line
603-
exec_line=$(grep '^ExecStart=' "$svc_file" 2>/dev/null || true)
604-
socks_user=$(echo "$exec_line" | sed -n 's/.*-u \([^ ]*\).*/\1/p' || true)
605-
socks_pass=$(echo "$exec_line" | sed -n 's/.*-P \([^ ]*\).*/\1/p' || true)
606-
if [[ -n "$socks_user" && -n "$socks_pass" ]]; then
607-
socks_auth=true
608-
fi
609-
fi
628+
# ─── Detect SOCKS auth via dnstm ───
629+
detect_socks_auth || true
630+
local socks_user="$SOCKS_USER" socks_pass="$SOCKS_PASS" socks_auth="$SOCKS_AUTH"
610631

611632
echo -e " ${BOLD}SOCKS Proxy Authentication${NC}"
612633
echo -e " ${DIM}────────────────────────────────────────${NC}"
@@ -1332,15 +1353,9 @@ do_add_tunnel() {
13321353

13331354
# Generate slipnet:// URL for non-SSH tunnels
13341355
if [[ "$backend" == "socks" ]]; then
1335-
# Detect existing SOCKS auth from microsocks service
1336-
local s_user="" s_pass=""
1337-
local svc_file="/etc/systemd/system/microsocks.service"
1338-
if [[ -f "$svc_file" ]]; then
1339-
local exec_line
1340-
exec_line=$(grep '^ExecStart=' "$svc_file" 2>/dev/null || true)
1341-
s_user=$(echo "$exec_line" | sed -n 's/.*-u \([^ ]*\).*/\1/p' || true)
1342-
s_pass=$(echo "$exec_line" | sed -n 's/.*-P \([^ ]*\).*/\1/p' || true)
1343-
fi
1356+
# Detect existing SOCKS auth via dnstm
1357+
detect_socks_auth || true
1358+
local s_user="$SOCKS_USER" s_pass="$SOCKS_PASS"
13441359

13451360
local pubkey_for_url=""
13461361
if [[ "$transport" == "dnstt" && -f "/etc/dnstm/tunnels/${tag}/server.pub" ]]; then
@@ -1577,6 +1592,10 @@ do_manage_users() {
15771592
print_fail "Username cannot be empty"
15781593
continue
15791594
fi
1595+
if [[ "$new_user" == *"|"* ]]; then
1596+
print_fail "Username cannot contain the | character"
1597+
continue
1598+
fi
15801599
new_pass=$(prompt_input "Enter password (leave blank to auto-generate)")
15811600
echo ""
15821601
if [[ -n "$new_pass" ]]; then
@@ -2413,11 +2432,21 @@ step_verify_microsocks() {
24132432
print_fail "Username cannot be empty"
24142433
SOCKS_USER="proxy"
24152434
fi
2435+
# Reject pipe and colon in username (breaks slipnet URL format and curl --proxy-user)
2436+
if [[ "$SOCKS_USER" == *"|"* || "$SOCKS_USER" == *":"* ]]; then
2437+
print_warn "Username cannot contain | or : characters — using default 'proxy'"
2438+
SOCKS_USER="proxy"
2439+
fi
24162440
SOCKS_PASS=$(prompt_input "Enter SOCKS proxy password")
24172441
if [[ -z "$SOCKS_PASS" ]]; then
24182442
print_fail "Password cannot be empty — disabling SOCKS auth"
24192443
SOCKS_USER=""
24202444
SOCKS_PASS=""
2445+
# Reject pipe in password (breaks slipnet URL pipe-delimited format)
2446+
elif [[ "$SOCKS_PASS" == *"|"* ]]; then
2447+
print_fail "Password cannot contain the | character — disabling SOCKS auth"
2448+
SOCKS_USER=""
2449+
SOCKS_PASS=""
24212450
else
24222451
SOCKS_AUTH=true
24232452
print_ok "SOCKS authentication enabled (user: ${SOCKS_USER})"
@@ -2427,102 +2456,42 @@ step_verify_microsocks() {
24272456
fi
24282457
echo ""
24292458

2430-
# Check if microsocks binary has GLIBC compatibility issues
2431-
local microsocks_bin
2432-
microsocks_bin=$(command -v microsocks 2>/dev/null || echo "/usr/local/bin/microsocks")
2433-
if [[ -x "$microsocks_bin" ]]; then
2434-
local glibc_err
2435-
glibc_err=$("$microsocks_bin" --help 2>&1 || true)
2436-
if echo "$glibc_err" | grep -q "GLIBC.*not found"; then
2437-
print_warn "microsocks binary is incompatible with this OS (GLIBC version mismatch)"
2438-
print_info "Building microsocks from source..."
2439-
2440-
# Install build tools
2441-
apt-get install -y -qq gcc make git >/dev/null 2>&1 || true
2442-
2443-
# Build from source
2444-
local build_dir="/tmp/microsocks-build"
2445-
rm -rf "$build_dir"
2446-
if git clone --quiet https://github.com/rofl0r/microsocks.git "$build_dir" 2>/dev/null; then
2447-
if make -C "$build_dir" -j"$(nproc)" >/dev/null 2>&1; then
2448-
cp "$build_dir/microsocks" "$microsocks_bin"
2449-
chmod +x "$microsocks_bin"
2450-
print_ok "Built microsocks from source"
2451-
# Restart the service with the new binary
2452-
systemctl restart microsocks 2>/dev/null || true
2453-
sleep 1
2454-
else
2455-
print_fail "Failed to build microsocks from source"
2456-
fi
2457-
else
2458-
print_fail "Failed to clone microsocks repo"
2459-
fi
2460-
rm -rf "$build_dir"
2461-
fi
2462-
fi
2463-
2464-
# Check if microsocks is running
2459+
# Check if microsocks is running (dnstm manages the binary and service)
2460+
local microsocks_running=false
24652461
if pgrep -x microsocks &>/dev/null || systemctl is-active --quiet microsocks 2>/dev/null; then
24662462
print_ok "microsocks is running"
2463+
microsocks_running=true
24672464
else
24682465
print_warn "microsocks is not running"
24692466
print_info "Starting microsocks..."
24702467

24712468
systemctl enable microsocks 2>/dev/null || true
24722469
if systemctl start microsocks 2>/dev/null; then
24732470
print_ok "microsocks started"
2471+
microsocks_running=true
24742472
else
24752473
print_fail "Failed to start microsocks"
24762474
print_info "Check: systemctl status microsocks"
24772475
fi
24782476
fi
24792477

2480-
# Apply SOCKS authentication if enabled
2481-
if [[ "$SOCKS_AUTH" == true && -n "$SOCKS_USER" && -n "$SOCKS_PASS" ]]; then
2482-
local svc_file="/etc/systemd/system/microsocks.service"
2483-
if [[ -f "$svc_file" ]]; then
2484-
print_info "Configuring microsocks with SOCKS5 authentication..."
2485-
# Read the current ExecStart line and add -u/-P flags
2486-
local current_exec
2487-
current_exec=$(grep '^ExecStart=' "$svc_file" 2>/dev/null || true)
2488-
if [[ -n "$current_exec" ]]; then
2489-
# Remove any existing -u/-P flags to avoid duplicates
2490-
# Use awk for safe handling of passwords with sed metacharacters
2491-
local clean_exec
2492-
clean_exec=$(echo "$current_exec" | awk '{
2493-
r=""; skip=0
2494-
for(i=1;i<=NF;i++){
2495-
if($i=="-u"||$i=="-P"){skip=1;continue}
2496-
if(skip){skip=0;continue}
2497-
r=(r?r" ":"")$i
2498-
}
2499-
print r
2500-
}')
2501-
# Append auth flags — pass each piece via separate ENVIRON
2502-
# vars so shell never interprets special chars in credentials
2503-
_CLEAN="$clean_exec" _USER="$SOCKS_USER" _PASS="$SOCKS_PASS" awk \
2504-
'/^ExecStart=/{print ENVIRON["_CLEAN"] " -u " ENVIRON["_USER"] " -P " ENVIRON["_PASS"]; next}{print}' \
2505-
"$svc_file" > "${svc_file}.tmp" \
2506-
&& mv "${svc_file}.tmp" "$svc_file"
2507-
systemctl daemon-reload 2>/dev/null || true
2508-
systemctl restart microsocks 2>/dev/null || true
2509-
sleep 2
2510-
# Verify microsocks came back up
2511-
if pgrep -x microsocks &>/dev/null || systemctl is-active --quiet microsocks 2>/dev/null; then
2512-
print_ok "microsocks configured with SOCKS5 authentication"
2513-
else
2514-
print_warn "microsocks may have failed to restart — check: systemctl status microsocks"
2515-
fi
2516-
else
2517-
print_warn "Could not find ExecStart in microsocks.service — auth not applied"
2518-
SOCKS_AUTH=false
2519-
fi
2478+
# Apply SOCKS authentication via dnstm (v0.6.8+) — only if microsocks is running
2479+
if [[ "$microsocks_running" == true && "$SOCKS_AUTH" == true && -n "$SOCKS_USER" && -n "$SOCKS_PASS" ]]; then
2480+
print_info "Configuring SOCKS5 authentication via dnstm..."
2481+
if dnstm backend auth -t socks -u "$SOCKS_USER" -p "$SOCKS_PASS" 2>/dev/null; then
2482+
print_ok "SOCKS5 authentication enabled (user: ${SOCKS_USER})"
25202483
else
2521-
print_warn "microsocks.service not found — auth not applied"
2484+
print_warn "Failed to configure SOCKS5 authentication via dnstm"
2485+
print_info "Try manually: dnstm backend auth -t socks -u ${SOCKS_USER} -p <password>"
25222486
SOCKS_AUTH=false
25232487
fi
25242488
fi
25252489

2490+
if [[ "$microsocks_running" != true ]]; then
2491+
print_warn "Skipping SOCKS proxy test — microsocks is not running"
2492+
return
2493+
fi
2494+
25262495
# Detect actual microsocks port (3 methods, most reliable first)
25272496
local socks_port=""
25282497
# Method 1: parse ss output — find the listen port on the microsocks line
@@ -2609,13 +2578,21 @@ step_ssh_user() {
26092578
print_fail "Username cannot be empty"
26102579
return
26112580
fi
2581+
if [[ "$SSH_USER" == *"|"* ]]; then
2582+
print_fail "Username cannot contain the | character"
2583+
return
2584+
fi
26122585

26132586
# Get password
26142587
SSH_PASS=$(prompt_input "Enter password for SSH tunnel user")
26152588
if [[ -z "$SSH_PASS" ]]; then
26162589
print_fail "Password cannot be empty"
26172590
return
26182591
fi
2592+
if [[ "$SSH_PASS" == *"|"* ]]; then
2593+
print_fail "Password cannot contain the | character"
2594+
return
2595+
fi
26192596

26202597
echo ""
26212598

@@ -3044,22 +3021,11 @@ do_add_domain() {
30443021
print_info "Creating 4 tunnels (set #${num}) for domain: ${BOLD}${DOMAIN}${NC}"
30453022
echo ""
30463023

3047-
# Detect existing SOCKS authentication from microsocks service
3048-
local svc_file="/etc/systemd/system/microsocks.service"
3049-
if [[ -f "$svc_file" ]]; then
3050-
local existing_exec
3051-
existing_exec=$(grep '^ExecStart=' "$svc_file" 2>/dev/null || true)
3052-
local existing_socks_user existing_socks_pass
3053-
existing_socks_user=$(echo "$existing_exec" | sed -n 's/.*-u \([^ ]*\).*/\1/p' || true)
3054-
existing_socks_pass=$(echo "$existing_exec" | sed -n 's/.*-P \([^ ]*\).*/\1/p' || true)
3055-
if [[ -n "$existing_socks_user" && -n "$existing_socks_pass" ]]; then
3056-
SOCKS_AUTH=true
3057-
SOCKS_USER="$existing_socks_user"
3058-
SOCKS_PASS="$existing_socks_pass"
3059-
print_ok "Detected existing SOCKS authentication (user: ${SOCKS_USER})"
3060-
else
3061-
print_info "SOCKS proxy has no authentication configured"
3062-
fi
3024+
# Detect existing SOCKS authentication via dnstm
3025+
if detect_socks_auth; then
3026+
print_ok "Detected existing SOCKS authentication (user: ${SOCKS_USER})"
3027+
else
3028+
print_info "SOCKS proxy has no authentication configured"
30633029
fi
30643030
echo ""
30653031

0 commit comments

Comments
 (0)