edgesecurityaccess-wireguard-vpn

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

EdgeSecurityAccess WireGuard VPN Skill

EdgeSecurityAccess WireGuard VPN Skill

Skill by ara.so — Security Skills collection.
EdgeSecurityAccess (ESA) is a WireGuard-based rapid networking software suite for setting up virtual private networks. It consists of three components: ESA mainframe (Go server), ESA utility software package (C/C++ tools), and ESA desktop client (C# Windows GUI). The server exposes an HTTP API for retrieving WireGuard configurations based on username/password authentication.
该Skill由ara.so开发 — 安全技能集合。
EdgeSecurityAccess(ESA)是一套基于WireGuard的快速组网软件套件,用于搭建虚拟专用网络(VPN)。它包含三个组件:ESA主框架(Go语言服务器)、ESA实用软件包(C/C++工具)和ESA桌面客户端(C# Windows图形界面)。服务器提供HTTP API,可基于用户名/密码认证获取WireGuard配置。

Installation

安装

Prerequisites

前提条件

Linux Server:
bash
undefined
Linux服务器:
bash
undefined

Install WireGuard

安装WireGuard

apt install wireguard # Debian/Ubuntu
apt install wireguard # Debian/Ubuntu

or

yum install wireguard-tools # RHEL/CentOS
yum install wireguard-tools # RHEL/CentOS

Install Go 1.26+ for building ESA mainframe

安装Go 1.26+以构建ESA主框架

wget https://go.dev/dl/go1.26.linux-amd64.tar.gz tar -C /usr/local -xzf go1.26.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin

**Windows Client:**
```powershell
wget https://go.dev/dl/go1.26.linux-amd64.tar.gz tar -C /usr/local -xzf go1.26.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin

**Windows客户端:**
```powershell

Install WireGuard

安装WireGuard

winget install WireGuard.WireGuard
winget install WireGuard.WireGuard

Install .NET Runtime for ESA Desktop

安装.NET Runtime以运行ESA桌面客户端

Download from Microsoft official website

从微软官方网站下载

undefined
undefined

Build ESA Mainframe

构建ESA主框架

bash
git clone https://github.com/KochiyaSanaeNya/EdgeSecurityAccess.git
cd EdgeSecurityAccess
bash
git clone https://github.com/KochiyaSanaeNya/EdgeSecurityAccess.git
cd EdgeSecurityAccess

Build the main server

构建主服务器

go build -o esa-server ./main.go
go build -o esa-server ./main.go

Build utility tools (C/C++)

构建实用工具(C/C++)

cd tools gcc -o ESAusr ESAusr.c gcc -o ESAProc ESAProc.c gcc -o ESAInit ESAInit.c cd ..
undefined
cd tools gcc -o ESAusr ESAusr.c gcc -o ESAProc ESAProc.c gcc -o ESAInit ESAInit.c cd ..
undefined

Build ESA Desktop (Windows)

构建ESA桌面客户端(Windows)

bash
undefined
bash
undefined

Open solution in Visual Studio and build

在Visual Studio中打开解决方案并构建

Or use dotnet CLI

或使用dotnet CLI

cd ESADesktop dotnet build -c Release
undefined
cd ESADesktop dotnet build -c Release
undefined

Configuration

配置

Generate WireGuard Keys

生成WireGuard密钥

bash
undefined
bash
undefined

Generate server keys

生成服务器密钥

wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee server_private.key | wg pubkey > server_public.key

Generate client keys (done automatically by ESAProc)

生成客户端密钥(由ESAProc自动完成)

wg genkey | tee client_private.key | wg pubkey > client_public.key
undefined
wg genkey | tee client_private.key | wg pubkey > client_public.key
undefined

Create esa.conf

创建esa.conf配置文件

Create
/etc/esa/esa.conf
:
$servip = 172.16.16.1/24
$subnet = 172.16.16.0/24
$endpoint = vpn.example.com:50000
$keeptime = 25
$wgport = 50000
$httport = 50001
$servpriv = $(cat server_private.key)
$servpub = $(cat server_public.key)
创建
/etc/esa/esa.conf
$servip = 172.16.16.1/24
$subnet = 172.16.16.0/24
$endpoint = vpn.example.com:50000
$keeptime = 25
$wgport = 50000
$httport = 50001
$servpriv = $(cat server_private.key)
$servpub = $(cat server_public.key)

Configuration File Structure

配置文件结构

go
// Configuration keys reference
type Config struct {
    ServIP    string  // $servip - Server IP in virtual network
    Subnet    string  // $subnet - Virtual network subnet
    Endpoint  string  // $endpoint - External WireGuard access point
    KeepTime  int     // $keeptime - NAT traversal keepalive interval
    WGPort    int     // $wgport - WireGuard UDP port
    HTTPPort  int     // $httport - HTTP API port
    ServPriv  string  // $servpriv - Server WireGuard private key
    ServPub   string  // $servpub - Server WireGuard public key
}
go
// 配置键参考
type Config struct {
    ServIP    string  // $servip - 虚拟网络中的服务器IP
    Subnet    string  // $subnet - 虚拟网络子网
    Endpoint  string  // $endpoint - WireGuard外部访问端点
    KeepTime  int     // $keeptime - NAT穿越保活间隔
    WGPort    int     // $wgport - WireGuard UDP端口
    HTTPPort  int     // $httport - HTTP API端口
    ServPriv  string  // $servpriv - 服务器WireGuard私钥
    ServPub   string  // $servpub - 服务器WireGuard公钥
}

User Management

用户管理

Add users with ESAusr:
bash
undefined
使用ESAusr添加用户:
bash
undefined

Copy ESAusr to config directory

将ESAusr复制到配置目录

cp tools/ESAusr /etc/esa/ cd /etc/esa
cp tools/ESAusr /etc/esa/ cd /etc/esa

Run and follow prompts

运行并按照提示操作

./ESAusr
./ESAusr

Enter username: alice

输入用户名: alice

Enter password: secure_password

输入密码: secure_password

User added to users.txt

用户将被添加到users.txt


**users.txt format:**
alice:secure_password:172.16.16.2/32:client_public_key_here bob:another_password:172.16.16.3/32:another_public_key_here
undefined

**users.txt格式:**
alice:secure_password:172.16.16.2/32:client_public_key_here bob:another_password:172.16.16.3/32:another_public_key_here
undefined

Generate User WireGuard Configs

生成用户WireGuard配置

bash
undefined
bash
undefined

Copy ESAProc to config directory

将ESAProc复制到配置目录

cp tools/ESAProc /etc/esa/ cd /etc/esa
cp tools/ESAProc /etc/esa/ cd /etc/esa

Generate usrwg.conf from users.txt

从users.txt生成usrwg.conf

./ESAProc
./ESAProc

Output: usrwg.conf created with all user WireGuard configurations

输出: usrwg.conf已创建,包含所有用户的WireGuard配置

undefined
undefined

Initialize Local WireGuard

初始化本地WireGuard

bash
undefined
bash
undefined

Copy ESAInit to config directory

将ESAInit复制到配置目录

cp tools/ESAInit /etc/esa/ cd /etc/esa
cp tools/ESAInit /etc/esa/ cd /etc/esa

Configure local WireGuard interface

配置本地WireGuard接口

./ESAInit
./ESAInit

Output: /etc/wireguard/wg0.conf configured

输出: /etc/wireguard/wg0.conf已配置完成

undefined
undefined

Running the Server

运行服务器

Start ESA Mainframe

启动ESA主框架

bash
undefined
bash
undefined

Start the server

启动服务器

./esa-server -config /etc/esa/esa.conf
./esa-server -config /etc/esa/esa.conf

Or run as systemd service

或作为systemd服务运行

cat > /etc/systemd/system/esa.service <<EOF [Unit] Description=EdgeSecurityAccess VPN Server After=network.target
[Service] Type=simple ExecStart=/usr/local/bin/esa-server -config /etc/esa/esa.conf Restart=on-failure
[Install] WantedBy=multi-user.target EOF
systemctl daemon-reload systemctl enable esa systemctl start esa
undefined
cat > /etc/systemd/system/esa.service <<EOF [Unit] Description=EdgeSecurityAccess VPN Server After=network.target
[Service] Type=simple ExecStart=/usr/local/bin/esa-server -config /etc/esa/esa.conf Restart=on-failure
[Install] WantedBy=multi-user.target EOF
systemctl daemon-reload systemctl enable esa systemctl start esa
undefined

Start WireGuard Interface

启动WireGuard接口

bash
undefined
bash
undefined

Bring up WireGuard interface

启动WireGuard接口

wg-quick up wg0
wg-quick up wg0

Check status

检查状态

wg show
wg show

Enable at boot

设置开机自启

systemctl enable wg-quick@wg0
undefined
systemctl enable wg-quick@wg0
undefined

Enable Kernel Forwarding

启用内核转发

bash
undefined
bash
undefined

Enable IP forwarding

启用IP转发

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.ip_forward=1

Persist across reboots

配置重启后保持生效

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p

Configure NAT (replace eth0 with your interface)

配置NAT(将eth0替换为你的网络接口)

iptables -t nat -A POSTROUTING -s 172.16.16.0/24 -o eth0 -j MASQUERADE iptables -A FORWARD -i wg0 -j ACCEPT iptables -A FORWARD -o wg0 -j ACCEPT
undefined
iptables -t nat -A POSTROUTING -s 172.16.16.0/24 -o eth0 -j MASQUERADE iptables -A FORWARD -i wg0 -j ACCEPT iptables -A FORWARD -o wg0 -j ACCEPT
undefined

HTTP API Usage

HTTP API使用

Retrieve User Configuration

获取用户配置

cURL Example:
bash
undefined
cURL示例:
bash
undefined

Get WireGuard config for user

获取用户的WireGuard配置

curl -X POST
--data "username=alice&password=secure_password"
http://127.0.0.1:50001
curl -X POST
--data "username=alice&password=secure_password"
http://127.0.0.1:50001

Response (WireGuard config):

响应(WireGuard配置):

[Interface]

[Interface]

PrivateKey = client_private_key

PrivateKey = client_private_key

Address = 172.16.16.2/32

Address = 172.16.16.2/32

[Peer]

[Peer]

PublicKey = server_public_key

PublicKey = server_public_key

AllowedIPs = 172.16.16.0/24

AllowedIPs = 172.16.16.0/24

Endpoint = vpn.example.com:50000

Endpoint = vpn.example.com:50000

PersistentKeepalive = 25

PersistentKeepalive = 25


**Go Client Example:**

```go
package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "strings"
)

func getWireGuardConfig(username, password, apiURL string) (string, error) {
    data := url.Values{}
    data.Set("username", username)
    data.Set("password", password)

    resp, err := http.Post(
        apiURL,
        "application/x-www-form-urlencoded",
        strings.NewReader(data.Encode()),
    )
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(body), nil
}

func main() {
    config, err := getWireGuardConfig(
        "alice",
        "secure_password",
        "http://127.0.0.1:50001",
    )
    if err != nil {
        panic(err)
    }
    fmt.Println(config)
}
Python Client Example:
python
import requests

def get_wireguard_config(username, password, api_url):
    response = requests.post(
        api_url,
        data={
            'username': username,
            'password': password
        }
    )
    return response.text

config = get_wireguard_config(
    'alice',
    'secure_password',
    'http://127.0.0.1:50001'
)
print(config)

**Go客户端示例:**

```go
package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "strings"
)

func getWireGuardConfig(username, password, apiURL string) (string, error) {
    data := url.Values{}
    data.Set("username", username)
    data.Set("password", password)

    resp, err := http.Post(
        apiURL,
        "application/x-www-form-urlencoded",
        strings.NewReader(data.Encode()),
    )
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(body), nil
}

func main() {
    config, err := getWireGuardConfig(
        "alice",
        "secure_password",
        "http://127.0.0.1:50001",
    )
    if err != nil {
        panic(err)
    }
    fmt.Println(config)
}
Python客户端示例:
python
import requests

def get_wireguard_config(username, password, api_url):
    response = requests.post(
        api_url,
        data={
            'username': username,
            'password': password
        }
    )
    return response.text

config = get_wireguard_config(
    'alice',
    'secure_password',
    'http://127.0.0.1:50001'
)
print(config)

Save to file and connect

保存到文件并连接

with open('wg_client.conf', 'w') as f: f.write(config)
import subprocess subprocess.run(['wg-quick', 'up', 'wg_client.conf'])
undefined
with open('wg_client.conf', 'w') as f: f.write(config)
import subprocess subprocess.run(['wg-quick', 'up', 'wg_client.conf'])
undefined

Client Connection

客户端连接

Linux/macOS CLI

Linux/macOS命令行

bash
undefined
bash
undefined

Get config and save

获取配置并保存

curl -X POST
--data "username=alice&password=secure_password"
http://127.0.0.1:50001 > esa_user.conf
curl -X POST
--data "username=alice&password=secure_password"
http://127.0.0.1:50001 > esa_user.conf

Connect

连接

wg-quick up esa_user.conf
wg-quick up esa_user.conf

Test connection

测试连接

ping 172.16.16.1
ping 172.16.16.1

Disconnect

断开连接

wg-quick down esa_user.conf
undefined
wg-quick down esa_user.conf
undefined

Using ESA Desktop (Windows)

使用ESA桌面客户端(Windows)

1. Launch ESA Desktop application
2. Enter:
   - Username: alice
   - Password: secure_password
   - Server URL: http://vpn.example.com:50001
3. Click "Connect"
4. WireGuard tunnel establishes automatically
1. 启动ESA桌面应用程序
2. 输入以下信息:
   - 用户名: alice
   - 密码: secure_password
   - 服务器URL: http://vpn.example.com:50001
3. 点击“连接”
4. WireGuard隧道将自动建立

Reverse Proxy Setup (HTTPS)

反向代理设置(HTTPS)

Nginx Configuration

Nginx配置

nginx
server {
    listen 443 ssl http2;
    server_name vpn.example.com;

    ssl_certificate /etc/ssl/certs/vpn.example.com.crt;
    ssl_certificate_key /etc/ssl/private/vpn.example.com.key;

    location / {
        proxy_pass http://127.0.0.1:50001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
nginx
server {
    listen 443 ssl http2;
    server_name vpn.example.com;

    ssl_certificate /etc/ssl/certs/vpn.example.com.crt;
    ssl_certificate_key /etc/ssl/private/vpn.example.com.key;

    location / {
        proxy_pass http://127.0.0.1:50001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Caddy Configuration

Caddy配置

vpn.example.com {
    reverse_proxy 127.0.0.1:50001
}
Update client requests to use HTTPS:
bash
curl -X POST \
  --data "username=alice&password=secure_password" \
  https://vpn.example.com
vpn.example.com {
    reverse_proxy 127.0.0.1:50001
}
更新客户端请求以使用HTTPS:
bash
curl -X POST \
  --data "username=alice&password=secure_password" \
  https://vpn.example.com

Common Patterns

常见应用场景

Automated User Provisioning

自动化用户配置

go
package main

import (
    "crypto/rand"
    "encoding/base64"
    "fmt"
    "os"
    "strings"

    "golang.org/x/crypto/curve25519"
)

// Generate WireGuard key pair
func generateKeyPair() (privKey, pubKey string, err error) {
    var private [32]byte
    if _, err := rand.Read(private[:]); err != nil {
        return "", "", err
    }

    public, err := curve25519.X25519(private[:], curve25519.Basepoint)
    if err != nil {
        return "", "", err
    }

    privKey = base64.StdEncoding.EncodeToString(private[:])
    pubKey = base64.StdEncoding.EncodeToString(public)
    return privKey, pubKey, nil
}

// Add user to users.txt
func addUser(username, password, ip string) error {
    _, pubKey, err := generateKeyPair()
    if err != nil {
        return err
    }

    userLine := fmt.Sprintf("%s:%s:%s:%s\n", username, password, ip, pubKey)

    f, err := os.OpenFile("/etc/esa/users.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
    if err != nil {
        return err
    }
    defer f.Close()

    _, err = f.WriteString(userLine)
    return err
}

func main() {
    err := addUser("newuser", "newpass", "172.16.16.10/32")
    if err != nil {
        panic(err)
    }
    fmt.Println("User added successfully")
}
go
package main

import (
    "crypto/rand"
    "encoding/base64"
    "fmt"
    "os"
    "strings"

    "golang.org/x/crypto/curve25519"
)

// 生成WireGuard密钥对
func generateKeyPair() (privKey, pubKey string, err error) {
    var private [32]byte
    if _, err := rand.Read(private[:]); err != nil {
        return "", "", err
    }

    public, err := curve25519.X25519(private[:], curve25519.Basepoint)
    if err != nil {
        return "", "", err
    }

    privKey = base64.StdEncoding.EncodeToString(private[:])
    pubKey = base64.StdEncoding.EncodeToString(public)
    return privKey, pubKey, nil
}

// 将用户添加到users.txt
func addUser(username, password, ip string) error {
    _, pubKey, err := generateKeyPair()
    if err != nil {
        return err
    }

    userLine := fmt.Sprintf("%s:%s:%s:%s\n", username, password, ip, pubKey)

    f, err := os.OpenFile("/etc/esa/users.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
    if err != nil {
        return err
    }
    defer f.Close()

    _, err = f.WriteString(userLine)
    return err
}

func main() {
    err := addUser("newuser", "newpass", "172.16.16.10/32")
    if err != nil {
        panic(err)
    }
    fmt.Println("用户添加成功")
}

Health Check Endpoint

健康检查端点

go
package main

import (
    "fmt"
    "net/http"
)

func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "OK")
}

func main() {
    http.HandleFunc("/health", healthCheckHandler)
    http.ListenAndServe(":50002", nil)
}
go
package main

import (
    "fmt"
    "net/http"
)

func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "OK")
}

func main() {
    http.HandleFunc("/health", healthCheckHandler)
    http.ListenAndServe(":50002", nil)
}

User Config Backup Script

用户配置备份脚本

bash
#!/bin/bash
bash
#!/bin/bash

backup_esa_users.sh

backup_esa_users.sh

BACKUP_DIR="/var/backups/esa" CONFIG_DIR="/etc/esa" TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
BACKUP_DIR="/var/backups/esa" CONFIG_DIR="/etc/esa" TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"

Backup user files

备份用户文件

tar -czf "$BACKUP_DIR/esa_backup_$TIMESTAMP.tar.gz"
"$CONFIG_DIR/users.txt"
"$CONFIG_DIR/usrwg.conf"
"$CONFIG_DIR/esa.conf"
tar -czf "$BACKUP_DIR/esa_backup_$TIMESTAMP.tar.gz"
"$CONFIG_DIR/users.txt"
"$CONFIG_DIR/usrwg.conf"
"$CONFIG_DIR/esa.conf"

Keep only last 7 backups

仅保留最近7份备份

ls -t "$BACKUP_DIR"/esa_backup_*.tar.gz | tail -n +8 | xargs -r rm
echo "Backup completed: esa_backup_$TIMESTAMP.tar.gz"
undefined
ls -t "$BACKUP_DIR"/esa_backup_*.tar.gz | tail -n +8 | xargs -r rm
echo "备份完成: esa_backup_$TIMESTAMP.tar.gz"
undefined

Troubleshooting

故障排除

Server Won't Start

服务器无法启动

bash
undefined
bash
undefined

Check if port is already in use

检查端口是否已被占用

netstat -tuln | grep 50001 lsof -i :50001
netstat -tuln | grep 50001 lsof -i :50001

Check WireGuard port

检查WireGuard端口

netstat -tuln | grep 50000
netstat -tuln | grep 50000

Verify configuration syntax

验证配置语法

cat /etc/esa/esa.conf | grep -E '^$'
cat /etc/esa/esa.conf | grep -E '^$'

Check logs

查看日志

journalctl -u esa -f
undefined
journalctl -u esa -f
undefined

Authentication Fails

认证失败

bash
undefined
bash
undefined

Verify user exists

验证用户是否存在

grep "^username:" /etc/esa/users.txt
grep "^username:" /etc/esa/users.txt

Check users.txt format (should be username:password:ip:pubkey)

检查users.txt格式(应为username:password:ip:pubkey)

cat /etc/esa/users.txt
cat /etc/esa/users.txt

Regenerate usrwg.conf

重新生成usrwg.conf

cd /etc/esa ./ESAProc
undefined
cd /etc/esa ./ESAProc
undefined

WireGuard Connection Issues

WireGuard连接问题

bash
undefined
bash
undefined

Check WireGuard interface status

检查WireGuard接口状态

wg show wg0
wg show wg0

Verify server can reach UDP port

验证服务器是否能访问UDP端口

nc -u -v vpn.example.com 50000
nc -u -v vpn.example.com 50000

Check routing

检查路由

ip route show
ip route show

Test from client

从客户端测试连接

ping 172.16.16.1
ping 172.16.16.1

Check server firewall

检查服务器防火墙

iptables -L -n -v ufw status
iptables -L -n -v ufw status

Allow WireGuard port

允许WireGuard端口

ufw allow 50000/udp
undefined
ufw allow 50000/udp
undefined

Cannot Forward Traffic

无法转发流量

bash
undefined
bash
undefined

Verify IP forwarding is enabled

验证IP转发是否已启用

sysctl net.ipv4.ip_forward
sysctl net.ipv4.ip_forward

Should output: net.ipv4.ip_forward = 1

应输出: net.ipv4.ip_forward = 1

Check NAT rules

检查NAT规则

iptables -t nat -L -n -v
iptables -t nat -L -n -v

Re-add NAT rule

重新添加NAT规则

iptables -t nat -A POSTROUTING -s 172.16.16.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 172.16.16.0/24 -o eth0 -j MASQUERADE

Save iptables rules

保存iptables规则

iptables-save > /etc/iptables/rules.v4
undefined
iptables-save > /etc/iptables/rules.v4
undefined

HTTP API Returns Empty

HTTP API返回空内容

bash
undefined
bash
undefined

Test with verbose curl

使用详细模式测试curl

curl -v -X POST
--data "username=alice&password=secure_password"
http://127.0.0.1:50001
curl -v -X POST
--data "username=alice&password=secure_password"
http://127.0.0.1:50001

Check if users.txt is properly formatted

检查users.txt格式是否正确

cat /etc/esa/users.txt | sed 's/:/ : /g'
cat /etc/esa/users.txt | sed 's/:/ : /g'

Verify usrwg.conf was generated

验证usrwg.conf是否已生成

cat /etc/esa/usrwg.conf
cat /etc/esa/usrwg.conf

Restart ESA server

重启ESA服务器

systemctl restart esa
undefined
systemctl restart esa
undefined

Key Security Issues

密钥安全问题

Note: ESA stores user private keys on the server (architectural limitation). For production use:
bash
undefined
注意: ESA在服务器上存储用户私钥(架构限制)。生产环境使用时:
bash
undefined

Restrict file permissions

限制文件权限

chmod 600 /etc/esa/users.txt chmod 600 /etc/esa/usrwg.conf chown root:root /etc/esa/.txt /etc/esa/.conf
chmod 600 /etc/esa/users.txt chmod 600 /etc/esa/usrwg.conf chown root:root /etc/esa/.txt /etc/esa/.conf

Encrypt sensitive files (future improvement)

加密敏感文件(未来改进方向)

Current version does NOT encrypt username/password

当前版本不加密用户名/密码

Use HTTPS reverse proxy to protect credentials in transit

使用HTTPS反向代理保护传输中的凭据

undefined
undefined

Performance Tuning

性能调优

bash
undefined
bash
undefined

Increase WireGuard MTU if needed

如有需要,增大WireGuard MTU值

ip link set dev wg0 mtu 1420
ip link set dev wg0 mtu 1420

Optimize sysctl for VPN

优化sysctl参数以提升VPN性能

cat >> /etc/sysctl.conf <<EOF net.core.rmem_max = 134217728 net.core.wmem_max = 134217728 net.ipv4.tcp_rmem = 4096 87380 67108864 net.ipv4.tcp_wmem = 4096 65536 67108864 EOF sysctl -p
undefined
cat >> /etc/sysctl.conf <<EOF net.core.rmem_max = 134217728 net.core.wmem_max = 134217728 net.ipv4.tcp_rmem = 4096 87380 67108864 net.ipv4.tcp_wmem = 4096 65536 67108864 EOF sysctl -p
undefined

Security Considerations

安全注意事项

  1. Use HTTPS reverse proxy (Nginx/Caddy) to protect credentials
  2. Passwords are stored in plaintext in users.txt - restrict access
  3. User private keys stored on server - architectural limitation
  4. No rate limiting - implement fail2ban or reverse proxy rate limits
  5. Enable firewall rules to restrict HTTP API access
  6. Regular backups of configuration files
  7. Monitor logs for authentication attempts
bash
undefined
  1. 使用HTTPS反向代理(Nginx/Caddy)保护凭据
  2. 密码以明文存储在users.txt中 - 限制文件访问权限
  3. 用户私钥存储在服务器上 - 架构限制
  4. 无速率限制 - 实现fail2ban或反向代理速率限制
  5. 启用防火墙规则限制HTTP API访问
  6. 定期备份配置文件
  7. 监控日志中的认证尝试
bash
undefined

Example fail2ban filter for ESA

ESA的fail2ban过滤规则示例

/etc/fail2ban/filter.d/esa.conf

/etc/fail2ban/filter.d/esa.conf

[Definition] failregex = ^.Authentication failed for user <HOST>.$ ignoreregex =
[Definition] failregex = ^.Authentication failed for user <HOST>.$ ignoreregex =

/etc/fail2ban/jail.local

/etc/fail2ban/jail.local

[esa] enabled = true port = 50001 filter = esa logpath = /var/log/esa/access.log maxretry = 5 bantime = 3600
undefined
[esa] enabled = true port = 50001 filter = esa logpath = /var/log/esa/access.log maxretry = 5 bantime = 3600
undefined