Пожалуйста, обратите внимание, что пользователь заблокирован
The first thing I did was consider the possibility of hiding and securing the IP of my work VPS for reconnaissance on targets, so I paid for a Kali Linux VPS (based on Debian). They gave me the public IP of my VPS and port 22 to connect to it via SSH.
Investigating a little about how to run mullvad vpn on my vps without affecting the already configured connections (so that it doesn't disconnect me from ssh, rdp and other services to manage my vps), I found the following issue on the official mullvad site on github: https://github.com/mullvad/mullvadvpn-app/issues/6758 and this post: https://xel.sh/blog/mullvad-ssh
Based on these, I set to work to achieve the network workflow I wanted.
You must manage Mullvad manually by typing: mullvad connect, mullvad login "key" from your console or by RDP from the app-gui by RDP.
When connecting Mullvad to one of the servers, the public IP of your VPS will be inaccessible, if you ping it you will not get a response, if you enter it in the Shodan search engine it will not appear, only the Mullvad IP will mask the public IP of your VPS, you can check it by doing: curl ifconfig.me, but you will be able to connect to your VPS through the ports previously configured for SSH and RDP using your public VPS IP, ex: ssh -p 47320 user@<ipvps>, the same for RDP
The script It automatically creates all the necessary configurations for this, detects the gateway and interface, adds the sshroute table to rt_tables if it doesn't exist, adds ip rule and ip route rules, adjusts nftables to mark ports 47320 (SSH) and 47650 (RDP) -The ones I configured, change them to yours.
Save the following script in /usr/local/bin/ with:
Make it executable:
Run:
Create a systemd service to run at startup, edit and save:
Paste this:
Activate it with:
Connect Mullvad VPN manually with the command or enter via RDP and from the mullvad app:
This first step is ready, you can now work from the VPS making all traffic go through the mullvad VPN, you can check it by doing curl ifconfig.me (You will see a different IP than your VPS, you will be able to connect to the servers you want by location or country in mullvad and the IP of your VPS will only be accessible to you.
After some more thought, the idea of manually connecting the VPN to another location to continue my reconnaissance every time I get restricted from that IP (if a firewall or whatever blocks the current IP I’m using for that purpose) seemed quite annoying, so I looked into using another VPN, since my VPS is already secure through the first Mulllvad connection, but I want the traffic to go out through other IPs, not the first VPN that masks my VPS IP, so I made another script for that
I called this other script subnet, since it creates virtual hosts and isolated namespaces so as not to affect the connection of the main VPN and to perform the reconnaissance on the second VPN.
First I entered the account of the second mullvad vpn that I paid for, I tried with the openvpn confs, but for some reason I couldn't connect, so I modified it to use the mullvad wireguard configurations, I downloaded them, unzipped them and saved them in the working directory to use the script, in my case: /opt/Mvad_relay-listwire, in the script you must change this directory to yours and change the host and nameserver ip to yours
Edit and save the script in /usr/local/bin/ to use it globally:
Give it permissions:
If everything is configured correctly you can test it in the following way: subnet curl ifconfig.me, it will show you a different IP than the one that the first mullvad VPN has, it is the second mask, also if you use the auto-recon command in the script, it will rotate every 15-20 minutes to other servers automatically connecting to other locations to continue with the recon in case it blacklistens that IP due to the amount of requests made by tools like nmap, etc.
The commands: subnet nmap ----- subnet nikto ------ subnet auto-recon nmap can be run in each terminal individually, the script will automatically select the servers to which it will connect to run the requested command and once it finishes running the requested command it is automatically cleaned.
Hardening SSH and RDP or configure an firewall is easy, I won't do writeups on that for now. I hope it helps you.
Thanks for reading
Investigating a little about how to run mullvad vpn on my vps without affecting the already configured connections (so that it doesn't disconnect me from ssh, rdp and other services to manage my vps), I found the following issue on the official mullvad site on github: https://github.com/mullvad/mullvadvpn-app/issues/6758 and this post: https://xel.sh/blog/mullvad-ssh
Based on these, I set to work to achieve the network workflow I wanted.
- I bought two mullvad accounts using Tor browser, paid with XMR and saved my access keys.
- I configured SSH and RDP on non-common ports, other than 22, 2222 for ssh or 3389 or 3390 for RDP and i added them to the rules to exclude SSH and RDP traffic from the VPN tunnel and made it persistent so as not to lose remote access.
- I installed nftables and made a complete script to only configure the routes and nftables persistently, which would be executed at system startup (in case the VPS is turned off or restarted, access is not lost if mullvad does not start automatically) these configurations remain persistent, make sure to change the ports to the ones you use in the rules.
You must manage Mullvad manually by typing: mullvad connect, mullvad login "key" from your console or by RDP from the app-gui by RDP.
When connecting Mullvad to one of the servers, the public IP of your VPS will be inaccessible, if you ping it you will not get a response, if you enter it in the Shodan search engine it will not appear, only the Mullvad IP will mask the public IP of your VPS, you can check it by doing: curl ifconfig.me, but you will be able to connect to your VPS through the ports previously configured for SSH and RDP using your public VPS IP, ex: ssh -p 47320 user@<ipvps>, the same for RDP
Routes and nftables configurations will be persistent and automatic at system startup to not kill remote connections (always active). Connecting and disconnecting Mullvad within the VPS is handled manually.apt update
sudo apt install -y nftables
The script It automatically creates all the necessary configurations for this, detects the gateway and interface, adds the sshroute table to rt_tables if it doesn't exist, adds ip rule and ip route rules, adjusts nftables to mark ports 47320 (SSH) and 47650 (RDP) -The ones I configured, change them to yours.
Save the following script in /usr/local/bin/ with:
nano /usr/local/bin/mullvad_routing_setup.sh
#!/usr/bin/env bash
set -e
GATEWAY=$(ip route show default | awk '/default/ {print $3}')
INTERFACE=$(ip route show default | awk '/default/ {print $5}')
RT_TABLES="/etc/iproute2/rt_tables"
TABLE_NAME="sshroute"
TABLE_ID=100
if ! grep -q "$TABLE_NAME" "$RT_TABLES" 2>/dev/null; then
echo "$TABLE_ID $TABLE_NAME" | tee -a "$RT_TABLES" >/dev/null
fi
ip rule add fwmark 0x6d6f6c65 table sshroute || true
ip route add default via $GATEWAY dev $INTERFACE table sshroute || true
NFT_CONF="/etc/nftables.conf"
if [ ! -f "$NFT_CONF.bak" ]; then
cp "$NFT_CONF" "$NFT_CONF.bak"
fi
cat > "$NFT_CONF" <<EOF
table inet excludeTraffic {
chain allowIncoming {
type filter hook input priority -100; policy accept;
tcp dport {47320, 47650} ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
}
chain allowOutgoing {
type route hook output priority -100; policy accept;
tcp sport {47320, 47650} meta mark set 0x6d6f6c65;
}
}
EOF
systemctl restart nftables.service
Make it executable:
sudo chmod +x /usr/local/bin/mullvad_routing_setup.sh
Run:
./mullvad_routing_setup.sh
Create a systemd service to run at startup, edit and save:
nano /etc/systemd/system/mullvad-routing.service
Paste this:
[Unit]
Description=Configure routes and nftables for SSH and RDP ports
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mullvad_routing_setup.sh
[Install]
WantedBy=multi-user.target
Activate it with:
sudo systemctl daemon-reload
sudo systemctl enable mullvad-routing.service
sudo systemctl start mullvad-routing.service
Connect Mullvad VPN manually with the command or enter via RDP and from the mullvad app:
command in console:
The system will always have routing and nftables configured so that your SSH (47320) and RDP (47650) ports go out through the special table. Mullvad connect and disconnect manually whenever you want. Routes and nftables will be ready and persistent by the time Mullvad is active.mullvad connect [options]
Disconnect it with:
mullvad disconnect
This first step is ready, you can now work from the VPS making all traffic go through the mullvad VPN, you can check it by doing curl ifconfig.me (You will see a different IP than your VPS, you will be able to connect to the servers you want by location or country in mullvad and the IP of your VPS will only be accessible to you.
After some more thought, the idea of manually connecting the VPN to another location to continue my reconnaissance every time I get restricted from that IP (if a firewall or whatever blocks the current IP I’m using for that purpose) seemed quite annoying, so I looked into using another VPN, since my VPS is already secure through the first Mulllvad connection, but I want the traffic to go out through other IPs, not the first VPN that masks my VPS IP, so I made another script for that
I called this other script subnet, since it creates virtual hosts and isolated namespaces so as not to affect the connection of the main VPN and to perform the reconnaissance on the second VPN.
First I entered the account of the second mullvad vpn that I paid for, I tried with the openvpn confs, but for some reason I couldn't connect, so I modified it to use the mullvad wireguard configurations, I downloaded them, unzipped them and saved them in the working directory to use the script, in my case: /opt/Mvad_relay-listwire, in the script you must change this directory to yours and change the host and nameserver ip to yours
Edit and save the script in /usr/local/bin/ to use it globally:
nano /usr/local/bin/subnet
Give it permissions:
chmod +x /usr/local/bin/subnet
#!/bin/bash
# ------------------------------------------------------------------
# subnet-recon - Professional reconnaissance tool with rotating VPN
# ------------------------------------------------------------------
# Configuration
NAMESPACE="mproxy"
VETH_HOST="veth-host"
VETH_NS="veth-ns"
IP_HOST="10.20.20.1"
IP_NS="10.20.20.2"
WG_CONF_DIR="/opt/Mvad_relay-listwire"
MAX_ATTEMPTS=3
LOG_DIR="/var/log/subnet-recon"
CURRENT_CONF=""
TIMEOUT=20 # Seconds for VPN attempt
# Network initialization
init_network() {
# Limpieza previa
ip netns del $NAMESPACE 2>/dev/null
ip link del $VETH_HOST 2>/dev/null
# Crear namespace
ip netns add $NAMESPACE || { echo "[-] Error when create namespace"; exit 1; }
# Configure interfaces
ip link add $VETH_HOST type veth peer name $VETH_NS
ip link set $VETH_NS netns $NAMESPACE
# Configure IPs
ip addr add $IP_HOST/24 dev $VETH_HOST
ip link set $VETH_HOST up
ip netns exec $NAMESPACE ip addr add $IP_NS/24 dev $VETH_NS
ip netns exec $NAMESPACE ip link set veth-ns up
ip netns exec $NAMESPACE ip link set lo up
ip netns exec $NAMESPACE ip route add default via $IP_HOST
# NAT & DNS
sysctl -w net.ipv4.ip_forward=1 >/dev/null
iptables -t nat -A POSTROUTING -s $IP_NS/24 -o $(ip route | grep default | awk '{print $5}') -j MASQUERADE
mkdir -p /etc/netns/$NAMESPACE
echo -e "nameserver 93.38.2.74\nnameserver 1.1.1.1" > /etc/netns/$NAMESPACE/resolv.conf
}
# Intelligent VPNS rotation
rotate_vpn() {
local attempts=0
local vpn_list=($(ls $WG_CONF_DIR/*.conf | shuf))
for CONF in "${vpn_list[@]}"; do
echo "[+] Probando: $(basename "$CONF")" | tee -a $LOG_FILE
# Stop previous VPN
[ -n "$CURRENT_CONF" ] && ip netns exec $NAMESPACE wg-quick down "$CURRENT_CONF" 2>/dev/null
# Try to connection with Timeout
if timeout $TIMEOUT ip netns exec $NAMESPACE wg-quick up "$CONF" &>> $LOG_FILE; then
if ip netns exec $NAMESPACE curl -4s --max-time 5 https://am.i.mullvad.net/connected &>> $LOG_FILE; then
CURRENT_CONF="$CONF"
CURRENT_IP=$(ip netns exec $NAMESPACE curl -4s ifconfig.me)
echo "[✓] VPN activa: $(basename "$CONF") (IP: $CURRENT_IP)" | tee -a $LOG_FILE
return 0
fi
fi
ip netns exec $NAMESPACE wg-quick down "$CONF" 2>/dev/null
((attempts++))
[ $attempts -ge $MAX_ATTEMPTS ] && break
done
return 1
}
# Encapsulated execution
run_command() {
local cmd="$@"
local timestamp=$(date +"%Y%m%d_%H%M%S")
local output_file="$LOG_DIR/output_${timestamp}.log"
echo "[→] Ejecutando: $cmd" | tee -a $LOG_FILE
ip netns exec $NAMESPACE $cmd | tee -a "$output_file"
return ${PIPESTATUS[0]}
}
# Professional cleaning
cleanup() {
echo "[+] Limpiando recursos..." | tee -a $LOG_FILE
[ -n "$CURRENT_CONF" ] && ip netns exec $NAMESPACE wg-quick down "$CURRENT_CONF" 2>/dev/null
ip netns del $NAMESPACE 2>/dev/null
rm -rf "/etc/netns/$NAMESPACE"
}
trap cleanup EXIT INT TERM
# ------------------------------------------------------------------
# Main execution
# ------------------------------------------------------------------
# Log settings
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/subnet-recon_$(date +"%Y%m%d").log"
# Validation of arguments
if [ $# -eq 0 ]; then
echo "Uso: $0 <comando> [opciones]"
echo "Examples:"
echo " $0 nmap -sV -Pn example.com"
echo " $0 curl ifconfig.me"
echo " $0 auto-recon (Automatic mode with periodic rotation)"
exit 1
fi
# Operation mode
init_network
if [ "$1" == "auto-recon" ]; then
# Automatic mode with continuous rotation
while true; do
if rotate_vpn; then
run_command "${@:2}"
sleep $(( RANDOM % 600 + 900 )) # Wait 15-25 minutes (900-1500 seconds)
else
echo "[-]Critical failure in VPN rotation" | tee -a $LOG_FILE
exit 1
fi
done
else
# Unique command mode
if rotate_vpn; then
run_command "$@"
else
echo "[-]Connection could not be established VPN" | tee -a $LOG_FILE
exit 1
fi
fi
If everything is configured correctly you can test it in the following way: subnet curl ifconfig.me, it will show you a different IP than the one that the first mullvad VPN has, it is the second mask, also if you use the auto-recon command in the script, it will rotate every 15-20 minutes to other servers automatically connecting to other locations to continue with the recon in case it blacklistens that IP due to the amount of requests made by tools like nmap, etc.
The commands: subnet nmap ----- subnet nikto ------ subnet auto-recon nmap can be run in each terminal individually, the script will automatically select the servers to which it will connect to run the requested command and once it finishes running the requested command it is automatically cleaned.
Example: In shell 1 command subnet nmap with output to Portugal
Example: In shell 2, subnet nmap command with output to Japan
Example shell 1:
subnet curl https://am.i.mullvad.net/connected
[+] Testing: gb-mnc-wg-003.conf
[✓] VPN activa: gb-mnc-wg-003.conf (IP: 16.70.12.10)
[→] Running: curl https://am.i.mullvad.net/connected
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 87 100 87 0 0 164 0 --:--:-- --:--:-- --:--:-- 164
You are connected to Mullvad (server gb-mnc-wg-003). Your IP address is 16.70.12.10
[+] Cleaning up resources...
Example shell 2:
#subnet curl https://am.i.mullvad.net/connected
[+] Testing: fi-hel-wg-003.conf
[✓] VPN activa: fi-hel-wg-003.conf (IP: 15.24.1.221)
[→] Running: curl https://am.i.mullvad.net/connected
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 86 100 86 0 0 140 0 --:--:-- --:--:-- --:--:-- 140
You are connected to Mullvad (server fi-hel-wg-003). Your IP address is 15.24.1.221
[+] Cleaning up resources...
FLOWCHART:
┌────────────────────┐
│ Public VPS │
│ 16.21.66.X │
└────────┬───────────┘
│
▼
┌────────────────────┐
│ VPN1: WireGuard │
│ wg0: 16.70.14.X │
└────────┬───────────┘
│
▼
┌───────────────────────────┐
│ Using command: subnet <command>
└────────┬──────────────────┘
│
▼
┌────────────────────┐
│ VPN2 (namespace) │
│ 13.136.17.X │
└────────────────────┘
Hardening SSH and RDP or configure an firewall is easy, I won't do writeups on that for now. I hope it helps you.
Thanks for reading
Последнее редактирование модератором: