Operations 36 min read

frp vs WireGuard vs Tailscale: Hands-on Internal Network Penetration Comparison

This comprehensive guide compares frp, WireGuard, and Tailscale for internal network penetration, detailing deployment steps, configuration examples, troubleshooting tips, real-world latency and bandwidth benchmarks, and scenario-based recommendations to help operations engineers select the optimal solution.

Raymond Ops
Raymond Ops
Raymond Ops
frp vs WireGuard vs Tailscale: Hands-on Internal Network Penetration Comparison

Background and Applicable Scenarios

Operations engineers frequently encounter situations where locally developed services need exposure to the public internet for debugging, cloud servers behind NAT require access from home, Raspberry Pi devices need remote management, or multiple servers must communicate across different LANs. These scenarios all require internal network penetration technology.

The core problem of internal network penetration is how to allow external access to devices behind NAT. Three common approaches exist:

Port mapping : Configure port forwarding on the egress router (requires router control).

Reverse proxy : Relay traffic through a public IP relay server (frp, ngrok).

VPN tunnel : Establish encrypted tunnels to form a virtual LAN (WireGuard, Tailscale).

This article compares frp, WireGuard, and Tailscale from a practical operations perspective, covering which scenario suits which tool, how to deploy, and how to troubleshoot common issues.

Suitable scenarios for this article:

Local development exposing webhooks to the public internet

Remote work accessing company internal servers

Remote management of Raspberry Pi or NAS devices

Multiple cloud servers forming a private network

IoT devices requiring remote monitoring and management

Temporary test environments needing quick networking

frp Internal Network Penetration

Working Principle

frp (Fast Reverse Proxy) is the most traditional internal network penetration solution. It uses a C/S architecture requiring a public IP server as a relay:

[Internal Device] --frpc--> [Public Server frps] ---> [External User]
     <--frpc----          <------

frp features full control, no third-party dependency, and traffic passes through the relay server. The downside is bandwidth bottlenecks and latency because all traffic traverses the relay.

Server Deployment

# 1. Download frp (server is frps, client is frpc)
# releases page: https://github.com/fatedier/frp/releases
# Download matching architecture (Linux amd64 example)
wget https://github.com/fatedier/frp/releases/download/v0.60.0/frp_0.60.0_linux_amd64.tar.gz
tar -xzf frp_0.60.0_linux_amd64.tar.gz
cd frp_0.60.0_linux_amd64

# 2. Create frps configuration file
cat > frps.ini << 'EOF'
[common]
# frps listen address (public server IP)
bind_addr = 0.0.0.0
bind_port = 7000

# Token for client authentication
token = your-secret-token-here

# HTTP service listen ports
vhost_http_port = 80
vhost_https_port = 443

# Dashboard (optional, monitor frp connections)
dashboard_addr = 0.0.0.0
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = your-dashboard-password

# Log configuration
log_file = /var/log/frps.log
log_level = info
log_max_days = 3
EOF

# 3. Create systemd service
cat > /etc/systemd/system/frps.service << 'EOF'
[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
User=root
ExecStart=/opt/frp/frps -c /opt/frp/frps.ini
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

# 4. Start frps
mkdir -p /opt/frp
cp frps frps.ini /opt/frp/
systemctl daemon-reload
systemctl enable frps
systemctl start frps

# 5. Verify frps running status
systemctl status frps
netstat -tlnp | grep frps

Client Deployment (Linux)

# 1. Download frpc (client)
# releases page: https://github.com/fatedier/frp/releases
# Select matching architecture
wget https://github.com/fatedier/frp/releases/download/v0.60.0/frp_0.60.0_linux_amd64.tar.gz
tar -xzf frp_0.60.0_linux_amd64.tar.gz
cd frp_0.60.0_linux_amd64

# 2. Create frpc configuration file
cat > frpc.ini << 'EOF'
[common]
# frps server address
server_addr = your-frps-ip
server_port = 7000

# Auth token, must match frps
token = your-secret-token-here

# Log configuration
log_file = /var/log/frpc.log
log_level = info
log_max_days = 3

# SSH penetration example
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 2222

# Web service penetration example
[web]
type = http
local_ip = 127.0.0.1
local_port = 8080
custom_domains = your-domain.com

# TCP penetration example (access internal MySQL)
[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3306
remote_port = 13306
EOF

# 3. Create systemd service
cat > /etc/systemd/system/frpc.service << 'EOF'
[Unit]
Description=Frp Client Service
After=network.target

[Service]
Type=simple
User=root
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.ini
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

# 4. Start frpc
mkdir -p /opt/frp
cp frpc frpc.ini /opt/frp/
systemctl daemon-reload
systemctl enable frpc
systemctl start frpc

# 5. Verify
systemctl status frpc

Client Deployment (Windows)

# 1. Download Windows version
# https://github.com/fatedier/frp/releases

# 2. Create frpc.ini (same as Linux)

# 3. Create startup script start-frpc.bat
@echo off
cd /d %~dp0
frpc.exe -c frpc.ini
pause

# 4. Optional: Register as Windows service (requires NSSM or winsw)
# Download winsw: https://github.com/winsw/winsw/releases
# Create frpc.xml config file
# Run as admin: winsw.exe install frpc.xml

Configuration Details

Complete frps.ini example with all options:

# frps.ini complete configuration example
[common]
# Basic configuration
bind_addr = 0.0.0.0
bind_port = 7000

# Authentication
token = your-secret-token-here

# Port configuration
# vhost_http_port and vhost_https_port are HTTP/HTTPS ports frps listens on
vhost_http_port = 80
vhost_https_port = 443

# If frps has multiple IPs, specify a specific IP to listen on
# bind_addr = 1.2.3.4

# Allowed port range for clients (optional)
# Client remote_port within this range gets auto-allocated by frps
# allow_ports = 2000-3000, 3005, 5000-6000

# Connection timeout
max_pool_count = 5
max_ports_per_client = 0

# Heartbeat configuration
heartbeat_interval = 10
heartbeat_timeout = 90

# Bandwidth limit (optional)
# Single proxy bandwidth limit
# bandwidth_limit_type = server
# bandwidth_limit = 1MB

# Authentication timeout
authentication_timeout = 900

# Port whitelist (optional)
# allow_ports = 1000-2000, 3000

# Log
log_file = /var/log/frps.log
log_level = info
log_max_days = 3

Complete frpc.ini example:

# frpc.ini complete configuration example
[common]
server_addr = 1.2.3.4
server_port = 7000
token = your-secret-token-here

# Log
log_file = /var/log/frpc.log
log_level = info

# Authentication methods (besides token, there is oidc auth)
# oidc_audience = your-audience
# oidc_client_id = your-client-id
# oidc_client_secret = your-client-secret

# Wildcard domain HTTP penetration example
[web]
type = http
local_ip = 127.0.0.1
local_port = 8080
# Wildcard domain requires DNS resolution to frps server
subdomain = app
custom_domains = app.your-domain.com

# Multiple web services sharing port 80
[web1]
type = http
local_ip = 127.0.0.1
local_port = 3000
subdomain = api

[web2]
type = http
local_ip = 127.0.0.1
local_port = 4000
subdomain = admin

# HTTPS penetration example
[web_https]
type = https
local_ip = 127.0.0.1
local_port = 443
custom_domains = secure.your-domain.com
# frps automatically handles TLS termination
plugin = https2http
plugin_local_addr = 127.0.0.1:8080

# TCP penetration example
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 2222

# UDP penetration example (remote desktop, game servers)
[minecraft]
type = udp
local_ip = 127.0.0.1
local_port = 25565
remote_port = 25565

# STCP penetration (secure TCP, both sides run frpc)
[secret_ssh]
type = stcp
local_ip = 127.0.0.1
local_port = 22
# Visitor must know this secret_key
sk = your-secret-key

# XTCP penetration (hole punching, p2p direct, fallback to relay)
[xtcp]
type = xtcp
local_ip = 127.0.0.1
local_port = 9000
sk = your-secret-key

frp Common Troubleshooting

# 1. View frps logs
tail -f /var/log/frps.log

# 2. View frpc logs
tail -f /var/log/frpc.log

# 3. Test if frps port is reachable
# On client side
nc -zv your-frps-ip 7000
telnet your-frps-ip 7000

# 4. Client connection failure troubleshooting
# 1. Check if token matches
# 2. Check if firewall opens port 7000
# 3. Check if frps runs normally
systemctl status frps

# 5. HTTP penetration not working troubleshooting
# 1. Check if domain DNS resolves correctly to frps IP
nslookup app.your-domain.com

# 2. Check if frps vhost_http_port matches domain config
# 3. Check if frpc custom_domains is correct

# 6. frpc unstable connection troubleshooting
# 1. Adjust heartbeat interval
# frpc.ini add:
heartbeat_interval = 5
heartbeat_timeout = 20

# 7. Bandwidth limitation troubleshooting
# frps.ini can set per-connection bandwidth limit
# bandwidth_limit_type = server
# bandwidth_limit = 10MB

WireGuard Virtual LAN

Working Principle

WireGuard is a next-generation VPN protocol, faster, simpler, and more secure than OpenVPN or IPSec. It is not a traditional "internal network penetration" tool but rather connects multiple machines into a virtual LAN:

[Machine A] <-- WireGuard Tunnel --> [Machine B]
  10.0.0.1                     10.0.0.2

[Machine A] <-- WireGuard Tunnel --> [Machine C]
  10.0.0.1                     10.0.0.3

WireGuard features encrypted tunnels, P2P direct connection (no relay), and extremely high performance. Drawbacks: requires knowing peer public IPs, adding new devices requires reconfiguring all nodes.

Server Deployment (as Gateway)

# 1. Install WireGuard (Ubuntu/Debian)
apt update
apt install wireguard -y

# CentOS/RHEL 8+
dnf install epel-release -y
dnf install wireguard-tools -y

# 2. Generate key pairs (each machine generates its own)
cd /etc/wireguard
umask 077

# Generate server key pair
wg genkey | tee server_private.key | wg pubkey > server_public.key

# Generate client key pairs (multiple clients need multiple pairs)
wg genkey | tee client1_private.key | wg pubkey > client1_public.key
wg genkey | tee client2_private.key | wg pubkey > client2_public.key

# 3. Create server configuration file
cat > wg0.conf << 'EOF'
[Interface]
# Server private key
PrivateKey = <code>server_private_key</code>

# WireGuard interface IP (virtual LAN address)
Address = 10.0.0.1/24

# Server listen port
ListenPort = 51820

# Firewall rules (NAT forwarding)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT

# Remove firewall rules (on shutdown)
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -o wg0 -j ACCEPT

# Client configuration
[Peer]
# Client 1 public key
PublicKey = <code>client1_public_key</code>
# Client 1 allowed IPs (virtual LAN addresses this client can access)
AllowedIPs = 10.0.0.2/32

[Peer]
# Client 2 public key
PublicKey = <code>client2_public_key</code>
AllowedIPs = 10.0.0.3/32
EOF

# 4. Set permissions
chmod 600 wg0.conf

# 5. Enable IP forwarding
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# 6. Start WireGuard
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

# 7. Verify
wg show
ip addr show wg0

Client Deployment (Linux)

# 1. Install WireGuard (same as server)
apt install wireguard -y

# 2. Generate key pair
cd /etc/wireguard
umask 077
wg genkey | tee client_private.key | wg pubkey > client_public.key

# 3. Create client configuration
cat > wg0.conf << 'EOF'
[Interface]
# Local private key
PrivateKey = <code>client_private_key</code>

# Local virtual LAN IP
Address = 10.0.0.2/24

# DNS servers (optional)
DNS = 8.8.8.8, 8.8.4.4

[Peer]
# Server public key
PublicKey = <code>server_public_key</code>

# Server public address and port
Endpoint = your-server-ip:51820

# Keepalive (NAT traversal)
PersistentKeepalive = 25

# Allowed IP range
# 0.0.0.0/0 means all traffic goes through WireGuard (full VPN)
# Only virtual LAN: 10.0.0.0/24
AllowedIPs = 10.0.0.0/24
EOF

chmod 600 wg0.conf

# 4. Start
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

# 5. Test connection
# On client ping server
ping 10.0.0.1

# On server ping client
ping 10.0.0.2

Client Deployment (Windows/macOS)

Windows: Download WireGuard client from https://www.wireguard.com/install/
macOS: brew install wireguard-tools or download official client from App Store

Graphical client configuration:
1. Import or create new tunnel
2. Enter PrivateKey (client private key)
3. Enter Address (client virtual IP)
4. Add Peer: enter server public key, Endpoint (serverIP:51820)
5. AllowedIPs: enter 10.0.0.0/24 (only access virtual LAN)
6. Save and connect

WireGuard as Full VPN (All Traffic Through Tunnel)

# Client config, set AllowedIPs to 0.0.0.0/0
cat > wg0.conf << 'EOF'
[Interface]
PrivateKey = <code>client_private_key</code>
Address = 10.0.0.2/24
DNS = 8.8.8.8

[Peer]
PublicKey = <code>server_public_key</code>
Endpoint = your-server-ip:51820
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0
EOF

# Note: With 0.0.0.0/0, all traffic routes through WireGuard tunnel
# Server must have proper NAT and routing, otherwise no internet access

WireGuard Common Troubleshooting

# 1. View WireGuard status
wg show
wg show wg0

# 2. View interface
ip addr show wg0

# 3. View routing table
ip route show

# 4. Connection failure troubleshooting
# 1. Check if server firewall allows 51820/UDP
ufw allow 51820/udp

# 2. Check if client and server keys match
# On server run:
wg show
# Verify output peer public key matches client config

# 3. Check AllowedIPs configuration
# Client AllowedIPs must include target IPs
# Server AllowedIPs must include client virtual IP

# 5. NAT traversal issues
# WireGuard cannot traverse symmetric NAT by default
# Solution: set PersistentKeepalive = 25 (send keepalive every 25 seconds)
# Or port forward on router

# 6. Server bandwidth issues
# WireGuard traffic passes through server, server bandwidth is bottleneck
# Test with iperf3
# Server: iperf3 -s
# Client: iperf3 -c 10.0.0.1

Tailscale Virtual LAN

Working Principle

Tailscale is a commercial service built on WireGuard. Its core idea is to turn WireGuard's key management, NAT traversal, and device management into a managed service. Tailscale does not require a public relay server (basic tier), supports DERP relays (free), and supports NAT traversal (P2P direct).

Tailscale advantages:
1. No manual key management; Tailscale service handles automatically
2. Supports NAT traversal; most cases need no relay
3. Supports DERP relay service (free)
4. Supports Exit Node (traffic egress)
5. Supports ACL access control lists
6. Supports all platforms (Windows, macOS, Linux, iOS, Android)

Installation and Deployment

# 1. Install Tailscale (Linux)
curl -fsSL https://tailscale.com/install.sh | sh

# Or manual install (CentOS/RHEL)
# Check latest version: https://pkgs.tailscale.com/stable/
curl -fsSL https://pkgs.tailscale.com/stable/tailscale-latest.x86_64.rpm -o tailscale.rpm
rpm -i tailscale.rpm

# 2. Start Tailscale
tailscaled &
# Or
systemctl start tailscaled

# 3. Connect to Tailscale network
tailscale up --login-server=https://login.example.com

# If using official Tailscale service (simplest)
tailscale up

# 4. Follow browser prompt to complete authentication

# 5. View status
tailscale status

# 6. View assigned IP
tailscale ip

# 7. Enable on boot
systemctl enable tailscaled

Tailscale as Exit Node

# Configure server as Exit Node
# On server:
tailscale up --advertise-exit-node

# Approve this node as Exit Node in Tailscale admin console

# Client uses Exit Node
tailscale up --exit-node=<code>exit-node-ip</code>
# Or
tailscale up --exit-node=allow-networking

# All traffic routes through Exit Node

Tailscale ACL Access Control

# Tailscale uses JSON format ACL rules
# Edit in admin console https://login.tailscale.com/admin/acls

# Example ACL:
{
  "acls": [
    # Allow all users to access all devices
    {"action": "accept", "src": ["*"], "dst": ["*:*"]},

    # Restrictive ACL
    {"action": "accept", "src": ["group:developers"], "dst": ["tag:production:22"]},
    {"action": "accept", "src": ["tag:ci"], "dst": ["tag:production:0-65535"]},
  ],
  "tagOwners": {
    "tag:production": ["group:admins"],
    "tag:ci": ["group:admins"]
  }
}

Headscale Private Deployment (Self-hosted Tailscale Control Plane)

If you prefer not to use Tailscale's official service, you can deploy Headscale as a private control plane:

# Headscale deployment (Docker Compose example)
# docker-compose.yml
version: '3'
services:
  headscale:
    image: ghcr.io/juanfont/headscale:latest
    container_name: headscale
    volumes:
      - /etc/headscale:/etc/headscale
      - /var/lib/headscale:/var/lib/headscale
    ports:
      - "8080:8080"
      - "3478:3478/udp"
    command: serve
    restart: unless-stopped

# Create Headscale config
mkdir -p /etc/headscale /var/lib/headscale
cat > /etc/headscale/config.yaml << 'EOF'
server_url: http://your-headscale-ip:8080
listen_addr: 0.0.0.0:8080
private_key_path: /var/lib/headscale/private.key
noise:
  private_key_path: /var/lib/headscale/noise_private.key
prefix: 100.64.0.0/10
derp:
  server:
    enabled: false
  urls:
    - https://controlplane.tailscale.com/derpmap/default
EOF

# Initialize Headscale
docker exec -it headscale headscale nodes register --key <code>node-key</code>

# Client uses self-hosted Headscale
tailscale up --login-server=http://your-headscale-ip:8080

Tailscale Common Troubleshooting

# 1. View Tailscale status
tailscale status

# 2. View Tailscale logs
journalctl -u tailscaled -f

# 3. Test connectivity
tailscale ping <code>peer-name-or-ip</code>

# 4. View assigned IPs
tailscale ip -4
tailscale ip -6

# 5. Disconnection troubleshooting
# 1. Check if Tailscale service runs
systemctl status tailscaled

# 2. Check authentication status
tailscale status

# 3. If shows NeedsLogin, re-authenticate
tailscale up

# 4. Check NAT traversal status
tailscale netcheck

# 5. Force DERP relay
tailscale up --derp=http://custom-derp-server

# 6. Multi-device management
tailscale logout  # Logout current account
tailscale up      # Re-login

Comparison of Three Solutions

Feature Comparison

Architecture : frp (C/S, requires relay server), WireGuard (P2P, no relay server needed), Tailscale (Hybrid, relay optional)

Bandwidth : frp (Limited by relay server), WireGuard (Server bandwidth is bottleneck), Tailscale (No bottleneck during P2P)

Latency : frp (High due to relay), WireGuard (Low, P2P direct), Tailscale (Low, P2P direct)

NAT Traversal : frp (Supported), WireGuard (No symmetric NAT support), Tailscale (Supported)

Configuration Difficulty : frp (Medium), WireGuard (Hard), Tailscale (Easy)

Cost : frp (Requires public server), WireGuard (Requires public server), Tailscale (Free tier sufficient)

Multi-platform : frp (Supported), WireGuard (Official support for major platforms), Tailscale (Official support for all platforms)

ACL : frp (Not supported), WireGuard (Not supported), Tailscale (Supported)

Key Management : frp (Manual), WireGuard (Manual), Tailscale (Automatic)

Third-party Dependency : frp (None), WireGuard (None), Tailscale (Tailscale service, can self-host)

Recommended Scenarios

frp suitable scenarios:
- Temporarily expose local service to internet (webhook debugging)
- Have controllable public server
- Only need TCP/UDP port forwarding, not full VPN
- Low traffic, latency not critical

WireGuard suitable scenarios:
- Need stable long-lived connections
- Multiple servers forming private network
- Servers have independent public IPs
- Simple network environment (no symmetric NAT)
- High performance requirements

Tailscale suitable scenarios:
- Don't want to manage servers
- Multi-platform devices need interconnection
- Need ACL access control
- Complex network environments (NAT, symmetric NAT)
- Want quick deployment without configuration hassle

Real-world Bandwidth and Latency Benchmarks

Test environment: Client behind NAT, server in Alibaba Cloud South China (Guangzhou) region.

frp:
- Latency: 80-120ms (via relay)
- Bandwidth: Limited by relay server, single connection ~30-50MB/s
- Suitable for: Web services, SSH, RDP

WireGuard (P2P direct):
- Latency: 40-60ms (direct)
- Bandwidth: Near server bandwidth, single connection ~100MB/s+
- Suitable for: File transfer, database connections, SSH

Tailscale (P2P direct):
- Latency: 40-60ms (same as WireGuard)
- Bandwidth: Same as above
- Relay mode: Latency 80-120ms
- Suitable for: All scenarios

Practical Deployment Recommendations

Small Team / Personal Use

Recommended: Tailscale free tier

Reasons:
1. Install and configure in 5 minutes
2. Supports all platforms
3. Free tier sufficient for personal/small team
4. No need to maintain own server
5. Access control adequate

Deployment steps:
1. Register Tailscale account (GitHub/Google login)
2. Install Tailscale client on each device
3. Follow prompts to authenticate
4. Start using

Medium-sized Team

Recommended: WireGuard + Tailscale hybrid

Reasons:
1. Core business servers use WireGuard (high performance, controllable)
2. Employee devices use Tailscale (easy management)
3. Control access via Tailscale ACL
4. Servers interconnect via WireGuard

Deployment steps:
1. Purchase or rent public IP server
2. Deploy WireGuard on server
3. Team members install Tailscale
4. Configure ACL rules

Enterprise Use

Recommended: Headscale self-hosted + WireGuard

Reasons:
1. Data fully self-controlled
2. Headscale open-source and free
3. WireGuard optimal performance
4. Integrates with existing infrastructure

Deployment steps:
1. Deploy Headscale control plane
2. Install WireGuard on servers, join network
3. Manage all nodes via Headscale
4. Configure enterprise-grade ACL policies

Frequently Asked Questions

frp Related

Q: frp connects successfully but service inaccessible? A: Check: 1) Client local_port correct; 2) Server remote_port matches client; 3) Service actually listening on local_port; 4) Firewall allows traffic.

Q: How to implement HTTPS with frp? A: Two ways: 1) Configure SSL cert on frps for TLS termination; 2) Use frpc plugin https2http to convert HTTPS to HTTP for local service.

Q: How to limit bandwidth in frp? A: Configure bandwidth_limit_type and bandwidth_limit in frps.ini.

WireGuard Related

Q: WireGuard connected but ping fails? A: Check: 1) Server IP forwarding enabled (net.ipv4.ip_forward); 2) Server firewall allows wg0 interface; 3) Client AllowedIPs includes target IP.

Q: How to add new WireGuard client? A: 1) Generate key pair on client; 2) Send client public key to admin; 3) Admin adds [Peer] section to server wg0.conf with public key and AllowedIPs; 4) Restart wg-quick@wg0.

Q: Does WireGuard support Windows/macOS? A: Yes. Windows download installer from official site, macOS via brew or official client.

Tailscale Related

Q: Does Tailscale free tier have traffic limits? A: Free tier has no traffic limits, but DERP relay bandwidth limited to 1Mbps per connection. P2P direct has no limits.

Q: How to disable DERP relay and use only P2P? A: Run tailscale netcheck to check NAT type. If symmetric NAT, P2P fails, must use DERP.

Q: Can Tailscale self-host relay servers? A: Yes. Headscale includes DERP functionality, or deploy derper separately.

Q: Is Tailscale secure? A: Tailscale is based on WireGuard, which is proven secure. Tailscale official does not decrypt your traffic.

Summary

Three internal network penetration solutions each have trade-offs:

frp is the most traditional solution, requiring self-maintained relay server, slightly complex configuration, but fully controllable. Suitable for exposing local services to the internet.

WireGuard is a next-gen VPN protocol with high performance, security, and minimal codebase. Suitable for multiple servers forming a private network. Drawback: requires fixed public IP, weak NAT traversal.

Tailscale is the most hassle-free solution, operational in 5 minutes. Free tier sufficient for individuals and small teams. Suitable for those seeking ease of use without configuration overhead.

Selection guide:

Personal use, webhook debugging, temporary service exposure: Tailscale

Multi-server networking, have public IP: WireGuard

Already have relay server, only need port mapping: frp

Enterprise requirements: Headscale self-hosted + WireGuard

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

network troubleshootingreverse proxyVPNfrpNAT traversalWireGuardHeadscaleTailscale
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.