Vpn Rotate Skill
by @acastellana
Bypass API rate limits by rotating VPN servers. Works with any OpenVPN-compatible VPN (ProtonVPN, NordVPN, Mullvad, etc.). Automatically rotates to new server every N requests for fresh IPs. Use for high-volume scraping, government APIs, geo-restricted data.
clawhub install vpn-rotate-skillπ About This Skill
name: vpn-rotate-skill description: Bypass API rate limits by rotating VPN servers. Works with any OpenVPN-compatible VPN (ProtonVPN, NordVPN, Mullvad, etc.). Automatically rotates to new server every N requests for fresh IPs. Use for high-volume scraping, government APIs, geo-restricted data.
VPN Rotate Skill
Rotate VPN servers to bypass API rate limits. Works with any OpenVPN-compatible VPN.
Setup
1. Run Setup Wizard
./scripts/setup.sh
This will:
2. Manual Setup
If you prefer manual setup:
# Install OpenVPN
sudo apt install openvpnCreate config directory
mkdir -p ~/.vpn/serversDownload .ovpn files from your VPN provider
Put them in ~/.vpn/servers/
Create credentials file
echo "your_username" > ~/.vpn/creds.txt
echo "your_password" >> ~/.vpn/creds.txt
chmod 600 ~/.vpn/creds.txtEnable passwordless sudo for openvpn
echo "$USER ALL=(ALL) NOPASSWD: /usr/sbin/openvpn, /usr/bin/killall" | sudo tee /etc/sudoers.d/openvpn
Usage
Decorator (Recommended)
from scripts.decorator import with_vpn_rotation@with_vpn_rotation(rotate_every=10, delay=1.0)
def scrape(url):
return requests.get(url).json()
Automatically rotates VPN every 10 calls
for url in urls:
data = scrape(url)
VPN Class
from scripts.vpn import VPNvpn = VPN()
Connect
vpn.connect()
print(vpn.get_ip()) # New IPRotate (disconnect + reconnect to different server)
vpn.rotate()
print(vpn.get_ip()) # Different IPDisconnect
vpn.disconnect()
Context Manager
from scripts.vpn import VPNvpn = VPN()
with vpn.session():
# VPN connected
for url in urls:
vpn.before_request() # Handles rotation
data = requests.get(url).json()
VPN disconnected
CLI
python scripts/vpn.py connect
python scripts/vpn.py status
python scripts/vpn.py rotate
python scripts/vpn.py disconnect
python scripts/vpn.py ip
Configuration
Decorator Options
@with_vpn_rotation(
rotate_every=10, # Rotate after N requests
delay=1.0, # Seconds between requests
config_dir=None, # Override config directory
creds_file=None, # Override credentials file
country=None, # Filter servers by country prefix (e.g., "us")
auto_connect=True, # Connect automatically on first request
)
VPN Class Options
VPN(
config_dir="~/.vpn/servers",
creds_file="~/.vpn/creds.txt",
rotate_every=10,
delay=1.0,
verbose=True,
)
Recommended Settings
| API Aggressiveness | rotate_every | delay | |-------------------|--------------|-------| | Aggressive (Catastro, LinkedIn) | 5 | 2.0s | | Standard | 10 | 1.0s | | Lenient | 20-50 | 0.5s |
Files
vpn-rotate-skill/
βββ SKILL.md # This file
βββ README.md # Overview
βββ scripts/
β βββ vpn.py # VPN controller
β βββ decorator.py # @with_vpn_rotation
β βββ setup.sh # Setup wizard
βββ examples/
β βββ catastro.py # Spanish property API example
βββ providers/
βββ protonvpn.md # ProtonVPN setup
βββ nordvpn.md # NordVPN setup
βββ mullvad.md # Mullvad setup
Troubleshooting
"sudo: a password is required"
Run the setup script or manually add sudoers entry:
echo "$USER ALL=(ALL) NOPASSWD: /usr/sbin/openvpn, /usr/bin/killall" | sudo tee /etc/sudoers.d/openvpn
Connection fails
1. Check credentials are correct
2. Test manually: sudo openvpn --config ~/.vpn/servers/server.ovpn --auth-user-pass ~/.vpn/creds.txt
3. Check VPN provider account is active
Still getting blocked
1. Lower rotate_every (try 5 instead of 10)
2. Increase delay (try 2-3 seconds)
3. Check if API blocks VPN IPs entirely
No .ovpn files
Download from your VPN provider:
π‘ Examples
Decorator (Recommended)
from scripts.decorator import with_vpn_rotation@with_vpn_rotation(rotate_every=10, delay=1.0)
def scrape(url):
return requests.get(url).json()
Automatically rotates VPN every 10 calls
for url in urls:
data = scrape(url)
VPN Class
from scripts.vpn import VPNvpn = VPN()
Connect
vpn.connect()
print(vpn.get_ip()) # New IPRotate (disconnect + reconnect to different server)
vpn.rotate()
print(vpn.get_ip()) # Different IPDisconnect
vpn.disconnect()
Context Manager
from scripts.vpn import VPNvpn = VPN()
with vpn.session():
# VPN connected
for url in urls:
vpn.before_request() # Handles rotation
data = requests.get(url).json()
VPN disconnected
CLI
python scripts/vpn.py connect
python scripts/vpn.py status
python scripts/vpn.py rotate
python scripts/vpn.py disconnect
python scripts/vpn.py ip
βοΈ Configuration
Decorator Options
@with_vpn_rotation(
rotate_every=10, # Rotate after N requests
delay=1.0, # Seconds between requests
config_dir=None, # Override config directory
creds_file=None, # Override credentials file
country=None, # Filter servers by country prefix (e.g., "us")
auto_connect=True, # Connect automatically on first request
)
VPN Class Options
VPN(
config_dir="~/.vpn/servers",
creds_file="~/.vpn/creds.txt",
rotate_every=10,
delay=1.0,
verbose=True,
)
π Tips & Best Practices
"sudo: a password is required"
Run the setup script or manually add sudoers entry:
echo "$USER ALL=(ALL) NOPASSWD: /usr/sbin/openvpn, /usr/bin/killall" | sudo tee /etc/sudoers.d/openvpn
Connection fails
1. Check credentials are correct
2. Test manually: sudo openvpn --config ~/.vpn/servers/server.ovpn --auth-user-pass ~/.vpn/creds.txt
3. Check VPN provider account is active
Still getting blocked
1. Lower rotate_every (try 5 instead of 10)
2. Increase delay (try 2-3 seconds)
3. Check if API blocks VPN IPs entirely
No .ovpn files
Download from your VPN provider: