diff --git a/README.md b/README.md index 61b0dc0..c6a3394 100644 --- a/README.md +++ b/README.md @@ -974,6 +974,31 @@ mtproxymax tune clear all # Revert all Whitelisted params are regex-validated on input. Invalid values are rejected. Also available in **TUI: Settings > [n] Engine tuning**. +#### Middle-End NAT address with policy routing + +If Telegram traffic leaves through a VPN gateway while ordinary IP discovery uses +the server's WAN, ME key derivation may use the wrong public address. Persist the +actual IPv4 egress address and disable probing through the existing tuning commands: + +```bash +mtproxymax tune set middle_proxy_nat_ip 203.0.113.10 +mtproxymax tune set middle_proxy_nat_probe false +``` + +Replace the example with the public IPv4 address seen by Telegram. These overrides +are saved in `/opt/mtproxymax/tunings.conf` and reapplied when primary or additional +instance configs are generated. Each command can restart the running proxy. NAT +must also preserve the source TCP port for a direct ME connection; an IP override +alone cannot repair port translation or an unreachable route. With a compatible +SOCKS upstream, a valid public `BND.ADDR/BND.PORT` tuple supplies the ME endpoint. + +Restore automatic engine behavior with: + +```bash +mtproxymax tune clear middle_proxy_nat_ip +mtproxymax tune clear middle_proxy_nat_probe +``` + --- ### ✅ Verify & Audit diff --git a/mtproxymax.sh b/mtproxymax.sh index 8b28912..c09e6ca 100644 --- a/mtproxymax.sh +++ b/mtproxymax.sh @@ -4741,6 +4741,8 @@ _TUNE_WHITELIST=( "accept_permit_timeout_ms:server:^[0-9]+$" "prefer_ipv6:general:^(true|false)$" "fast_mode:general:^(true|false)$" + "middle_proxy_nat_ip:general:^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])[.]){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$" + "middle_proxy_nat_probe:general:^(true|false)$" "log_level:general:^(debug|verbose|normal|silent)$" "direct_relay_buffer_budget_max_bytes:general:^[0-9]+$" "conntrack_control:server:^(true|false)$" diff --git a/tests/test_me_nat_tuning.sh b/tests/test_me_nat_tuning.sh new file mode 100644 index 0000000..f540b9f --- /dev/null +++ b/tests/test_me_nat_tuning.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Persistent ME NAT overrides must survive primary and instance regeneration. +set -eo pipefail +test_root=$(mktemp -d) +trap 'rm -rf "$test_root"' EXIT +export INSTALL_DIR="$test_root/install" +export CONFIG_DIR="$INSTALL_DIR/mtproxy" +export SETTINGS_FILE="$INSTALL_DIR/settings.conf" +export _TUNE_FILE="$INSTALL_DIR/tunings.conf" +mkdir -p "$CONFIG_DIR" +MTPROXYMAX_SOURCE_ONLY=true source "$(dirname "${BASH_SOURCE[0]}")/../mtproxymax.sh" +set -eo pipefail +check_root() { :; } +confirm_settings_restart() { return 0; } +is_proxy_running() { return 1; } +log_success() { :; } +log_error() { :; } + +generate_telemt_config +! grep -q '^middle_proxy_nat_' "$CONFIG_DIR/config.toml" + +tune_set middle_proxy_nat_ip 203.0.113.10 +tune_set middle_proxy_nat_probe false +cp "$_TUNE_FILE" "$test_root/before" +for invalid in 256.1.1.1 1.2.3 01.2.3.4 hostname '1.2.3.4"' '1.2.3.4/24'; do + if tune_set middle_proxy_nat_ip "$invalid"; then + echo "FAIL: accepted invalid NAT IP: $invalid" >&2 + exit 1 + fi +done +if tune_set middle_proxy_nat_probe yes; then + echo 'FAIL: accepted invalid probe boolean' >&2 + exit 1 +fi +cmp "$test_root/before" "$_TUNE_FILE" + +# Read persisted values during config generation, including an instance destination. +for destination in "$CONFIG_DIR/config.toml" "$CONFIG_DIR/instance.toml" "$CONFIG_DIR/config.toml"; do + generate_telemt_config "$destination" + test "$(grep -c '^middle_proxy_nat_ip = "203.0.113.10"$' "$destination")" -eq 1 + test "$(grep -c '^middle_proxy_nat_probe = false$' "$destination")" -eq 1 + awk ' + /^\[/ {section=$0} + /^middle_proxy_nat_/ && section != "[general]" {exit 1} + ' "$destination" +done + +tune_clear middle_proxy_nat_ip +tune_clear middle_proxy_nat_probe +generate_telemt_config +! grep -q '^middle_proxy_nat_' "$CONFIG_DIR/config.toml" +echo 'PASS: ME NAT persistence, primary/instance regeneration, validation and clearing'