Update On Mon Jul 14 14:45:44 CEST 2025

This commit is contained in:
github-action[bot]
2025-07-14 14:45:44 +02:00
parent e8789f18dd
commit 8bd2db99cf
87 changed files with 9229 additions and 904 deletions

66
nodepass/.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: Docker
on:
push:
tags: [ 'v*.*.*' ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
VERSION: ${{ github.ref_name }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4.2.2
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@v3.8.2
with:
cosign-release: 'v2.2.4'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.10.0
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3.4.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5.7.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6.16.0
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
build-args: VERSION=${{ env.VERSION }}
provenance: false
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
run: echo ${{ steps.meta.outputs.tags }} | tr ',' '\n' | xargs -I {} cosign sign --yes {}@${DIGEST}

24
nodepass/.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Release
on:
push:
tags: [ 'v*.*.*' ]
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5.4.0
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6.3.0
with:
distribution: goreleaser
version: 'latest'
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

36
nodepass/.goreleaser.yml Normal file
View File

@@ -0,0 +1,36 @@
version: 2
builds:
- env:
- CGO_ENABLED=0
main: ./cmd/nodepass
goos:
- darwin
- freebsd
- linux
- windows
goarch:
- 386
- arm
- amd64
- arm64
- mips
- mipsle
- mips64
- mips64le
goarm:
- 6
- 7
gomips:
- hardfloat
- softfloat
flags:
- -trimpath
ldflags:
- -s -w -X main.version={{ .Tag }}
archives:
- formats: [tar.gz]
release:
prerelease: true
mode: replace

View File

@@ -0,0 +1,40 @@
# Code of Conduct
## Our Pledge
We are committed to providing a friendly, safe and welcoming environment for all, regardless of age, disability, ethnicity, gender identity, level of experience, nationality, personal appearance, race, religion, or sexual orientation.
## Our Standards
**Positive behaviors include:**
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
**Unacceptable behaviors include:**
* Harassment, trolling, or discriminatory comments
* Personal attacks or insulting/derogatory language
* Publishing others' private information without permission
* Any conduct that could reasonably be considered inappropriate in a professional setting
## Enforcement
Project maintainers are responsible for clarifying standards and may take appropriate corrective action in response to unacceptable behavior, including:
* Warning the individual
* Temporary restriction from project spaces
* Permanent ban from the project community
## Scope
This Code of Conduct applies to all project spaces, including GitHub repositories, issue trackers, social media accounts, and any events where individuals represent the project.
## Reporting
If you experience or witness unacceptable behavior, please report it to **team@mail.nodepass.eu**. All reports will be handled confidentially.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.

319
nodepass/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,319 @@
# Contributing to NodePass
Thank you for your interest in contributing to NodePass! We welcome all kinds of contributions, from bug reports and feature requests to code improvements and documentation updates.
## Table of Contents
- [Organization](#organization)
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [Contributing Guidelines](#contributing-guidelines)
- [Code Style and Standards](#code-style-and-standards)
- [Testing](#testing)
- [Documentation](#documentation)
- [Submitting Changes](#submitting-changes)
- [Community and Support](#community-and-support)
## Code of Conduct
Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md). We are committed to providing a welcoming and inclusive environment for all contributors.
## Getting Started
### Prerequisites
- **Go** (as specified in `go.mod`)
- **Git** for version control
- **Docker** (optional, for container-based development and testing)
- Basic knowledge of TCP/UDP networking concepts
- Familiarity with TLS/SSL concepts for security features
### Understanding the Architecture
NodePass is built on a three-tier architecture:
- **Server Mode**: Accepts incoming tunnel connections with configurable security
- **Client Mode**: Establishes outbound connections to tunnel servers
- **Master Mode**: Provides RESTful API for dynamic instance management
Key components:
- `/cmd/nodepass/`: Main application entry point and core dispatch logic
- `/internal/`: Core implementation packages (server, client, master, common utilities)
- `/docs/`: Comprehensive documentation in English and Chinese
- External dependencies: NodePassProject ecosystem libraries for certificates, connections, logging, and pooling
## Development Setup
### 1. Fork and Clone
```bash
# Fork the repository on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/nodepass.git
cd nodepass
# Add the upstream repository
git remote add upstream https://github.com/yosebyte/nodepass.git
```
### 2. Install Dependencies
```bash
# Download and install dependencies
go mod download
# Verify dependencies
go mod verify
```
### 3. Build and Test
```bash
# Build the application
go build -o nodepass ./cmd/nodepass
# Test the build
./nodepass "server://localhost:10101/127.0.0.1:8080?log=debug&tls=0"
```
### 4. Development with Docker (Optional)
```bash
# Build development container
docker build --build-arg VERSION=dev -t nodepass:dev .
# Run in container
docker run --rm -p 10101:10101 nodepass:dev "server://:10101/127.0.0.1:8080?log=debug&tls=0"
```
## Contributing Guidelines
### Types of Contributions
- **🐛 Bug Reports**: Help us identify and fix issues
- **✨ Feature Requests**: Suggest new features or improvements
- **📝 Documentation**: Improve existing docs or add new ones
- **🔧 Code Contributions**: Bug fixes, feature implementations, refactoring
- **🌐 Translations**: Help translate documentation to other languages
- **🧪 Testing**: Add test cases and improve test coverage
### Reporting Issues
When reporting bugs or requesting features, please:
1. **Search existing issues** to avoid duplicates
2. **Use our issue templates** when available
3. **Provide detailed information**:
- NodePass version and build information
- Operating system and architecture
- Network configuration details
- Complete command-line arguments used
- Expected vs. actual behavior
- Relevant log output (use `log=debug` for detailed logs)
- Steps to reproduce the issue
### Feature Requests
For new features:
1. **Check the roadmap** and existing feature requests
2. **Describe the use case** clearly
3. **Explain the expected behavior**
4. **Consider backwards compatibility**
5. **Discuss implementation approach** if you plan to contribute code
## Code Style and Standards
### Go Code Style
We follow standard Go conventions with project-specific guidelines:
- Write idiomatic Go code following [Effective Go](https://golang.org/doc/effective_go.html)
- Use `gofmt` for consistent formatting and `go vet` to catch common errors
- Follow the single responsibility principle and prefer composition over inheritance
- Use descriptive variable and function names with proper Go naming conventions
- Include both Chinese and English comments for public APIs (maintaining project tradition)
- Implement proper error handling with context wrapping
- Use the project's logging framework consistently with appropriate log levels
- Protect shared state with mutexes and use channels for goroutine coordination
- Always handle goroutine cleanup with proper defer and recover patterns
### Configuration and CLI
- Use URL-based configuration syntax: `scheme://[password@]host:port/target?param=value`
- Support environment variables for sensitive configuration
- Provide sensible defaults for all optional parameters
- Validate configuration early in the application lifecycle
### Performance Considerations
- Minimize allocations in hot paths
- Use connection pooling for frequent connections
- Implement graceful degradation under load
- Profile memory and CPU usage for critical paths
- Use buffered I/O where appropriate
## Testing
### Testing Strategy
Currently, the project focuses on integration testing through real-world usage scenarios. We welcome contributions to improve test coverage:
#### Manual Testing
1. **Basic Functionality**: Test server, client, and master modes with debug logging
2. **TLS Modes**: Verify all three TLS security levels (0, 1, 2)
3. **Protocol Support**: Test TCP tunneling and UDP forwarding with various applications
#### Future Testing Goals
We encourage contributions in these areas:
- Unit Tests for individual functions and methods
- Integration Tests for component interactions
- Benchmark Tests for performance regression detection
- Fuzzing Tests for security and robustness
- End-to-End Tests for complete workflow validation
### Testing Guidelines
When adding tests:
- Use Go's standard testing package with `*_test.go` naming convention
- Write table-driven tests where applicable
- Include both positive and negative test cases
- Test error conditions and edge cases
- Use meaningful test names that describe the scenario
## Documentation
### Documentation Standards
- **Write in clear, simple English**
- **Include practical examples** for all features
- **Maintain both English and Chinese versions** when possible
- **Use consistent formatting** and structure
- **Test all code examples** to ensure they work
### Documentation Structure
- `README.md`: Project overview and quick start
- `docs/en/`: English documentation
- `docs/zh/`: Chinese documentation
- Inline code comments for complex logic
- API documentation for master mode endpoints
### Contributing to Documentation
1. **Update both language versions** when possible
2. **Test all examples** before submitting
3. **Use proper Markdown formatting**
4. **Include relevant screenshots** for UI components
5. **Cross-reference related documentation**
## Submitting Changes
### Pull Request Process
1. **Create a feature branch** from the latest `main`:
```bash
git checkout main
git pull upstream main
git checkout -b feature/your-feature-name
```
2. **Make your changes** following the guidelines above
3. **Test your changes** thoroughly by building the application and running real scenarios
4. **Commit your changes** with descriptive messages using [Conventional Commits](https://www.conventionalcommits.org/) format:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `refactor`: Code refactoring
- `perf`: Performance improvements
- `test`: Adding or updating tests
5. **Push to your fork** and create a pull request
### Commit Message Guidelines
Use [Conventional Commits](https://www.conventionalcommits.org/) format:
```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
**Examples:**
- `feat(server): add support for IPv6 addresses`
- `fix(client): resolve connection timeout issues in high-latency networks`
- `docs: update installation guide with Docker instructions`
- `refactor(common): simplify address parsing logic`
### Pull Request Guidelines
**Before submitting:**
- [ ] Code follows the project style guidelines
- [ ] All tests pass (or explain why they should be skipped)
- [ ] Documentation is updated if needed
- [ ] Commit messages follow the conventional format
- [ ] No merge conflicts with the main branch
**In your pull request:**
- [ ] Provide a clear description of changes
- [ ] Reference any related issues
- [ ] Include testing instructions
- [ ] Add screenshots for UI changes
- [ ] List any breaking changes
### Review Process
1. **Automated checks** run on all pull requests
2. **Code review** by project maintainers
3. **Testing** in various environments
4. **Documentation review** for user-facing changes
5. **Final approval** and merge
## Community and Support
### Communication Channels
- **GitHub Issues**: Bug reports and feature requests
- **Telegram Channel**: [@NodePassChannel](https://t.me/NodePassChannel) - Updates and announcements
- **Telegram Group**: [@NodePassGroup](https://t.me/NodePassGroup) - Community discussion
- **Discord**: [Join our server](https://discord.gg/2cnXcnDMGc) - Real-time chat
### Getting Help
If you need help:
1. **Check the documentation** in the `docs/` directory
2. **Search existing issues** for similar problems
3. **Ask in our community channels** for general questions
4. **Create a GitHub issue** for bugs or feature requests
### Recognition
We appreciate all contributions! Contributors will be:
- **Listed in our contributors** section
- **Mentioned in release notes** for significant contributions
- **Invited to become maintainers** for consistent, high-quality contributions
### Maintainer Responsibilities
Current maintainers handle:
- **Code review** and pull request management
- **Release planning** and version management
- **Community management** and support
- **Security** issue handling
- **Roadmap** planning and prioritization
---
Thank you for contributing to NodePass! Your contributions help make universal TCP/UDP tunneling more accessible and reliable for everyone.
For questions about contributing, please reach out through our community channels or create a GitHub issue.

11
nodepass/Dockerfile Normal file
View File

@@ -0,0 +1,11 @@
FROM golang:alpine AS builder
RUN apk update && apk add --no-cache ca-certificates
WORKDIR /root
ADD . .
ARG VERSION
WORKDIR /root/cmd/nodepass
RUN env CGO_ENABLED=0 go build -v -trimpath -ldflags "-s -w -X main.version=${VERSION}"
FROM scratch
COPY --from=builder /etc/ssl/certs /etc/ssl/certs
COPY --from=builder /root/cmd/nodepass/nodepass /nodepass
ENTRYPOINT ["/nodepass"]

28
nodepass/LICENSE Normal file
View File

@@ -0,0 +1,28 @@
BSD 3-Clause License
Copyright (c) 2025, 𝐘𝐨𝐬𝐞𝐛𝐲𝐭𝐞
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

120
nodepass/README.md Normal file
View File

@@ -0,0 +1,120 @@
<div align="center">
<img src="https://cdn.yobc.de/assets/np-gopher.png" alt="nodepass" width="300">
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)
[![GitHub release](https://img.shields.io/github/v/release/yosebyte/nodepass)](https://github.com/yosebyte/nodepass/releases)
[![GitHub downloads](https://img.shields.io/github/downloads/yosebyte/nodepass/total.svg)](https://github.com/yosebyte/nodepass/releases)
[![Go Report Card](https://goreportcard.com/badge/github.com/yosebyte/nodepass)](https://goreportcard.com/report/github.com/yosebyte/nodepass)
[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Go Reference](https://pkg.go.dev/badge/github.com/yosebyte/nodepass.svg)](https://pkg.go.dev/github.com/yosebyte/nodepass)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/yosebyte/nodepass)
![GitHub last commit](https://img.shields.io/github/last-commit/yosebyte/nodepass)
English | [简体中文](README_zh.md)
</div>
**NodePass** is an open-source, lightweight, enterprise-grade TCP/UDP network tunneling solution featuring an all-in-one architecture with separation of control and data channels, along with flexible and high-performance instance control. It supports zero-configuration deployment, intelligent connection pooling, tiered TLS encryption, and seamless protocol conversion. Designed for DevOps professionals and system administrators to effortlessly handle complex network scenarios including firewall traversal, NAT bypassing, and advanced tunnel management.
## 💎 Key Features
- **🔀 Multiple Operating Modes**
- Server mode accepting incoming tunnels with configurable security
- Client mode for establishing outbound connections to tunnel servers
- Master mode with RESTful API for dynamic instance management
- **🌍 Protocol Support**
- TCP tunneling with persistent connection handling
- UDP datagram forwarding with configurable buffer sizes
- Intelligent routing mechanisms for both protocols
- **🛡️ Security Options**
- TLS Mode 0: Unencrypted mode for maximum speed in trusted networks
- TLS Mode 1: Self-signed certificates for quick secure setup
- TLS Mode 2: Custom certificate validation for enterprise security
- **⚡ Performance Features**
- Smart connection pooling with real-time capacity adaptation
- Dynamic interval adjustment based on network conditions
- Minimal resource footprint even under heavy load
- **🧰 Simple Configuration**
- Zero configuration files required
- Simple command-line parameters
- Environment variables for fine-tuning performance
## 📋 Quick Start
### 📥 Installation
- **Pre-built Binaries**: Download from [releases page](https://github.com/yosebyte/nodepass/releases).
- **Container Image**: `docker pull ghcr.io/yosebyte/nodepass:latest`
### 🚀 Basic Usage
**Server Mode**
```bash
nodepass "server://:10101/127.0.0.1:8080?log=debug&tls=1"
```
**Client Mode**
```bash
nodepass "client://server:10101/127.0.0.1:8080?min=128"
```
**Master Mode (API)**
```bash
nodepass "master://:10101/api?log=debug&tls=1"
```
## 📚 Documentation
Explore the complete documentation to learn more about NodePass:
- [Installation Guide](/docs/en/installation.md)
- [Usage Instructions](/docs/en/usage.md)
- [Configuration Options](/docs/en/configuration.md)
- [API Reference](/docs/en/api.md)
- [Examples](/docs/en/examples.md)
- [How It Works](/docs/en/how-it-works.md)
- [Troubleshooting](/docs/en/troubleshooting.md)
## 🌐 Ecosystem
The [NodePassProject](https://github.com/NodePassProject) organization develops various frontend applications and auxiliary tools to enhance the NodePass experience:
- **[NodePassDash](https://github.com/NodePassProject/NodePassDash)**: A modern NodePass management interface that provides master management, instance management, traffic statistics, history records, and more.
- **[NodePanel](https://github.com/NodePassProject/NodePanel)**: A lightweight frontend panel that provides visual tunnel management, deployable on Vercel or Cloudflare Pages.
- **[npsh](https://github.com/NodePassProject/npsh)**: A collection of one-click scripts that provide simple deployment for API or Dashboard with flexible configuration and management.
## 💬 Discussion
- Follow our [Telegram Channel](https://t.me/NodePassChannel) for updates and community support.
- Join our [Discord](https://discord.gg/2cnXcnDMGc) and [Telegram Group](https://t.me/NodePassGroup) to share experiences and ideas.
## 📄 License
Project `NodePass` is licensed under the [BSD 3-Clause License](LICENSE).
## ⚖️ Disclaimer
This project is provided "as is" without any warranties. Users assume all risks and must comply with local laws for legal use only. Developers are not liable for any direct, indirect, incidental, or consequential damages. Secondary development requires commitment to legal use and self-responsibility for legal compliance. Developers reserve the right to modify software features and this disclaimer at any time. Final interpretation rights belong to developers.
## 🤝 Sponsors
<table>
<tr>
<td width="200" align="center">
<a href="https://whmcs.as211392.com"><img src="https://cdn.yobc.de/assets/dreamcloud.png"></a>
</td>
<td width="200" align="center">
<a href="https://zmto.com"><img src="https://cdn.yobc.de/assets/zmto.png"></a>
</td>
</tr>
</table>
## ⭐ Stargazers
[![Stargazers over time](https://starchart.cc/yosebyte/nodepass.svg?variant=adaptive)](https://starchart.cc/yosebyte/nodepass)

120
nodepass/README_zh.md Normal file
View File

@@ -0,0 +1,120 @@
<div align="center">
<img src="https://cdn.yobc.de/assets/np-gopher.png" alt="nodepass" width="300">
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)
[![GitHub release](https://img.shields.io/github/v/release/yosebyte/nodepass)](https://github.com/yosebyte/nodepass/releases)
[![GitHub downloads](https://img.shields.io/github/downloads/yosebyte/nodepass/total.svg)](https://github.com/yosebyte/nodepass/releases)
[![Go Report Card](https://goreportcard.com/badge/github.com/yosebyte/nodepass)](https://goreportcard.com/report/github.com/yosebyte/nodepass)
[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Go Reference](https://pkg.go.dev/badge/github.com/yosebyte/nodepass.svg)](https://pkg.go.dev/github.com/yosebyte/nodepass)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/yosebyte/nodepass)
![GitHub last commit](https://img.shields.io/github/last-commit/yosebyte/nodepass)
[English](README.md) | 简体中文
</div>
**NodePass** 是一款开源、轻量的企业级 TCP/UDP 网络隧道解决方案,采用多合一架构设计,通过控制通道与数据通道分离,实现灵活、高性能的实例管控。支持零配置文件部署,内置智能连接池、分级 TLS 加密和无缝协议转换。专为 DevOps 工程师和系统管理员打造助力轻松应对防火墙穿透、NAT 绕过和高级隧道管理等复杂网络场景。
## 💎 核心功能
- **🔀 多种操作模式**
- 服务端模式接受传入隧道连接并提供可配置的安全选项
- 客户端模式用于建立与隧道服务端的出站连接
- 主控模式提供RESTful API进行动态实例管理
- **🌍 协议支持**
- TCP隧道传输与持久连接管理
- UDP数据报转发与可配置的缓冲区大小
- 两种协议的智能路由机制
- **🛡️ 安全选项**
- TLS模式0在可信网络中获得最大速度的无加密模式
- TLS模式1使用自签名证书提供快速安全设置
- TLS模式2使用自定义证书验证实现企业级安全
- **⚡ 性能特性**
- 智能连接池,具备实时容量自适应功能
- 基于网络状况的动态间隔调整
- 高负载下保持最小资源占用
- **🧰 简单配置**
- 零配置文件设计
- 简洁的命令行参数
- 环境变量支持性能精细调优
## 📋 快速开始
### 📥 安装方法
- **预编译二进制文件**: 从[发布页面](https://github.com/yosebyte/nodepass/releases)下载。
- **容器镜像**: `docker pull ghcr.io/yosebyte/nodepass:latest`
### 🚀 基本用法
**服务端模式**
```bash
nodepass "server://:10101/127.0.0.1:8080?log=debug&tls=1"
```
**客户端模式**
```bash
nodepass "client://server:10101/127.0.0.1:8080?min=128"
```
**主控模式 (API)**
```bash
nodepass "master://:10101/api?log=debug&tls=1"
```
## 📚 文档
探索完整文档以了解更多关于NodePass的信息
- [安装指南](/docs/zh/installation.md)
- [使用说明](/docs/zh/usage.md)
- [配置选项](/docs/zh/configuration.md)
- [API参考](/docs/zh/api.md)
- [使用示例](/docs/zh/examples.md)
- [工作原理](/docs/zh/how-it-works.md)
- [故障排除](/docs/zh/troubleshooting.md)
## 🌐 生态系统
[NodePassProject](https://github.com/NodePassProject) 组织开发了各种前端应用和辅助工具来增强 NodePass 体验:
- **[NodePassDash](https://github.com/NodePassProject/NodePassDash)**: 现代化的 NodePass 管理界面,提供主控管理、实例管理、流量统计、历史记录等功能。
- **[NodePanel](https://github.com/NodePassProject/NodePanel)**: 轻量化的前端面板,提供可视化的隧道管理功能,在 Vercel 或 Cloudflare Pages 轻松部署。
- **[npsh](https://github.com/NodePassProject/npsh)**: 简单易用的 NodePass 一键脚本合集,包括 API 主控、Dash 面板的安装部署、灵活配置和辅助管理。
## 💬 讨论
- 关注我们的 [Telegram 频道](https://t.me/NodePassChannel) 获取最新更新和社区支持。
- 加入我们的 [Discord](https://discord.gg/2cnXcnDMGc) 和 [Telegram 群组](https://t.me/NodePassGroup) 分享经验和想法。
## 📄 许可协议
`NodePass`项目根据[BSD 3-Clause许可证](LICENSE)授权。
## ⚖️ 免责声明
本项目以“现状”提供,开发者不提供任何明示或暗示的保证。用户使用风险自担,需遵守当地法律法规,仅限合法用途。开发者对任何直接、间接、偶然或后果性损害概不负责。进行二次开发须承诺合法使用并自负法律责任。开发者保留随时修改软件功能及本声明的权利。最终解释权归开发者所有。
## 🤝 赞助商
<table>
<tr>
<td width="200" align="center">
<a href="https://whmcs.as211392.com"><img src="https://cdn.yobc.de/assets/dreamcloud.png"></a>
</td>
<td width="200" align="center">
<a href="https://zmto.com"><img src="https://cdn.yobc.de/assets/zmto.png"></a>
</td>
</tr>
</table>
## ⭐ Star趋势
[![Stargazers over time](https://starchart.cc/yosebyte/nodepass.svg?variant=adaptive)](https://starchart.cc/yosebyte/nodepass)

161
nodepass/SECURITY.md Normal file
View File

@@ -0,0 +1,161 @@
# Security Policy
## Supported Versions
We provide security updates for the following versions of NodePass:
| Version | Supported |
| ------- | ------------------ |
| Latest | :white_check_mark: |
## Security Features
NodePass implements multiple security layers:
### TLS Encryption Modes
- **TLS Mode 0**: Unencrypted mode for trusted networks (highest performance)
- **TLS Mode 1**: Self-signed certificates with TLS 1.3 (balanced security)
- **TLS Mode 2**: Custom certificate validation for enterprise security
### Network Security
- Password-based tunnel authentication
- Connection pooling with capacity limits
- Graceful degradation under load
- Configurable timeout and retry mechanisms
## Reporting Security Vulnerabilities
We take security seriously. If you discover a security vulnerability in NodePass, please report it responsibly.
### Where to Report
- **Email**: team@mail.nodepass.eu
- **Subject**: [SECURITY] Brief description of the issue
### What to Include
Please provide the following information:
1. **Description** of the vulnerability
2. **Steps to reproduce** the issue
3. **Potential impact** and affected versions
4. **Your contact information** for follow-up
5. **Any proof-of-concept code** (if applicable)
### Response Process
1. **Acknowledgment**: We will acknowledge receipt within 48 hours
2. **Assessment**: Initial assessment within 5 business days
3. **Updates**: Regular updates on investigation progress
4. **Resolution**: Security patch and public disclosure coordination
### Responsible Disclosure
- Please **do not** create public GitHub issues for security vulnerabilities
- Give us reasonable time to investigate and patch the issue
- We will coordinate public disclosure timing with you
- Security researchers will be credited in our security advisories
## Security Best Practices
### For Users
- **Use TLS Mode 1 or 2** in production environments
- **Choose strong passwords** for tunnel authentication
- **Keep NodePass updated** to the latest version
- **Monitor logs** for suspicious activity
- **Limit network exposure** by binding to specific interfaces
- **Use firewall rules** to restrict access to tunnel ports
### For Developers
- **Validate all inputs** including URL parameters and network data
- **Use secure coding practices** following Go security guidelines
- **Implement proper error handling** without leaking sensitive information
- **Test security features** thoroughly before release
- **Follow the principle of least privilege** in code design
## Security Architecture
### Network Layer
- TLS 1.3 encryption for secure data transmission
- Certificate validation and auto-reload capabilities
- Protection against common network attacks
### Application Layer
- Input validation and sanitization
- Secure memory handling for sensitive data
- Proper resource cleanup and connection management
### Operational Security
- Minimal container image based on scratch
- No unnecessary dependencies or services
- Clear separation of concerns between components
## Known Security Considerations
### TLS Mode 0 Usage
- Only use in completely trusted networks
- Not recommended for internet-facing deployments
- Provides maximum performance at the cost of encryption
### Master API Security
- Secure the API endpoint with proper authentication
- Use reverse proxy for additional security layers
- Monitor API access and implement rate limiting
## Security Updates
Security updates are released as:
- **Patch releases** for critical vulnerabilities
- **Minor releases** for security enhancements
- **Documentation updates** for security best practices
Subscribe to our release notifications:
- [GitHub Releases](https://github.com/yosebyte/nodepass/releases)
- [Telegram Channel](https://t.me/NodePassChannel)
## Ecosystem Security
### NodePassProject Libraries
Our core dependencies are maintained by the NodePassProject organization:
- **cert**: Certificate generation and management
- **conn**: Secure connection handling
- **logs**: Secure logging with sensitive data protection
- **pool**: Connection pool management with resource limits
### Third-Party Dependencies
- We minimize external dependencies
- All dependencies are regularly audited for security issues
- Updates are applied promptly when security issues are discovered
## Contact Information
For security-related questions or concerns:
- **Security Team**: team@mail.nodepass.eu
- **General Issues**: [GitHub Issues](https://github.com/yosebyte/nodepass/issues)
- **Community**: [Telegram Group](https://t.me/NodePassGroup)
## Attribution
We appreciate security researchers who help improve NodePass security. Contributors to our security will be acknowledged in:
- Security advisories
- Release notes
- Our contributors list
---
**Note**: This security policy applies to the NodePass core project. For security issues in ecosystem projects (NodePassDash, NodePanel, etc.), please refer to their respective repositories in the [NodePassProject](https://github.com/NodePassProject) organization.

View File

@@ -0,0 +1,101 @@
package main
import (
"crypto/tls"
"net/url"
"time"
"github.com/NodePassProject/cert"
"github.com/yosebyte/nodepass/internal"
)
// coreDispatch 根据URL方案分派到不同的运行模式
func coreDispatch(parsedURL *url.URL) {
var core interface{ Run() }
switch scheme := parsedURL.Scheme; scheme {
case "server", "master":
tlsCode, tlsConfig := getTLSProtocol(parsedURL)
if scheme == "server" {
core = internal.NewServer(parsedURL, tlsCode, tlsConfig, logger)
} else {
core = internal.NewMaster(parsedURL, tlsCode, tlsConfig, logger, version)
}
case "client":
core = internal.NewClient(parsedURL, logger)
default:
logger.Error("Unknown core: %v", scheme)
getExitInfo()
}
core.Run()
}
// getTLSProtocol 获取TLS配置
func getTLSProtocol(parsedURL *url.URL) (string, *tls.Config) {
// 生成基本TLS配置
tlsConfig, err := cert.NewTLSConfig("yosebyte/nodepass:" + version)
if err != nil {
logger.Error("Generate failed: %v", err)
logger.Warn("TLS code-0: nil cert")
return "0", nil
}
tlsConfig.MinVersion = tls.VersionTLS13
tlsCode := parsedURL.Query().Get("tls")
switch tlsCode {
case "0":
// 不使用加密
logger.Info("TLS code-0: unencrypted")
return tlsCode, nil
case "1":
// 使用内存中的证书
logger.Info("TLS code-1: RAM cert with TLS 1.3")
return tlsCode, tlsConfig
case "2":
// 使用自定义证书
crtFile, keyFile := parsedURL.Query().Get("crt"), parsedURL.Query().Get("key")
cert, err := tls.LoadX509KeyPair(crtFile, keyFile)
if err != nil {
logger.Error("Cert load failed: %v", err)
logger.Warn("TLS code-1: RAM cert with TLS 1.3")
return "1", tlsConfig
}
// 缓存证书并设置自动重载
cachedCert := cert
lastReload := time.Now()
tlsConfig = &tls.Config{
MinVersion: tls.VersionTLS13,
GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
// 定期重载证书
if time.Since(lastReload) >= internal.ReloadInterval {
newCert, err := tls.LoadX509KeyPair(crtFile, keyFile)
if err != nil {
logger.Error("Cert reload failed: %v", err)
} else {
logger.Debug("TLS cert reloaded: %v", crtFile)
cachedCert = newCert
}
lastReload = time.Now()
}
return &cachedCert, nil
},
}
if cert.Leaf != nil {
logger.Info("TLS code-2: %v with TLS 1.3", cert.Leaf.Subject.CommonName)
} else {
logger.Warn("TLS code-2: unknown cert name with TLS 1.3")
}
return tlsCode, tlsConfig
default:
// 默认不使用加密
logger.Warn("TLS code-0: unencrypted")
return "0", nil
}
}

View File

@@ -0,0 +1,91 @@
package main
import (
"net/url"
"os"
"runtime"
"github.com/NodePassProject/logs"
)
var (
// 全局日志记录器
logger = logs.NewLogger(logs.Info, true)
// 程序版本
version = "dev"
)
// main 程序入口
func main() {
parsedURL := getParsedURL(os.Args)
initLogLevel(parsedURL.Query().Get("log"))
coreDispatch(parsedURL)
}
// getParsedURL 解析URL参数
func getParsedURL(args []string) *url.URL {
if len(args) < 2 {
getExitInfo()
}
parsedURL, err := url.Parse(args[1])
if err != nil {
logger.Error("URL parse: %v", err)
getExitInfo()
}
return parsedURL
}
// initLogLevel 初始化日志级别
func initLogLevel(level string) {
switch level {
case "debug":
logger.SetLogLevel(logs.Debug)
logger.Debug("Init log level: DEBUG")
case "warn":
logger.SetLogLevel(logs.Warn)
logger.Warn("Init log level: WARN")
case "error":
logger.SetLogLevel(logs.Error)
logger.Error("Init log level: ERROR")
default:
logger.SetLogLevel(logs.Info)
logger.Info("Init log level: INFO")
}
}
// getExitInfo 输出帮助信息并退出程序
func getExitInfo() {
logger.SetLogLevel(logs.Info)
logger.Info(`Version: %v %v/%v
╭─────────────────────────────────────────────────────────╮
│ ░░█▀█░█▀█░░▀█░█▀▀░█▀█░█▀█░█▀▀░█▀▀░░ │
│ ░░█░█░█░█░█▀█░█▀▀░█▀▀░█▀█░▀▀█░▀▀█░░ │
│ ░░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀░░░▀░▀░▀▀▀░▀▀▀░░ │
├─────────────────────────────────────────────────────────┤
│ >Universal TCP/UDP Tunneling Solution │
│ >https://github.com/yosebyte/nodepass │
├─────────────────────────────────────────────────────────┤
│ Usage: nodepass "<your-unique-URL-syntax-command>" │
├─────────────────────────────────────────────────────────┤
│ server://password@tunnel/target?log=X&tls=X&crt=X&key=X │
│ client://password@tunnel/target?log=X&min=X&max=X │
│ master://host:port/prefix?log=X&tls=X&crt=X&key=X │
├──────────┬─────────────────────────┬────────────────────┤
│ Keys │ Values │ Description │
├──────────┼─────────────────────────┼────────────────────┤
│ tunnel │ host:port (IP | domain) │ Tunnel address │
│ target │ host:port (IP | domain) │ Target address │
│ log │ debug | warn | error │ Default level info │
│ tls │ 0 off | 1 on | 2 verify │ Default TLS code-0 │
│ crt │ <path/to/crt.pem> │ Custom certificate │
│ key │ <path/to/key.pem> │ Custom private key │
│ min │ <min> │ Min pool capacity │
│ max │ <max> │ Max pool capacity │
│ prefix │ <path/to/your/api> │ Master API prefix │
╰──────────┴─────────────────────────┴────────────────────╯
`, version, runtime.GOOS, runtime.GOARCH)
os.Exit(1)
}

1127
nodepass/docs/en/api.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
# Configuration Options
NodePass uses a minimalist approach to configuration, with all settings specified via command-line parameters and environment variables. This guide explains all available configuration options and provides recommendations for various deployment scenarios.
## Log Levels
NodePass provides five log verbosity levels that control the amount of information displayed:
- `debug`: Verbose debugging information - shows all operations and connections
- `info`: General operational information (default) - shows startup, shutdown, and key events
- `warn`: Warning conditions - only shows potential issues that don't affect core functionality
- `error`: Error conditions - shows only problems that affect functionality
- `event`: Event recording - shows important operational events and traffic statistics
You can set the log level in the command URL:
```bash
nodepass server://0.0.0.0:10101/0.0.0.0:8080?log=debug
```
## TLS Encryption Modes
For server and master modes, NodePass offers three TLS security levels for data channels:
- **Mode 0**: No TLS encryption (plain TCP/UDP)
- Fastest performance, no overhead
- No security for data channel (only use in trusted networks)
- **Mode 1**: Self-signed certificate (automatically generated)
- Good security with minimal setup
- Certificate is automatically generated and not verified
- Protects against passive eavesdropping
- **Mode 2**: Custom certificate (requires `crt` and `key` parameters)
- Highest security with certificate validation
- Requires providing certificate and key files
- Suitable for production environments
Example with TLS Mode 1 (self-signed):
```bash
nodepass server://0.0.0.0:10101/0.0.0.0:8080?tls=1
```
Example with TLS Mode 2 (custom certificate):
```bash
nodepass "server://0.0.0.0:10101/0.0.0.0:8080?tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
## Connection Pool Capacity Parameters
Connection pool capacity can be configured via URL query parameters:
- `min`: Minimum connection pool capacity (default: 64)
- `max`: Maximum connection pool capacity (default: 8192)
Example:
```bash
# Set minimum pool to 32 and maximum to 4096
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=32&max=4096"
```
## Environment Variables
NodePass behavior can be fine-tuned using environment variables. Below is the complete list of available variables with their descriptions, default values, and recommended settings for different scenarios.
| Variable | Description | Default | Example |
|----------|-------------|---------|---------|
| `NP_SEMAPHORE_LIMIT` | Maximum number of concurrent connections | 1024 | `export NP_SEMAPHORE_LIMIT=2048` |
| `NP_UDP_DATA_BUF_SIZE` | Buffer size for UDP packets | 8192 | `export NP_UDP_DATA_BUF_SIZE=16384` |
| `NP_UDP_READ_TIMEOUT` | Timeout for UDP read operations | 20s | `export NP_UDP_READ_TIMEOUT=30s` |
| `NP_UDP_DIAL_TIMEOUT` | Timeout for establishing UDP connections | 20s | `export NP_UDP_DIAL_TIMEOUT=30s` |
| `NP_TCP_READ_TIMEOUT` | Timeout for TCP read operations | 20s | `export NP_TCP_READ_TIMEOUT=30s` |
| `NP_TCP_DIAL_TIMEOUT` | Timeout for establishing TCP connections | 20s | `export NP_TCP_DIAL_TIMEOUT=30s` |
| `NP_MIN_POOL_INTERVAL` | Minimum interval between connection creations | 1s | `export NP_MIN_POOL_INTERVAL=500ms` |
| `NP_MAX_POOL_INTERVAL` | Maximum interval between connection creations | 5s | `export NP_MAX_POOL_INTERVAL=3s` |
| `NP_REPORT_INTERVAL` | Interval for health check reports | 5s | `export NP_REPORT_INTERVAL=10s` |
| `NP_SERVICE_COOLDOWN` | Cooldown period before restart attempts | 3s | `export NP_SERVICE_COOLDOWN=5s` |
| `NP_SHUTDOWN_TIMEOUT` | Timeout for graceful shutdown | 5s | `export NP_SHUTDOWN_TIMEOUT=10s` |
| `NP_RELOAD_INTERVAL` | Interval for cert/pool reload | 1h | `export NP_RELOAD_INTERVAL=30m` |
### Connection Pool Tuning
The connection pool parameters are important settings for performance tuning:
#### Pool Capacity Settings
- `min` (URL parameter): Ensures a minimum number of available connections
- Too low: Increased latency during traffic spikes as new connections must be established
- Too high: Wasted resources maintaining idle connections
- Recommended starting point: 25-50% of your average concurrent connections
- `max` (URL parameter): Prevents excessive resource consumption while handling peak loads
- Too low: Connection failures during traffic spikes
- Too high: Potential resource exhaustion affecting system stability
- Recommended starting point: 150-200% of your peak concurrent connections
#### Pool Interval Settings
- `NP_MIN_POOL_INTERVAL`: Controls the minimum time between connection creation attempts
- Too low: May overwhelm network with connection attempts
- Recommended range: 500ms-2s depending on network latency
- `NP_MAX_POOL_INTERVAL`: Controls the maximum time between connection creation attempts
- Too high: May result in pool depletion during traffic spikes
- Recommended range: 3s-10s depending on expected traffic patterns
#### Connection Management
- `NP_SEMAPHORE_LIMIT`: Controls the maximum number of concurrent tunnel operations
- Too low: Rejected connections during traffic spikes
- Too high: Potential memory pressure from too many concurrent goroutines
- Recommended range: 1000-5000 for most applications, higher for high-throughput scenarios
### UDP Settings
For applications relying heavily on UDP traffic:
- `NP_UDP_DATA_BUF_SIZE`: Buffer size for UDP packets
- Increase for applications sending large UDP packets
- Default (8192) works well for most cases
- Consider increasing to 16384 or higher for media streaming or game servers
- `NP_UDP_READ_TIMEOUT`: Timeout for UDP read operations
- Increase for high-latency networks or applications with slow response times
- Decrease for low-latency applications requiring quick failover
- `NP_UDP_DIAL_TIMEOUT`: Timeout for establishing UDP connections
- Increase for high-latency networks or applications with slow response times
- Decrease for low-latency applications requiring quick failover
### TCP Settings
For optimizing TCP connections:
- `NP_TCP_READ_TIMEOUT`: Timeout for TCP read operations
- Increase for high-latency networks or servers with slow response times
- Decrease for applications that need to detect disconnections quickly
- Affects wait time during data transfer phases
- `NP_TCP_DIAL_TIMEOUT`: Timeout for establishing TCP connections
- Increase for unstable network conditions
- Decrease for applications that need quick connection success/failure determination
- Affects initial connection establishment phase
### Service Management Settings
- `NP_REPORT_INTERVAL`: Controls how frequently health status is reported
- Lower values provide more frequent updates but increase log volume
- Higher values reduce log output but provide less immediate visibility
- `NP_RELOAD_INTERVAL`: Controls how frequently TLS certificates are checked for changes
- Lower values detect certificate changes faster but increase file system operations
- Higher values reduce overhead but delay detection of certificate updates
- `NP_SERVICE_COOLDOWN`: Time to wait before attempting service restarts
- Lower values attempt recovery faster but might cause thrashing in case of persistent issues
- Higher values provide more stability but slower recovery from transient issues
- `NP_SHUTDOWN_TIMEOUT`: Maximum time to wait for connections to close during shutdown
- Lower values ensure quicker shutdown but may interrupt active connections
- Higher values allow more time for connections to complete but delay shutdown
## Configuration Profiles
Here are some recommended environment variable configurations for common scenarios:
### High-Throughput Configuration
For applications requiring maximum throughput (e.g., media streaming, file transfers):
URL parameters:
```bash
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=128&max=8192"
```
Environment variables:
```bash
export NP_MIN_POOL_INTERVAL=500ms
export NP_MAX_POOL_INTERVAL=3s
export NP_SEMAPHORE_LIMIT=8192
export NP_UDP_DATA_BUF_SIZE=32768
export NP_REPORT_INTERVAL=10s
```
### Low-Latency Configuration
For applications requiring minimal latency (e.g., gaming, financial trading):
URL parameters:
```bash
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=256&max=4096"
```
Environment variables:
```bash
export NP_MIN_POOL_INTERVAL=100ms
export NP_MAX_POOL_INTERVAL=1s
export NP_SEMAPHORE_LIMIT=4096
export NP_UDP_READ_TIMEOUT=5s
export NP_REPORT_INTERVAL=1s
```
### Resource-Constrained Configuration
For deployment on systems with limited resources (e.g., IoT devices, small VPS):
URL parameters:
```bash
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=16&max=512"
```
Environment variables:
```bash
export NP_MIN_POOL_INTERVAL=2s
export NP_MAX_POOL_INTERVAL=10s
export NP_SEMAPHORE_LIMIT=512
export NP_REPORT_INTERVAL=30s
export NP_SHUTDOWN_TIMEOUT=3s
```
## Next Steps
- See [usage instructions](/docs/en/usage.md) for basic operational commands
- Explore [examples](/docs/en/examples.md) to understand deployment patterns
- Learn about [how NodePass works](/docs/en/how-it-works.md) to optimize your configuration
- Check the [troubleshooting guide](/docs/en/troubleshooting.md) if you encounter issues

View File

@@ -0,0 +1,261 @@
# Usage Examples
This page provides practical examples of NodePass in various deployment scenarios. These examples cover common use cases and can be adapted to suit your specific requirements.
## Basic Server Setup with TLS Options
### Example 1: No TLS Encryption
When speed is more important than security (e.g., in trusted networks):
```bash
nodepass "server://0.0.0.0:10101/127.0.0.1:8080?log=debug&tls=0"
```
This starts a NodePass server that:
- Listens for tunnel connections on all interfaces, port 10101
- Forwards traffic to localhost:8080
- Uses debug logging for detailed information
- Uses no encryption for data channels (fastest performance)
### Example 2: Self-Signed Certificate
For balanced security and ease of setup (recommended for most cases):
```bash
nodepass "server://0.0.0.0:10101/127.0.0.1:8080?log=debug&tls=1"
```
This configuration:
- Automatically generates a self-signed certificate
- Provides encryption without requiring certificate management
- Protects data traffic from passive eavesdropping
- Works well for internal or testing environments
### Example 3: Custom Domain Certificate
For production environments requiring verified certificates:
```bash
nodepass "server://0.0.0.0:10101/127.0.0.1:8080?log=debug&tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
This setup:
- Uses your provided TLS certificate and private key
- Offers the highest security level with certificate validation
- Is ideal for production environments and public-facing services
- Allows clients to verify the server's identity
## Connecting to a NodePass Server
### Example 4: Basic Client Connection
Connect to a NodePass server with default settings:
```bash
nodepass client://server.example.com:10101/127.0.0.1:8080
```
This client:
- Connects to the NodePass server at server.example.com:10101
- Forwards received traffic to localhost:8080
- Automatically adopts the server's TLS security policy
- Uses the default info log level
### Example 5: Client with Debug Logging
For troubleshooting connection issues:
```bash
nodepass client://server.example.com:10101/127.0.0.1:8080?log=debug
```
This enables verbose output to help identify:
- Connection establishment issues
- Signal processing
- Data transfer details
- Error conditions
## Database Access Through Firewall
### Example 6: Database Tunneling
Enable secure access to a database server behind a firewall:
```bash
# Server side (outside secured network) with TLS encryption
nodepass server://:10101/127.0.0.1:5432?tls=1
# Client side (inside the firewall)
nodepass client://server.example.com:10101/127.0.0.1:5432
```
This configuration:
- Creates an encrypted tunnel to a PostgreSQL database (port 5432)
- Allows secure access to the database without exposing it directly to the internet
- Encrypts all database traffic with a self-signed certificate
- Maps the remote database to appear as a local service on the client side
## Secure Microservice Communication
### Example 7: Service-to-Service Communication
Enable secure communication between microservices:
```bash
# Service A (consuming API) with custom certificate
nodepass "server://0.0.0.0:10101/127.0.0.1:8081?log=warn&tls=2&crt=/path/to/service-a.crt&key=/path/to/service-a.key"
# Service B (providing API)
nodepass client://service-a:10101/127.0.0.1:8082
```
This setup:
- Creates a secure channel between two microservices
- Uses a custom certificate for service identity verification
- Limits logging to warnings and errors only
- Maps service A's API to appear as a local service on service B
## IoT Device Management
### Example 8: IoT Gateway
Create a central access point for IoT devices:
```bash
# Central management server
nodepass "server://0.0.0.0:10101/127.0.0.1:8888?log=info&tls=1"
# IoT device
nodepass client://mgmt.example.com:10101/127.0.0.1:80
```
This configuration:
- Enables secure connections from distributed IoT devices to a central server
- Uses self-signed certificates for adequate security
- Allows embedded devices to expose their local web interfaces securely
- Centralizes device management through a single endpoint
## Multi-environment Development
### Example 9: Development Environment Access
Access different development environments through tunnels:
```bash
# Production API access tunnel
nodepass client://tunnel.example.com:10101/127.0.0.1:3443
# Development environment
nodepass server://tunnel.example.com:10101/127.0.0.1:3000
# Testing environment
nodepass "server://tunnel.example.com:10101/127.0.0.1:3001?log=warn&tls=1"
```
This setup:
- Creates secure access to multiple environments (production, development, testing)
- Uses different levels of logging based on environment sensitivity
- Enables developers to access environments without direct network exposure
- Maps remote services to different local ports for easy identification
## Container Deployment
### Example 10: Containerized NodePass
Deploy NodePass in a Docker environment:
```bash
# Create a network for the containers
docker network create nodepass-net
# Deploy NodePass server with self-signed certificate
docker run -d --name nodepass-server \
--network nodepass-net \
-p 10101:10101 \
ghcr.io/yosebyte/nodepass "server://0.0.0.0:10101/web-service:80?log=info&tls=1"
# Deploy a web service as target
docker run -d --name web-service \
--network nodepass-net \
nginx:alpine
# Deploy NodePass client
docker run -d --name nodepass-client \
-p 8080:8080 \
ghcr.io/yosebyte/nodepass client://nodepass-server:10101/127.0.0.1:8080?log=info
# Access the web service via http://localhost:8080
```
This configuration:
- Creates a containerized tunnel between services
- Uses Docker networking to connect containers
- Exposes only necessary ports to the host
- Provides secure access to an internal web service
## Master API Management
### Example 11: Centralized Management
Set up a central controller for multiple NodePass instances:
```bash
# Start the master API service with self-signed certificate
nodepass "master://0.0.0.0:9090?log=info&tls=1"
```
You can then manage instances via API calls:
```bash
# Create a server instance
curl -X POST http://localhost:9090/api/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
# Create a client instance
curl -X POST http://localhost:9090/api/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"client://localhost:10101/127.0.0.1:8081"}'
# List all running instances
curl http://localhost:9090/api/v1/instances
# Control an instance (replace {id} with actual instance ID)
curl -X PUT http://localhost:9090/api/v1/instances/{id} \
-H "Content-Type: application/json" \
-d '{"action":"restart"}'
```
This setup:
- Provides a central management interface for all NodePass instances
- Allows dynamic creation and control of tunnels
- Offers a RESTful API for automation and integration
- Includes a built-in Swagger UI at http://localhost:9090/api/v1/docs
### Example 12: Custom API Prefix
Use a custom API prefix for the master mode:
```bash
# Start with custom API prefix
nodepass "master://0.0.0.0:9090/admin?log=info&tls=1"
# Create an instance using the custom prefix
curl -X POST http://localhost:9090/admin/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
```
This allows:
- Integration with existing API gateways
- Custom URL paths for security or organizational purposes
- Swagger UI access at http://localhost:9090/admin/v1/docs
## Next Steps
Now that you've seen various usage examples, you might want to:
- Learn about [configuration options](/docs/en/configuration.md) for fine-tuning
- Understand [how NodePass works](/docs/en/how-it-works.md) under the hood
- Check the [troubleshooting guide](/docs/en/troubleshooting.md) for common issues

View File

@@ -0,0 +1,313 @@
# How NodePass Works
This page explains the internal architecture and data flow mechanisms of NodePass, providing insights into how the different components interact to create efficient and secure tunnels.
## Architecture Overview
NodePass creates a network architecture with separate channels for control and data:
1. **Control Channel (Tunnel)**:
- Unencrypted TCP connection between client and server
- Used exclusively for signaling and coordination
- Maintains persistent connection for the lifetime of the tunnel
2. **Data Channel (Target)**:
- Configurable TLS encryption options:
- **Mode 0**: Unencrypted data transfer (fastest, least secure)
- **Mode 1**: Self-signed certificate encryption (good security, no verification)
- **Mode 2**: Verified certificate encryption (highest security, requires valid certificates)
- Created on-demand for each connection or datagram
- Used for actual application data transfer
3. **Server Mode Operation**:
- Listens for control connections on the tunnel endpoint
- When traffic arrives at the target endpoint, signals the client via the control channel
- Establishes data channels with the specified TLS mode when needed
- Supports bidirectional data flow: connections can be initiated from either server or client side
4. **Client Mode Operation**:
- Connects to the server's control channel
- Listens for signals indicating incoming connections
- Creates data connections using the TLS security level specified by the server
- Forwards data between the secure channel and local target
- Supports bidirectional data flow: data flow direction is automatically selected based on target address
5. **Client Single-End Forwarding Mode**:
- Automatically enabled when tunnel address is a local address (e.g., 127.0.0.1)
- Client directly listens on local port without server control channel coordination
- Uses connection pooling technology for TCP connections to significantly improve forwarding performance
- Suitable for pure local forwarding scenarios, reducing network overhead and latency
- Supports high-performance single-end forwarding for both TCP and UDP protocols
5. **Protocol Support**:
- **TCP**: Full bidirectional streaming with persistent connections, supports connection pool optimization in client single-end forwarding mode
- **UDP**: Datagram forwarding with configurable buffer sizes and timeouts
## Data Transmission Flow
NodePass establishes a bidirectional data flow through its tunnel architecture, supporting both TCP and UDP protocols. The system supports three data flow modes:
### Data Flow Mode Explanation
- **Server Receives Mode (dataFlow: "-")**: Server listens on target address, client listens locally, data flows from target address to client local
- **Server Sends Mode (dataFlow: "+")**: Server connects to remote target address, client listens locally, data flows from client local to remote target
- **Client Single-End Forwarding Mode**: Client directly listens locally and forwards to target address without server coordination, using connection pooling technology for high-performance forwarding
The data flow mode is automatically determined based on tunnel address and target address:
- If tunnel address is a local address (localhost, 127.0.0.1, etc.), enables Client Single-End Forwarding Mode
- If target address is a local address, uses Server Receives Mode
- If target address is a remote address, uses Server Sends Mode
### Server-Side Flow (Server Receives Mode)
1. **Connection Initiation**:
```
[Target Client] → [Target Listener] → [Server: Target Connection Created]
```
- For TCP: Client establishes persistent connection to target listener
- For UDP: Server receives datagrams on UDP socket bound to target address
2. **Signal Generation**:
```
[Server] → [Generate Unique Connection ID] → [Signal Client via Unencrypted TCP Tunnel]
```
- For TCP: Generates a `//<connection_id>#1` signal
- For UDP: Generates a `//<connection_id>#2` signal
3. **Connection Preparation**:
```
[Server] → [Create Remote Connection in Pool with Configured TLS Mode] → [Wait for Client Connection]
```
- Both protocols use the same connection pool mechanism with unique connection IDs
- TLS configuration applied based on the specified mode (0, 1, or 2)
4. **Data Exchange**:
```
[Target Connection] ⟷ [Exchange/Transfer] ⟷ [Remote Connection]
```
- For TCP: Uses `conn.DataExchange()` for continuous bidirectional data streaming
- For UDP: Individual datagrams are forwarded with configurable buffer sizes
### Client-Side Flow
1. **Signal Reception**:
```
[Client] → [Read Signal from TCP Tunnel] → [Parse Connection ID]
```
- Client differentiates between TCP and UDP signals based on URL scheme
2. **Connection Establishment**:
```
[Client] → [Retrieve Connection from Pool] → [Connect to Remote Endpoint]
```
- Connection management is protocol-agnostic at this stage
3. **Local Connection**:
```
[Client] → [Connect to Local Target] → [Establish Local Connection]
```
- For TCP: Establishes persistent TCP connection to local target
- For UDP: Creates UDP socket for datagram exchange with local target
4. **Data Exchange**:
```
[Remote Connection] ⟷ [Exchange/Transfer] ⟷ [Local Target Connection]
```
- For TCP: Uses `conn.DataExchange()` for continuous bidirectional data streaming
- For UDP: Reads single datagram, forwards it, waits for response with timeout, then returns response
### Client Single-End Forwarding Flow
1. **Mode Detection**:
```
[Client] → [Detect Tunnel Address as Local Address] → [Enable Single-End Forwarding Mode]
```
- Automatically detects if tunnel address is localhost, 127.0.0.1, or other local addresses
- Enables single-end forwarding mode, skipping server control channel establishment
2. **Local Listening**:
```
[Client] → [Start Listener on Tunnel Port] → [Wait for Local Connections]
```
- Directly starts TCP or UDP listener on specified tunnel port
- No need to connect to remote server, achieving zero-latency startup
3. **Connection Pool Initialization** (TCP Only):
```
[Client] → [Initialize Target Connection Pool] → [Pre-establish Connections to Target Address]
```
- Creates high-performance connection pool for TCP forwarding
- Pre-establishes multiple connections to target address, significantly reducing connection establishment latency
- Connection pool size can be dynamically adjusted based on concurrent demand
4. **High-Performance Forwarding**:
```
[Local Connection] → [Get Target Connection from Pool] → [Direct Data Exchange] → [Connection Reuse or Release]
```
- For TCP: Quickly gets pre-established target connection from pool for efficient data exchange
- For UDP: Directly forwards datagrams to target address without connection pool
- Optimized data path minimizing forwarding overhead and latency
### Protocol-Specific Characteristics
- **TCP Exchange**:
- Persistent connections for full-duplex communication
- Continuous data streaming until connection termination
- Error handling with automatic reconnection
- **Client Single-End Forwarding Optimization**: Pre-established connections through connection pooling technology, significantly reducing connection establishment latency
- **UDP Exchange**:
- One-time datagram forwarding with configurable buffer sizes (`UDP_DATA_BUF_SIZE`)
- Read timeout control for response waiting (`UDP_READ_TIMEOUT`)
- Optimized for low-latency, stateless communications
- **Client Single-End Forwarding Optimization**: Direct forwarding mechanism without connection pool, achieving minimal latency
## Signal Communication Mechanism
NodePass uses a sophisticated URL-based signaling protocol through the TCP tunnel:
### Signal Types
1. **Tunnel Signal**:
- Format: `#<tls>`
- Purpose: Informs the client about the tls code
- Timing: Sent on tunnel handshake
2. **TCP Launch Signal**:
- Format: `//<connection_id>#1`
- Purpose: Requests the client to establish a TCP connection for a specific ID
- Timing: Sent when a new TCP connection to the target service is received
3. **UDP Launch Signal**:
- Format: `//<connection_id>#2`
- Purpose: Requests the client to handle UDP traffic for a specific ID
- Timing: Sent when UDP data is received on the target port
### Signal Flow
1. **Signal Generation**:
- Server creates URL-formatted signals for specific events
- Signal is terminated with a newline character for proper parsing
2. **Signal Transmission**:
- Server writes signals to the TCP tunnel connection
- Uses a mutex to prevent concurrent writes to the tunnel
3. **Signal Reception**:
- Client uses a buffered reader to read signals from the tunnel
- Signals are trimmed and parsed into URL format
4. **Signal Processing**:
- Client places valid signals in a buffered channel (signalChan)
- A dedicated goroutine processes signals from the channel
- Semaphore pattern prevents signal overflow
5. **Signal Execution**:
- Remote signals update the client's remote address configuration
- Launch signals trigger the `clientOnce()` method to establish connections
### Signal Resilience
- Buffered channel with configurable capacity prevents signal loss during high load
- Semaphore implementation ensures controlled concurrency
- Error handling for malformed or unexpected signals
## Connection Pool Architecture
NodePass implements an efficient connection pooling system for managing network connections:
### Pool Design
1. **Pool Types**:
- **Client Pool**: Pre-establishes connections to the remote endpoint
- **Server Pool**: Manages incoming connections from clients
2. **Pool Components**:
- **Connection Storage**: Thread-safe map of connection IDs to net.Conn objects
- **ID Channel**: Buffered channel for available connection IDs
- **Capacity Management**: Dynamic adjustment based on usage patterns
- **Interval Control**: Time-based throttling between connection creations
- **Connection Factory**: Customizable connection creation function
### Connection Lifecycle
1. **Connection Creation**:
- Connections are created up to the configured capacity
- Each connection is assigned a unique ID
- IDs and connections are stored in the pool
2. **Connection Acquisition**:
- Client retrieves connections using connection IDs
- Server retrieves the next available connection from the pool
- Connections are validated before being returned
3. **Connection Usage**:
- Connection is removed from the pool when acquired
- Used for data exchange between endpoints
- No connection reuse (one-time use model)
4. **Connection Termination**:
- Connections are closed after use
- Resources are properly released
- Error handling ensures clean termination
### Pool Management
1. **Capacity Control**:
- `MIN_POOL_CAPACITY`: Ensures minimum available connections
- `MAX_POOL_CAPACITY`: Prevents excessive resource consumption
- Dynamic scaling based on demand patterns
2. **Interval Control**:
- `MIN_POOL_INTERVAL`: Minimum time between connection creation attempts
- `MAX_POOL_INTERVAL`: Maximum time between connection creation attempts
- Adaptive time-based throttling to optimize resource usage
3. **Dynamic Pool Adaptation**:
The connection pool employs a dual-adaptive mechanism to ensure optimal performance:
**A. Capacity Adjustment**
- Pool capacity dynamically adjusts based on real-time usage patterns
- If connection creation success rate is low (<20%), capacity decreases to minimize resource waste
- If connection creation success rate is high (>80%), capacity increases to accommodate higher traffic
- Gradual scaling prevents oscillation and provides stability
- Respects configured minimum and maximum capacity boundaries
**B. Interval Adjustment**
- Creation intervals adapt based on pool idle connection count
- When idle connections are low (<20% of capacity), intervals decrease toward min interval
- When idle connections are high (>80% of capacity), intervals increase toward max interval
- Prevents overwhelming network resources during periods of low demand
- Accelerates connection creation during high demand periods when pool is depleting
## Master API Architecture
In master mode, NodePass provides a RESTful API for centralized management:
### API Components
1. **HTTP/HTTPS Server**:
- Listens on configured address and port
- Optional TLS encryption with same modes as tunnel server
- Configurable API prefix path
2. **Instance Management**:
- In-memory registry of NodePass instances
- UID-based instance identification
- State tracking for each instance (running, stopped, etc.)
3. **RESTful Endpoints**:
- Standard CRUD operations for instances
- Instance control actions (start, stop, restart)
- Health status reporting
- OpenAPI specification for API documentation
### Instance Lifecycle Management
1. **Instance Creation**:
- URL-based configuration similar to command line
- Dynamic initialization based on instance type
- Parameter validation before instance creation
2. **Instance Control**:
- Start/stop/restart capabilities
- Graceful shutdown with configurable timeout
- Resource cleanup on termination
3. **API Security**:
- TLS encryption options for API connections
- Same security modes as tunnel server
- Certificate management for HTTPS
## Next Steps
- For practical examples of deploying NodePass, see the [examples page](/docs/en/examples.md)
- To fine-tune NodePass for your specific needs, explore the [configuration options](/docs/en/configuration.md)
- If you encounter any issues, check the [troubleshooting guide](/docs/en/troubleshooting.md)

View File

@@ -0,0 +1,111 @@
# Installation Guide
This guide provides detailed instructions for installing NodePass using different methods. Choose the option that best suits your environment and requirements.
## System Requirements
- Go 1.24 or higher (for building from source)
- Network connectivity between server and client endpoints
- Admin privileges may be required for binding to ports below 1024
## Installation Options
### Option 1: Pre-built Binaries
The easiest way to get started with NodePass is to download a pre-built binary for your platform.
1. Visit the [releases page](https://github.com/yosebyte/nodepass/releases) on GitHub
2. Download the appropriate binary for your operating system (Windows, macOS, Linux)
3. Extract the archive if necessary
4. Make the binary executable (Linux/macOS):
```bash
chmod +x nodepass
```
5. Move the binary to a location in your PATH:
- Linux/macOS: `sudo mv nodepass /usr/local/bin/`
- Windows: Add the location to your PATH environment variable
### Option 2: Using Go Install
If you have Go installed on your system, you can use the `go install` command:
```bash
go install github.com/yosebyte/nodepass/cmd/nodepass@latest
```
This command downloads the source code, compiles it, and installs the binary in your Go bin directory (usually `$GOPATH/bin`).
### Option 3: Building from Source
For the latest development version or to customize the build:
```bash
# Clone the repository
git clone https://github.com/yosebyte/nodepass.git
# Navigate to the project directory
cd nodepass
# Build the binary
go build -o nodepass ./cmd/nodepass
# Optional: Install to your GOPATH/bin
go install ./cmd/nodepass
```
### Option 4: Using Container Image
NodePass is available as a container image on GitHub Container Registry, perfect for containerized environments:
```bash
# Pull the container image
docker pull ghcr.io/yosebyte/nodepass:latest
# Run in server mode
docker run -d --name nodepass-server -p 10101:10101 -p 8080:8080 \
ghcr.io/yosebyte/nodepass server://0.0.0.0:10101/0.0.0.0:8080
# Run in client mode
docker run -d --name nodepass-client \
-e MIN_POOL_CAPACITY=32 \
-e MAX_POOL_CAPACITY=512 \
-p 8080:8080 \
ghcr.io/yosebyte/nodepass client://nodepass-server:10101/127.0.0.1:8080
```
### Option 5: Using Management Script (Linux Only)
For Linux systems, we provide a one-click script:
```bash
bash <(curl -sSL https://run.nodepass.eu/np.sh)
```
- This script provides easy-to-use master mode (API mode) installation, configuration, and management functions.
- For details, please refer to [https://github.com/NodePassProject/npsh](https://github.com/NodePassProject/npsh)
## Verifying Installation
After installation, verify that NodePass is correctly installed by checking the version:
```bash
nodepass
```
## Next Steps
Now that you have NodePass installed, you can:
- Learn about its basic [usage](/docs/en/usage.md)
- Explore [configuration options](/docs/en/configuration.md)
- Try out some [examples](/docs/en/examples.md)
## Troubleshooting Installation Issues
If you encounter any issues during installation:
- Ensure your system meets the minimum requirements
- Check that you have the correct permissions to install software
- For Go-related issues, verify your Go installation with `go version`
- For container-related issues, ensure Docker is properly installed and running
- See our [troubleshooting guide](/docs/en/troubleshooting.md) for more help

View File

@@ -0,0 +1,287 @@
# Troubleshooting Guide
This guide helps you diagnose and resolve common issues you might encounter when using NodePass. For each problem, we provide possible causes and step-by-step solutions.
## Connection Issues
### Unable to Establish Tunnel Connection
**Symptoms**: Client cannot connect to the server's tunnel endpoint, or connection is immediately dropped.
**Possible Causes and Solutions**:
1. **Network Connectivity Issues**
- Verify basic connectivity with `ping` or `telnet` to the server address
- Check if the specified port is reachable: `telnet server.example.com 10101`
- Ensure no firewall is blocking the tunnel port (typically 10101)
2. **Server Not Running**
- Verify the NodePass server is running with `ps aux | grep nodepass` on Linux/macOS
- Check server logs for any startup errors
- Try restarting the server process
3. **Incorrect Addressing**
- Double-check the tunnel address format in your client command
- Ensure you're using the correct hostname/IP and port
- If using DNS names, verify they resolve to the correct IP addresses
4. **TLS Configuration Mismatch**
- If server requires TLS but client doesn't support it, connection will fail
- Check server logs for TLS handshake errors
- Ensure certificates are correctly configured if using TLS mode 2
### Data Not Flowing Through the Tunnel
**Symptoms**: Tunnel connection established, but application data isn't reaching the destination.
**Possible Causes and Solutions**:
1. **Target Service Not Running**
- Verify the target service is running on both server and client sides
- Check if you can connect directly to the service locally
2. **Port Conflicts**
- Ensure the target port isn't already in use by another application
- Use `netstat -tuln` to check for port usage
3. **Protocol Mismatch**
- Verify you're tunneling the correct protocol (TCP vs UDP)
- Some applications require specific protocol support
4. **Incorrect Target Address**
- Double-check the target address in both server and client commands
- For server-side targets, ensure they're reachable from the server
- For client-side targets, ensure they're reachable from the client
### Connection Stability Issues
**Symptoms**: Tunnel works initially but disconnects frequently or becomes unresponsive.
**Possible Causes and Solutions**:
1. **Network Instability**
- Check for packet loss or high latency in your network
- Consider a more stable network connection for production deployments
2. **Resource Constraints**
- Monitor CPU and memory usage on both client and server
- Adjust pool parameters if resources are being exhausted (see Performance section)
- Check file descriptor limits with `ulimit -n` on Linux/macOS
3. **Timeout Configuration**
- Adjust `UDP_READ_TIMEOUT` if using UDP with slow response times
- Consider adjusting TCP keepalive settings at the OS level for long-lived connections
4. **Overloaded Server**
- Check server logs for signs of connection overload
- Adjust `MAX_POOL_CAPACITY` and `SEMAPHORE_LIMIT` to handle the load
- Consider scaling horizontally with multiple NodePass instances
## Certificate Issues
### TLS Handshake Failures
**Symptoms**: Connection attempts fail with TLS handshake errors.
**Possible Causes and Solutions**:
1. **Invalid Certificate**
- Verify certificate validity: `openssl x509 -in cert.pem -text -noout`
- Ensure the certificate hasn't expired
- Check that the certificate is issued for the correct domain/IP
2. **Missing or Inaccessible Certificate Files**
- Confirm file paths to certificates and keys are correct
- Verify file permissions allow the NodePass process to read them
- Check for file corruption by opening certificates in a text editor
3. **Certificate Trust Issues**
- If using custom CAs, ensure they are properly trusted
- For self-signed certificates, confirm TLS mode 1 is being used
- For verified certificates, ensure the CA chain is complete
4. **Key Format Problems**
- Ensure private keys are in the correct format (usually PEM)
- Check for passphrase protection on private keys (not supported directly)
### Certificate Renewal Issues
**Symptoms**: After certificate renewal, secure connections start failing.
**Possible Causes and Solutions**:
1. **New Certificate Not Loaded**
- Restart NodePass to force loading of new certificates
- Check if `RELOAD_INTERVAL` is set correctly to automatically detect changes
2. **Certificate Chain Incomplete**
- Ensure the full certificate chain is included in the certificate file
- Verify chain order: your certificate first, then intermediate certificates
3. **Key Mismatch**
- Verify the new certificate matches the private key:
```bash
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
```
- If outputs differ, certificate and key don't match
## Performance Optimization
### High Latency
**Symptoms**: Connections work but have noticeable delays.
**Possible Causes and Solutions**:
1. **Pool Configuration**
- Increase `MIN_POOL_CAPACITY` to have more connections ready
- Decrease `MIN_POOL_INTERVAL` to create connections faster
- Adjust `SEMAPHORE_LIMIT` if connection queue is backing up
2. **Network Path**
- Check for network congestion or high-latency links
- Consider deploying NodePass closer to either the client or server
- Use a traceroute to identify potential bottlenecks
3. **TLS Overhead**
- If extreme low latency is required and security is less critical, consider using TLS mode 0
- For a balance, use TLS mode 1 with session resumption
4. **Resource Contention**
- Ensure the host system has adequate CPU and memory
- Check for other processes competing for resources
- Consider dedicated hosts for high-traffic deployments
### High CPU Usage
**Symptoms**: NodePass process consuming excessive CPU resources.
**Possible Causes and Solutions**:
1. **Pool Thrashing**
- If pool is constantly creating and destroying connections, adjust timings
- Increase `MIN_POOL_INTERVAL` to reduce connection creation frequency
- Find a good balance for `MIN_POOL_CAPACITY` and `MAX_POOL_CAPACITY`
2. **Excessive Logging**
- Reduce log level from debug to info or warn for production use
- Check if logs are being written to a slow device
3. **TLS Overhead**
- TLS handshakes are CPU-intensive; consider session caching
- Use TLS mode 1 instead of mode 2 if certificate validation is less critical
4. **Traffic Volume**
- High throughput can cause CPU saturation
- Consider distributing traffic across multiple NodePass instances
- Vertical scaling (more CPU cores) may be necessary for very high throughput
### Memory Leaks
**Symptoms**: NodePass memory usage grows continuously over time.
**Possible Causes and Solutions**:
1. **Connection Leaks**
- Ensure `SHUTDOWN_TIMEOUT` is sufficient to properly close connections
- Check for proper error handling in custom scripts or management code
- Monitor connection counts with system tools like `netstat`
2. **Pool Size Issues**
- If `MAX_POOL_CAPACITY` is very large, memory usage will be higher
- Monitor actual pool usage vs. configured capacity
- Adjust capacity based on actual concurrent connection needs
3. **Debug Logging**
- Extensive debug logging can consume memory in high-traffic scenarios
- Use appropriate log levels for production environments
## UDP-Specific Issues
### UDP Data Loss
**Symptoms**: UDP packets are not reliably forwarded through the tunnel.
**Possible Causes and Solutions**:
1. **Buffer Size Limitations**
- If UDP packets are large, increase `UDP_DATA_BUF_SIZE`
- Default of 8192 bytes may be too small for some applications
2. **Timeout Issues**
- If responses are slow, increase `UDP_READ_TIMEOUT`
- For applications with variable response times, find an optimal balance
3. **High Packet Rate**
- UDP is handled one datagram at a time; very high rates may cause issues
- Consider increasing pool capacity for high-traffic UDP applications
4. **Protocol Expectations**
- Some UDP applications expect specific behavior regarding packet order or timing
- NodePass provides best-effort forwarding but cannot guarantee UDP properties beyond what the network provides
### UDP Connection Tracking
**Symptoms**: UDP sessions disconnect prematurely or fail to establish.
**Possible Causes and Solutions**:
1. **Connection Mapping**
- Verify client configurations match server expectations
- Check for firewalls that may be timing out UDP session tracking
2. **Application UDP Timeout**
- Some applications have built-in UDP session timeouts
- May need to adjust application-specific keepalive settings
## Master API Issues
### API Accessibility Problems
**Symptoms**: Cannot connect to the master API endpoint.
**Possible Causes and Solutions**:
1. **Endpoint Configuration**
- Verify API address and port in the master command
- Check if the API server is bound to the correct network interface
2. **TLS Configuration**
- If using HTTPS (TLS modes 1 or 2), ensure client tools support TLS
- For testing, use `curl -k` to skip certificate validation
3. **Custom Prefix Issues**
- If using a custom API prefix, ensure it's included in all requests
- Check URL formatting in API clients and scripts
### Instance Management Failures
**Symptoms**: Cannot create, control, or delete instances through the API.
**Possible Causes and Solutions**:
1. **JSON Format Issues**
- Verify request body is valid JSON
- Check for required fields in API requests
2. **URL Parsing Problems**
- Ensure instance URLs are properly formatted and URL-encoded if necessary
- Verify URL parameters use the correct format
3. **Instance State Conflicts**
- Cannot delete running instances without stopping them first
- Check current instance state with GET before performing actions
4. **Permission Issues**
- Ensure the NodePass master has sufficient permissions to create processes
- Check file system permissions for any referenced certificates or keys
## Next Steps
If you encounter issues not covered in this guide:
- Check the [project repository](https://github.com/yosebyte/nodepass) for known issues
- Increase the log level to `debug` for more detailed information
- Review the [How It Works](/docs/en/how-it-works.md) section to better understand internal mechanisms
- Consider joining the community discussion for assistance from other users

283
nodepass/docs/en/usage.md Normal file
View File

@@ -0,0 +1,283 @@
# Usage Instructions
NodePass creates tunnels with an unencrypted TCP control channel and configurable TLS encryption options for data exchange. This guide covers the three operating modes and explains how to use each effectively.
## Command Line Syntax
The general syntax for NodePass commands is:
```bash
nodepass "<core>://<tunnel_addr>/<target_addr>?log=<level>&tls=<mode>&crt=<cert_file>&key=<key_file>&min=<min_pool>&max=<max_pool>"
```
Where:
- `<core>`: Specifies the operating mode (`server`, `client`, or `master`)
- `<tunnel_addr>`: The tunnel endpoint address for control channel communications
- `<target_addr>`: The destination address for business data with bidirectional flow support (or API prefix in master mode)
### Query Parameters
Common query parameters:
- `log=<level>`: Log verbosity level (`debug`, `info`, `warn`, `error`, or `event`)
- `min=<min_pool>`: Minimum connection pool capacity (default: 64, client mode only)
- `max=<max_pool>`: Maximum connection pool capacity (default: 8192, client mode only)
TLS-related parameters (server/master modes only):
- `tls=<mode>`: TLS security level for data channels (`0`, `1`, or `2`)
- `crt=<cert_file>`: Path to certificate file (when `tls=2`)
- `key=<key_file>`: Path to private key file (when `tls=2`)
## Operating Modes
NodePass offers three complementary operating modes to suit various deployment scenarios.
### Server Mode
Server mode establishes tunnel control channels and supports bidirectional data flow forwarding.
```bash
nodepass "server://<tunnel_addr>/<target_addr>?log=<level>&tls=<mode>&crt=<cert_file>&key=<key_file>"
```
#### Parameters
- `tunnel_addr`: Address for the TCP tunnel endpoint (control channel) that clients will connect to (e.g., 10.1.0.1:10101)
- `target_addr`: The destination address for business data with bidirectional flow support (e.g., 10.1.0.1:8080)
- `log`: Log level (debug, info, warn, error, event)
- `tls`: TLS encryption mode for the target data channel (0, 1, 2)
- `0`: No TLS encryption (plain TCP/UDP)
- `1`: Self-signed certificate (automatically generated)
- `2`: Custom certificate (requires `crt` and `key` parameters)
- `crt`: Path to certificate file (required when `tls=2`)
- `key`: Path to private key file (required when `tls=2`)
#### How Server Mode Works
In server mode, NodePass supports two data flow directions:
**Mode 1: Server Receives Traffic** (target_addr is local address)
1. Listens for TCP tunnel connections (control channel) on `tunnel_addr`
2. Listens for incoming TCP and UDP traffic on `target_addr`
3. When a connection arrives at `target_addr`, it signals the connected client through the control channel
4. Creates a data channel for each connection with the specified TLS encryption level
**Mode 2: Server Sends Traffic** (target_addr is remote address)
1. Listens for TCP tunnel connections (control channel) on `tunnel_addr`
2. Waits for clients to listen locally and receive connections through the tunnel
3. Establishes connections to remote `target_addr` and forwards data
#### Examples
```bash
# No TLS encryption for data channel - Server receives mode
nodepass "server://10.1.0.1:10101/10.1.0.1:8080?log=debug&tls=0"
# Self-signed certificate (auto-generated) - Server sends mode
nodepass "server://10.1.0.1:10101/192.168.1.100:8080?log=debug&tls=1"
# Custom domain certificate - Server receives mode
nodepass "server://10.1.0.1:10101/10.1.0.1:8080?log=debug&tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
### Client Mode
Client mode connects to a NodePass server and supports bidirectional data flow forwarding.
```bash
nodepass "client://<tunnel_addr>/<target_addr>?log=<level>&min=<min_pool>&max=<max_pool>"
```
#### Parameters
- `tunnel_addr`: Address of the NodePass server's tunnel endpoint to connect to (e.g., 10.1.0.1:10101)
- `target_addr`: The destination address for business data with bidirectional flow support (e.g., 127.0.0.1:8080)
- `log`: Log level (debug, info, warn, error, event)
- `min`: Minimum connection pool capacity (default: 64)
- `max`: Maximum connection pool capacity (default: 8192)
#### How Client Mode Works
In client mode, NodePass supports three operating modes:
**Mode 1: Client Single-End Forwarding** (when tunnel address is local)
1. Listens for TCP and UDP connections on the local tunnel address
2. Uses connection pooling technology to pre-establish TCP connections to target address, eliminating connection latency
3. Directly forwards received traffic to the target address with high performance
4. No handshake with server required, enables point-to-point direct forwarding
5. Suitable for local proxy and simple forwarding scenarios
**Mode 2: Client Receives Traffic** (when server sends traffic)
1. Connects to the server's TCP tunnel endpoint (control channel)
2. Listens locally and waits for connections through the tunnel
3. Establishes connections to local `target_addr` and forwards data
**Mode 3: Client Sends Traffic** (when server receives traffic)
1. Connects to the server's TCP tunnel endpoint (control channel)
2. Listens for signals from the server through this control channel
3. When a signal is received, establishes a data connection with the TLS security level specified by the server
4. Creates a connection to `target_addr` and forwards traffic
#### Examples
```bash
# Client single-end forwarding mode - Local proxy listening on port 1080, forwarding to target server
nodepass client://127.0.0.1:1080/target.example.com:8080?log=debug
# Connect to a NodePass server and adopt its TLS security policy - Client sends mode
nodepass client://server.example.com:10101/127.0.0.1:8080
# Connect with debug logging - Client receives mode
nodepass client://server.example.com:10101/192.168.1.100:8080?log=debug
# Custom connection pool capacity - High performance configuration
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=128&max=4096"
# Resource-constrained configuration - Small connection pool
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=16&max=512&log=info"
```
### Master Mode (API)
Master mode runs a RESTful API server for centralized management of NodePass instances.
```bash
nodepass "master://<api_addr>[<prefix>]?log=<level>&tls=<mode>&crt=<cert_file>&key=<key_file>"
```
#### Parameters
- `api_addr`: Address where the API service will listen (e.g., 0.0.0.0:9090)
- `prefix`: Optional API prefix path (e.g., /management). Default is `/api`
- `log`: Log level (debug, info, warn, error, event)
- `tls`: TLS encryption mode for the API service (0, 1, 2)
- `0`: No TLS encryption (HTTP)
- `1`: Self-signed certificate (HTTPS with auto-generated cert)
- `2`: Custom certificate (HTTPS with provided cert)
- `crt`: Path to certificate file (required when `tls=2`)
- `key`: Path to private key file (required when `tls=2`)
#### How Master Mode Works
In master mode, NodePass:
1. Runs a RESTful API server that allows dynamic management of NodePass instances
2. Provides endpoints for creating, starting, stopping, and monitoring client and server instances
3. Includes Swagger UI for easy API exploration at `{prefix}/v1/docs`
4. Automatically inherits TLS and logging settings for instances created through the API
#### API Endpoints
All endpoints are relative to the configured prefix (default: `/api`):
- `GET {prefix}/v1/instances` - List all instances
- `POST {prefix}/v1/instances` - Create a new instance with JSON body: `{"url": "server://0.0.0.0:10101/0.0.0.0:8080"}`
- `GET {prefix}/v1/instances/{id}` - Get instance details
- `PATCH {prefix}/v1/instances/{id}` - Update instance with JSON body: `{"action": "start|stop|restart"}`
- `DELETE {prefix}/v1/instances/{id}` - Delete instance
- `GET {prefix}/v1/openapi.json` - OpenAPI specification
- `GET {prefix}/v1/docs` - Swagger UI documentation
#### Examples
```bash
# Start master with HTTP using default API prefix (/api)
nodepass "master://0.0.0.0:9090?log=info"
# Start master with custom API prefix (/management)
nodepass "master://0.0.0.0:9090/management?log=info"
# Start master with HTTPS (self-signed certificate)
nodepass "master://0.0.0.0:9090/admin?log=info&tls=1"
# Start master with HTTPS (custom certificate)
nodepass "master://0.0.0.0:9090?log=info&tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
## Managing NodePass Instances
### Creating and Managing via API
You can use standard HTTP requests to manage NodePass instances through the master API:
```bash
# Create and manage instances via API (using default prefix)
curl -X POST http://localhost:9090/api/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
# Using custom prefix
curl -X POST http://localhost:9090/admin/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
# List all running instances
curl http://localhost:9090/api/v1/instances
# Control an instance (replace {id} with actual instance ID)
curl -X PUT http://localhost:9090/api/v1/instances/{id} \
-H "Content-Type: application/json" \
-d '{"action":"restart"}'
```
## Bidirectional Data Flow Explanation
NodePass supports flexible bidirectional data flow configuration:
### Client Single-End Forwarding Mode
- **Client**: Listens on local tunnel address, uses connection pooling technology to directly forward to target address
- **Connection Pool Optimization**: Pre-establishes TCP connections, eliminates connection latency, provides high-performance forwarding
- **No Server Required**: Operates independently without server handshake
- **Use Case**: Local proxy, simple port forwarding, testing environments, high-performance forwarding
### Server Receives Mode (dataFlow: "-")
- **Server**: Listens for incoming connections on target_addr, forwards through tunnel to client
- **Client**: Connects to local target_addr to provide services
- **Use Case**: Expose internal services to external access
### Server Sends Mode (dataFlow: "+")
- **Server**: Connects to remote target_addr to fetch data, sends through tunnel to client
- **Client**: Listens locally to receive connections from server
- **Use Case**: Access remote services through tunnel proxy
The system automatically selects the appropriate operation mode based on tunnel and target addresses:
- If the client's tunnel address is a local address, enables single-end forwarding mode
- If target address is a local address, uses Server Receives Mode
- If target address is a remote address, uses Server Sends Mode
## Tunnel Key
NodePass uses tunnel keys to authenticate connections between clients and servers. The key can be specified in two ways:
### Key Derivation Rules
1. **Explicit Key**: Specify the username part in the URL as the key
```bash
# Use "mypassword" as the tunnel key
nodepass server://mypassword@10.1.0.1:10101/10.1.0.1:8080
nodepass client://mypassword@10.1.0.1:10101/127.0.0.1:8080
```
2. **Port-Derived Key**: If no username is specified, the system uses the hexadecimal value of the port number as the key
```bash
# Port 10101's hexadecimal value "2775" will be used as the tunnel key
nodepass server://10.1.0.1:10101/10.1.0.1:8080
nodepass client://10.1.0.1:10101/127.0.0.1:8080
```
### Handshake Process
The handshake process between client and server is as follows:
1. **Client Connection**: Client connects to the server's tunnel address
2. **Key Authentication**: Client sends XOR-encrypted tunnel key
3. **Server Verification**: Server decrypts and verifies if the key matches
4. **Configuration Sync**: Upon successful verification, server sends tunnel configuration (including TLS mode)
5. **Connection Established**: Handshake complete, data transmission begins
This design ensures that only clients with the correct key can establish tunnel connections.
## Next Steps
- Learn about [configuration options](/docs/en/configuration.md) to fine-tune NodePass
- Explore [examples](/docs/en/examples.md) of common deployment scenarios
- Understand [how NodePass works](/docs/en/how-it-works.md) under the hood
- Check the [troubleshooting guide](/docs/en/troubleshooting.md) if you encounter issues

1044
nodepass/docs/zh/api.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
# 配置选项
NodePass采用极简方法进行配置所有设置都通过命令行参数和环境变量指定。本指南说明所有可用的配置选项并为各种部署场景提供建议。
## 日志级别
NodePass提供五种日志详细级别控制显示的信息量
- `debug`:详细调试信息 - 显示所有操作和连接
- `info`:一般操作信息(默认) - 显示启动、关闭和关键事件
- `warn`:警告条件 - 仅显示不影响核心功能的潜在问题
- `error`:错误条件 - 仅显示影响功能的问题
- `event`:事件记录 - 显示重要的操作事件和流量统计
您可以在命令URL中设置日志级别
```bash
nodepass server://0.0.0.0:10101/0.0.0.0:8080?log=debug
```
## TLS加密模式
对于服务器和主控模式NodePass为数据通道提供三种TLS安全级别
- **模式0**无TLS加密明文TCP/UDP
- 最快性能,无开销
- 数据通道无安全保护(仅在受信任网络中使用)
- **模式1**:自签名证书(自动生成)
- 设置简单的良好安全性
- 证书自动生成且不验证
- 防止被动窃听
- **模式2**:自定义证书(需要`crt``key`参数)
- 具有证书验证的最高安全性
- 需要提供证书和密钥文件
- 适用于生产环境
TLS模式1示例自签名
```bash
nodepass server://0.0.0.0:10101/0.0.0.0:8080?tls=1
```
TLS模式2示例自定义证书
```bash
nodepass "server://0.0.0.0:10101/0.0.0.0:8080?tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
## 连接池容量参数
连接池容量可以通过URL查询参数进行配置
- `min`: 最小连接池容量(默认: 64
- `max`: 最大连接池容量(默认: 8192
示例:
```bash
# 设置最小连接池为32最大为4096
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=32&max=4096"
```
## 环境变量
可以使用环境变量微调NodePass行为。以下是所有可用变量的完整列表包括其描述、默认值以及不同场景的推荐设置。
| 变量 | 描述 | 默认值 | 示例 |
|----------|-------------|---------|---------|
| `NP_SEMAPHORE_LIMIT` | 最大并发连接数 | 1024 | `export NP_SEMAPHORE_LIMIT=2048` |
| `NP_UDP_DATA_BUF_SIZE` | UDP数据包缓冲区大小 | 8192 | `export NP_UDP_DATA_BUF_SIZE=16384` |
| `NP_UDP_READ_TIMEOUT` | UDP读取操作超时 | 20s | `export NP_UDP_READ_TIMEOUT=30s` |
| `NP_UDP_DIAL_TIMEOUT` | UDP连接建立超时 | 20s | `export NP_UDP_DIAL_TIMEOUT=30s` |
| `NP_TCP_READ_TIMEOUT` | TCP读取操作超时 | 20s | `export NP_TCP_READ_TIMEOUT=30s` |
| `NP_TCP_DIAL_TIMEOUT` | TCP连接建立超时 | 20s | `export NP_TCP_DIAL_TIMEOUT=30s` |
| `NP_MIN_POOL_INTERVAL` | 连接创建之间的最小间隔 | 1s | `export NP_MIN_POOL_INTERVAL=500ms` |
| `NP_MAX_POOL_INTERVAL` | 连接创建之间的最大间隔 | 5s | `export NP_MAX_POOL_INTERVAL=3s` |
| `NP_REPORT_INTERVAL` | 健康检查报告间隔 | 5s | `export NP_REPORT_INTERVAL=10s` |
| `NP_SERVICE_COOLDOWN` | 重启尝试前的冷却期 | 3s | `export NP_SERVICE_COOLDOWN=5s` |
| `NP_SHUTDOWN_TIMEOUT` | 优雅关闭超时 | 5s | `export NP_SHUTDOWN_TIMEOUT=10s` |
| `NP_RELOAD_INTERVAL` | 证书/连接池重载间隔 | 1h | `export NP_RELOAD_INTERVAL=30m` |
### 连接池调优
连接池参数是性能调优中的重要设置:
#### 池容量设置
- `min` (URL参数):确保最小可用连接数
- 太低:流量高峰期延迟增加,因为必须建立新连接
- 太高:维护空闲连接浪费资源
- 推荐起点平均并发连接的25-50%
- `max` (URL参数):防止过度资源消耗,同时处理峰值负载
- 太低:流量高峰期连接失败
- 太高:潜在资源耗尽影响系统稳定性
- 推荐起点峰值并发连接的150-200%
#### 池间隔设置
- `NP_MIN_POOL_INTERVAL`:控制连接创建尝试之间的最小时间
- 太低:可能以连接尝试压垮网络
- 推荐范围根据网络延迟500ms-2s
- `NP_MAX_POOL_INTERVAL`:控制连接创建尝试之间的最大时间
- 太高:流量高峰期可能导致池耗尽
- 推荐范围根据预期流量模式3s-10s
#### 连接管理
- `NP_SEMAPHORE_LIMIT`:控制最大并发隧道操作数
- 太低:流量高峰期拒绝连接
- 太高太多并发goroutine可能导致内存压力
- 推荐范围大多数应用1000-5000高吞吐量场景更高
### UDP设置
对于严重依赖UDP流量的应用
- `NP_UDP_DATA_BUF_SIZE`UDP数据包缓冲区大小
- 对于发送大UDP数据包的应用增加此值
- 默认值(8192)适用于大多数情况
- 考虑为媒体流或游戏服务器增加到16384或更高
- `NP_UDP_READ_TIMEOUT`UDP读取操作超时
- 对于高延迟网络或响应时间慢的应用增加此值
- 对于需要快速故障转移的低延迟应用减少此值
- `NP_UDP_DIAL_TIMEOUT`UDP拨号超时
- 对于高延迟网络增加此值
- 对于需要快速连接的应用减少此值
### TCP设置
对于TCP连接的优化
- `NP_TCP_READ_TIMEOUT`TCP读取操作超时
- 对于高延迟网络或响应慢的服务器增加此值
- 对于需要快速检测断开连接的应用降低此值
- 影响数据传输过程中的等待时间
- `NP_TCP_DIAL_TIMEOUT`TCP连接建立超时
- 对于网络条件不稳定的环境增加此值
- 对于需要快速判断连接成功与否的应用减少此值
- 影响初始连接建立阶段
### 服务管理设置
- `NP_REPORT_INTERVAL`:控制健康状态报告频率
- 较低值提供更频繁的更新但增加日志量
- 较高值减少日志输出但提供较少的即时可见性
- `NP_RELOAD_INTERVAL`控制检查TLS证书变更的频率
- 较低值更快检测证书变更但增加文件系统操作
- 较高值减少开销但延迟检测证书更新
- `NP_SERVICE_COOLDOWN`:尝试服务重启前的等待时间
- 较低值更快尝试恢复但可能在持续性问题情况下导致抖动
- 较高值提供更多稳定性但从瞬态问题中恢复较慢
- `NP_SHUTDOWN_TIMEOUT`:关闭期间等待连接关闭的最长时间
- 较低值确保更快关闭但可能中断活动连接
- 较高值允许连接有更多时间完成但延迟关闭
## 推荐配置
以下是常见场景的推荐环境变量配置:
### 高吞吐量配置
对于需要最大吞吐量的应用(如媒体流、文件传输):
URL参数
```bash
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=128&max=8192"
```
环境变量:
```bash
export NP_MIN_POOL_INTERVAL=500ms
export NP_MAX_POOL_INTERVAL=3s
export NP_SEMAPHORE_LIMIT=8192
export NP_UDP_DATA_BUF_SIZE=32768
export NP_REPORT_INTERVAL=10s
```
### 低延迟配置
对于需要最小延迟的应用(如游戏、金融交易):
URL参数
```bash
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=256&max=4096"
```
环境变量:
```bash
export NP_MIN_POOL_INTERVAL=100ms
export NP_MAX_POOL_INTERVAL=1s
export NP_SEMAPHORE_LIMIT=4096
export NP_UDP_READ_TIMEOUT=5s
export NP_REPORT_INTERVAL=1s
```
### 资源受限配置
对于在资源有限系统上的部署如IoT设备、小型VPS
URL参数
```bash
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=16&max=512"
```
环境变量:
```bash
export NP_MIN_POOL_INTERVAL=2s
export NP_MAX_POOL_INTERVAL=10s
export NP_SEMAPHORE_LIMIT=512
export NP_REPORT_INTERVAL=30s
export NP_SHUTDOWN_TIMEOUT=3s
```
## 下一步
- 查看[使用说明](/docs/zh/usage.md)了解基本操作命令
- 探索[使用示例](/docs/zh/examples.md)了解部署模式
- 了解[NodePass工作原理](/docs/zh/how-it-works.md)以优化配置
- 如果遇到问题,请查看[故障排除指南](/docs/zh/troubleshooting.md)

View File

@@ -0,0 +1,261 @@
# 使用示例
本页提供了NodePass在各种部署场景中的实际示例。这些示例涵盖了常见用例可以根据您的具体需求进行调整。
## 基本服务器设置与TLS选项
### 示例1无TLS加密
当速度比安全性更重要时(例如,在受信任网络中):
```bash
nodepass "server://0.0.0.0:10101/127.0.0.1:8080?log=debug&tls=0"
```
这会启动一个NodePass服务器
- 在所有接口的10101端口上监听隧道连接
- 将流量转发到localhost:8080
- 使用debug日志记录详细信息
- 不对数据通道使用加密(最快性能)
### 示例2自签名证书
为了平衡安全性和易于设置(推荐大多数情况):
```bash
nodepass "server://0.0.0.0:10101/127.0.0.1:8080?log=debug&tls=1"
```
此配置:
- 自动生成自签名证书
- 提供加密而无需证书管理
- 保护数据流量免受被动窃听
- 适用于内部或测试环境
### 示例3自定义域名证书
对于需要验证证书的生产环境:
```bash
nodepass "server://0.0.0.0:10101/127.0.0.1:8080?log=debug&tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
这一设置:
- 使用您提供的TLS证书和私钥
- 提供具有证书验证的最高安全级别
- 适合生产环境和面向公众的服务
- 允许客户端验证服务器的身份
## 连接到NodePass服务器
### 示例4基本客户端连接
使用默认设置连接到NodePass服务器
```bash
nodepass client://server.example.com:10101/127.0.0.1:8080
```
此客户端:
- 连接到server.example.com:10101的NodePass服务器
- 将接收到的流量转发到localhost:8080
- 自动采用服务器的TLS安全策略
- 使用默认的info日志级别
### 示例5带调试日志的客户端
用于故障排除连接问题:
```bash
nodepass client://server.example.com:10101/127.0.0.1:8080?log=debug
```
这启用了详细输出,有助于识别:
- 连接建立问题
- 信号处理
- 数据传输详情
- 错误情况
## 通过防火墙访问数据库
### 示例6数据库隧道
启用对防火墙后的数据库服务器的安全访问:
```bash
# 服务器端(位于安全网络外部)使用TLS加密
nodepass server://:10101/127.0.0.1:5432?tls=1
# 客户端(位于防火墙内部)
nodepass client://server.example.com:10101/127.0.0.1:5432
```
此配置:
- 创建到PostgreSQL数据库端口5432的加密隧道
- 允许安全访问数据库而不直接将其暴露于互联网
- 使用自签名证书加密所有数据库流量
- 使远程数据库在客户端上显示为本地服务
## 安全的微服务通信
### 示例7服务间通信
启用微服务之间的安全通信:
```bash
# 服务A(消费API)使用自定义证书
nodepass "server://0.0.0.0:10101/127.0.0.1:8081?log=warn&tls=2&crt=/path/to/service-a.crt&key=/path/to/service-a.key"
# 服务B(提供API)
nodepass client://service-a:10101/127.0.0.1:8082
```
此设置:
- 在两个微服务之间创建安全通道
- 使用自定义证书进行服务身份验证
- 将日志限制为仅警告和错误
- 使服务A的API在服务B上显示为本地服务
## 物联网设备管理
### 示例8物联网网关
创建物联网设备的中央访问点:
```bash
# 中央管理服务器
nodepass "server://0.0.0.0:10101/127.0.0.1:8888?log=info&tls=1"
# 物联网设备
nodepass client://mgmt.example.com:10101/127.0.0.1:80
```
此配置:
- 使分布式物联网设备能够安全连接到中央服务器
- 使用自签名证书提供足够的安全性
- 允许嵌入式设备安全地暴露其本地Web界面
- 通过单一端点集中设备管理
## 多环境开发
### 示例9开发环境访问
通过隧道访问不同的开发环境:
```bash
# 生产API访问隧道
nodepass client://tunnel.example.com:10101/127.0.0.1:3443
# 开发环境
nodepass server://tunnel.example.com:10101/127.0.0.1:3000
# 测试环境
nodepass "server://tunnel.example.com:10101/127.0.0.1:3001?log=warn&tls=1"
```
此设置:
- 创建对多个环境(生产、开发、测试)的安全访问
- 根据环境敏感性使用不同级别的日志记录
- 使开发人员能够访问环境而无需直接网络暴露
- 将远程服务映射到不同的本地端口,便于识别
## 容器部署
### 示例10容器化NodePass
在Docker环境中部署NodePass
```bash
# 为容器创建网络
docker network create nodepass-net
# 部署使用自签名证书的NodePass服务器
docker run -d --name nodepass-server \
--network nodepass-net \
-p 10101:10101 \
ghcr.io/yosebyte/nodepass "server://0.0.0.0:10101/web-service:80?log=info&tls=1"
# 部署Web服务作为目标
docker run -d --name web-service \
--network nodepass-net \
nginx:alpine
# 部署NodePass客户端
docker run -d --name nodepass-client \
-p 8080:8080 \
ghcr.io/yosebyte/nodepass client://nodepass-server:10101/127.0.0.1:8080?log=info
# 通过http://localhost:8080访问Web服务
```
此配置:
- 在服务之间创建容器化隧道
- 使用Docker网络连接容器
- 仅向主机公开必要端口
- 提供对内部Web服务的安全访问
## 主控API管理
### 示例11集中管理
为多个NodePass实例设置中央控制器
```bash
# 使用自签名证书启动主控API服务
nodepass "master://0.0.0.0:9090?log=info&tls=1"
```
然后您可以通过API调用管理实例
```bash
# 创建服务器实例
curl -X POST http://localhost:9090/api/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
# 创建客户端实例
curl -X POST http://localhost:9090/api/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"client://localhost:10101/127.0.0.1:8081"}'
# 列出所有运行实例
curl http://localhost:9090/api/v1/instances
# 控制实例用实际实例ID替换{id}
curl -X PUT http://localhost:9090/api/v1/instances/{id} \
-H "Content-Type: application/json" \
-d '{"action":"restart"}'
```
此设置:
- 为所有NodePass实例提供中央管理界面
- 允许动态创建和控制隧道
- 提供用于自动化和集成的RESTful API
- 包含内置的Swagger UI位于http://localhost:9090/api/v1/docs
### 示例12自定义API前缀
为主控模式使用自定义API前缀
```bash
# 使用自定义API前缀启动
nodepass "master://0.0.0.0:9090/admin?log=info&tls=1"
# 使用自定义前缀创建实例
curl -X POST http://localhost:9090/admin/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
```
这允许:
- 与现有API网关集成
- 用于安全或组织目的的自定义URL路径
- 在http://localhost:9090/admin/v1/docs访问Swagger UI
## 下一步
现在您已经了解了各种使用示例,您可能想要:
- 了解[配置选项](/docs/zh/configuration.md)以进行微调
- 理解NodePass内部[工作原理](/docs/zh/how-it-works.md)
- 查看[故障排除指南](/docs/zh/troubleshooting.md)了解常见问题

View File

@@ -0,0 +1,313 @@
# NodePass 工作原理
本页解释了 NodePass 的内部架构和数据流机制,提供了不同组件如何交互以创建高效、安全的隧道的深入见解。
## 架构概述
NodePass 创建了一个具有独立控制和数据通道的网络架构:
1. **控制通道(隧道)**
- 客户端和服务器之间的未加密 TCP 连接
- 专门用于信号传输和协调
- 在隧道生命周期内维持持久连接
2. **数据通道(目标)**
- 可配置的 TLS 加密选项:
- **模式 0**:未加密数据传输(最快,安全性最低)
- **模式 1**:自签名证书加密(良好安全性,无验证)
- **模式 2**:验证证书加密(最高安全性,需要有效证书)
- 按需为每个连接或数据报创建
- 用于实际应用数据传输
3. **服务端模式操作**
- 在隧道端点监听控制连接
- 当流量到达目标端点时,通过控制通道向客户端发送信号
- 在需要时使用指定的 TLS 模式建立数据通道
- 支持双向数据流:可以从服务端或客户端发起连接
4. **客户端模式操作**
- 连接到服务端的控制通道
- 监听指示传入连接的信号
- 使用服务端指定的 TLS 安全级别创建数据连接
- 在安全通道和本地目标之间转发数据
- 支持双向数据流:根据目标地址自动选择数据流方向
5. **客户端单端转发模式**
- 当隧道地址为本地地址时如127.0.0.1)自动启用
- 客户端直接在本地监听端口,无需服务端的控制通道协调
- 对于TCP连接使用连接池技术显著提高转发性能
- 适用于纯本地转发场景,减少网络开销和延迟
- 支持TCP和UDP协议的高性能单端转发
5. **协议支持**
- **TCP**:具有持久连接的全双工流式传输,在客户端单端转发模式下支持连接池优化
- **UDP**:具有可配置缓冲区大小和超时的数据报转发
## 数据传输流
NodePass 通过其隧道架构建立双向数据流,支持 TCP 和 UDP 协议。系统支持三种数据流模式:
### 数据流模式说明
- **服务端接收模式dataFlow: "-"**:服务端在目标地址监听,客户端在本地监听,数据从目标地址流向客户端本地
- **服务端发送模式dataFlow: "+"**:服务端连接到远程目标地址,客户端在本地监听,数据从客户端本地流向远程目标
- **客户端单端转发模式**:客户端在本地直接监听并转发到目标地址,无需服务端协调,使用连接池技术实现高性能转发
数据流模式根据隧道地址和目标地址自动确定:
- 如果隧道地址是本地地址localhost、127.0.0.1等),启用客户端单端转发模式
- 如果目标地址是本地地址,使用服务端接收模式
- 如果目标地址是远程地址,使用服务端发送模式
### 服务端流程(服务端接收模式)
1. **连接初始化**
```
[目标客户端] → [目标监听器] → [服务器:目标连接已创建]
```
- 对于 TCP客户端建立到目标监听器的持久连接
- 对于 UDP服务器在绑定到目标地址的 UDP 套接字上接收数据报
2. **信号生成**
```
[服务端] → [生成唯一连接 ID] → [通过未加密的 TCP 隧道向客户端发送信号]
```
- 对于 TCP生成 `//<connection_id>#1` 信号
- 对于 UDP生成 `//<connection_id>#2` 信号
3. **连接准备**
```
[服务端] → [在池中创建具有配置的 TLS 模式的远程连接] → [等待客户端连接]
```
- 两种协议都使用相同的具有唯一连接 ID 的连接池机制
- 根据指定模式0、1 或 2应用 TLS 配置
4. **数据交换**
```
[目标连接] ⟷ [交换/传输] ⟷ [远程连接]
```
- 对于 TCP使用 `conn.DataExchange()` 进行持续的双向数据流传输
- 对于 UDP使用可配置的缓冲区大小转发单个数据报
### 客户端流程
1. **信号接收**
```
[客户端] → [从 TCP 隧道读取信号] → [解析连接 ID]
```
- 客户端根据 URL 方案区分 TCP 和 UDP 信号
2. **连接建立**
```
[客户端] → [从池中检索连接] → [连接到远程端点]
```
- 此阶段的连接管理与协议无关
3. **本地连接**
```
[客户端] → [连接到本地目标] → [建立本地连接]
```
- 对于 TCP建立到本地目标的持久 TCP 连接
- 对于 UDP创建用于与本地目标交换数据报的 UDP 套接字
4. **数据交换**
```
[远程连接] ⟷ [交换/传输] ⟷ [本地目标连接]
```
- 对于 TCP使用 `conn.DataExchange()` 进行持续的双向数据流传输
- 对于 UDP读取单个数据报转发它使用超时等待响应然后返回响应
### 客户端单端转发流程
1. **模式识别**
```
[客户端] → [检测隧道地址为本地地址] → [启用单端转发模式]
```
- 自动检测隧道地址是否为localhost、127.0.0.1等本地地址
- 启用单端转发模式,跳过服务端控制通道建立
2. **本地监听**
```
[客户端] → [在隧道端口启动监听器] → [等待本地连接]
```
- 直接在指定的隧道端口启动TCP或UDP监听器
- 无需连接到远程服务端,实现零延迟启动
3. **连接池初始化**仅TCP
```
[客户端] → [初始化目标连接池] → [预建立连接到目标地址]
```
- 为TCP转发创建高性能连接池
- 预先建立多个到目标地址的连接,显著减少连接建立延迟
- 连接池大小可根据并发需求动态调整
4. **高性能转发**
```
[本地连接] → [从连接池获取目标连接] → [直接数据交换] → [连接复用或释放]
```
- 对于TCP从连接池中快速获取预建立的目标连接进行高效数据交换
- 对于UDP直接转发数据报到目标地址无需连接池
- 优化的数据路径,最小化转发开销和延迟
### 特定协议特性
- **TCP 交换**
- 用于全双工通信的持久连接
- 连接终止前的持续数据流传输
- 具有自动重连的错误处理
- **客户端单端转发优化**:通过连接池技术预建立连接,显著减少连接建立延迟
- **UDP 交换**
- 具有可配置缓冲区大小的一次性数据报转发 (`UDP_DATA_BUF_SIZE`)
- 响应等待的读取超时控制 (`UDP_READ_TIMEOUT`)
- 针对低延迟、无状态通信进行了优化
- **客户端单端转发优化**:直接转发机制,无需连接池,实现最低延迟
## 信号通信机制
NodePass 通过 TCP 隧道使用复杂的基于 URL 的信号协议:
### 信号类型
1. **隧道信号**
- 格式:`#<tls>`
- 目的:通知客户端 TLS 代号
- 时机:在隧道握手时发送
2. **TCP 启动信号**
- 格式:`//<connection_id>#1`
- 目的:请求客户端为特定 ID 建立 TCP 连接
- 时机:当接收到目标服务的新 TCP 连接时发送
3. **UDP 启动信号**
- 格式:`//<connection_id>#2`
- 目的:请求客户端处理特定 ID 的 UDP 流量
- 时机:当在目标端口接收到 UDP 数据时发送
### 信号流程
1. **信号生成**
- 服务端为特定事件创建 URL 格式的信号
- 信号以换行符终止,以便正确解析
2. **信号传输**
- 服务端将信号写入 TCP 隧道连接
- 使用互斥锁防止对隧道的并发写入
3. **信号接收**
- 客户端使用缓冲读取器从隧道读取信号
- 信号被修剪并解析为 URL 格式
4. **信号处理**
- 客户端将有效信号放入缓冲通道 (signalChan)
- 专用 goroutine 处理来自通道的信号
- 信号量模式防止信号溢出
5. **信号执行**
- 远程信号更新客户端的远程地址配置
- 启动信号触发 `clientOnce()` 方法建立连接
### 信号弹性
- 具有可配置容量的缓冲通道防止在高负载下信号丢失
- 信号量实现确保受控并发
- 对格式错误或意外信号的错误处理
## 连接池架构
NodePass 实现了一个高效的连接池系统来管理网络连接:
### 池设计
1. **池类型**
- **客户端池**:预先建立到远程端点的连接
- **服务器池**:管理来自客户端的传入连接
2. **池组件**
- **连接存储**:线程安全的连接 ID 到 net.Conn 对象的映射
- **ID 通道**:用于可用连接 ID 的缓冲通道
- **容量管理**:基于使用模式的动态调整
- **间隔控制**:连接创建之间的基于时间的限流
- **连接工厂**:可定制的连接创建函数
### 连接生命周期
1. **连接创建**
- 连接创建数量不超过配置的容量
- 每个连接都分配一个唯一 ID
- ID 和连接存储在池中
2. **连接获取**
- 客户端使用连接 ID 检索连接
- 服务端从池中检索下一个可用连接
- 在返回前验证连接
3. **连接使用**
- 获取时从池中移除连接
- 用于端点之间的数据交换
- 无连接重用(一次性使用模型)
4. **连接终止**
- 使用后关闭连接
- 正确释放资源
- 错误处理确保干净终止
### 池管理
1. **容量控制**
- `MIN_POOL_CAPACITY`:确保最小可用连接数
- `MAX_POOL_CAPACITY`:防止过度资源消耗
- 基于需求模式的动态缩放
2. **间隔控制**
- `MIN_POOL_INTERVAL`:连接创建尝试之间的最小时间
- `MAX_POOL_INTERVAL`:连接创建尝试之间的最大时间
- 自适应基于时间的限流以优化资源使用
3. **动态池适应**
连接池采用双重自适应机制以确保最佳性能:
**A. 容量调整**
- 池容量根据实时使用模式动态调整
- 如果连接创建成功率低(<20%),容量减少以最小化资源浪费
- 如果连接创建成功率高(>80%),容量增加以适应更高的流量
- 渐进缩放防止振荡并提供稳定性
- 遵守配置的最小和最大容量边界
**B. 间隔调整**
- 创建间隔根据池空闲连接数调整
- 当空闲连接较少(容量的<20%)时,间隔向最小间隔减少
- 当空闲连接较多(容量的>80%)时,间隔向最大间隔增加
- 防止在低需求期间压垮网络资源
- 在池耗尽的高需求期间加速连接创建
## 主控API架构
在主控模式下NodePass提供RESTful API进行集中管理
### API组件
1. **HTTP/HTTPS服务器**
- 在配置的地址和端口上监听
- 可选的TLS加密与隧道服务器使用相同模式
- 可配置的API前缀路径
2. **实例管理**
- NodePass实例的内存注册表
- 基于UID的实例标识
- 每个实例的状态跟踪(运行中、已停止等)
3. **RESTful端点**
- 实例的标准CRUD操作
- 实例控制操作(启动、停止、重启)
- 健康状态报告
- API文档的OpenAPI规范
### 实例生命周期管理
1. **实例创建**
- 基于URL的配置类似于命令行
- 基于实例类型的动态初始化
- 实例创建前的参数验证
2. **实例控制**
- 启动/停止/重启能力
- 可配置超时的优雅关闭
- 终止时的资源清理
3. **API安全**
- API连接的TLS加密选项
- 与隧道服务端相同的安全模式
- HTTPS的证书管理
## 下一步
- 有关部署NodePass的实际示例请参阅[示例页面](/docs/zh/examples.md)
- 要根据您的特定需求优化NodePass请探索[配置选项](/docs/zh/configuration.md)
- 如果遇到任何问题,请查看[故障排除指南](/docs/zh/troubleshooting.md)

View File

@@ -0,0 +1,111 @@
# 安装指南
本指南提供了使用不同方法安装 NodePass 的详细说明。选择最适合您环境和需求的安装方式。
## 系统要求
- Go 1.24或更高版本(从源代码构建时需要)
- 服务器和客户端端点之间的网络连接
- 绑定1024以下端口可能需要管理员权限
## 安装方法
### 方式1预编译二进制文件
开始使用 NodePass 的最简单方法是为您的平台下载预编译的二进制文件。
1. 访问 GitHub 上的[发布页面](https://github.com/yosebyte/nodepass/releases)
2. 下载适合您操作系统的二进制文件(Windows、macOS、Linux)
3. 如有必要,解压缩档案
4. 使二进制文件可执行(Linux/macOS)
```bash
chmod +x nodepass
```
5. 将二进制文件移动到PATH中的位置
- Linux/macOS`sudo mv nodepass /usr/local/bin/`
- Windows将位置添加到PATH环境变量
### 方式2使用Go安装
如果您的系统上已安装Go可以使用`go install`命令:
```bash
go install github.com/yosebyte/nodepass/cmd/nodepass@latest
```
此命令下载源代码编译它并将二进制文件安装到您的Go bin目录中(通常是`$GOPATH/bin`)。
### 方式3从源代码构建
对于最新的开发版本或自定义构建:
```bash
# 克隆仓库
git clone https://github.com/yosebyte/nodepass.git
# 导航到项目目录
cd nodepass
# 构建二进制文件
go build -o nodepass ./cmd/nodepass
# 可选安装到GOPATH/bin
go install ./cmd/nodepass
```
### 方式4使用容器镜像
NodePass在GitHub容器注册表中提供容器镜像非常适合容器化环境
```bash
# 拉取容器镜像
docker pull ghcr.io/yosebyte/nodepass:latest
# 服务器模式运行
docker run -d --name nodepass-server -p 10101:10101 -p 8080:8080 \
ghcr.io/yosebyte/nodepass server://0.0.0.0:10101/0.0.0.0:8080
# 客户端模式运行
docker run -d --name nodepass-client \
-e MIN_POOL_CAPACITY=32 \
-e MAX_POOL_CAPACITY=512 \
-p 8080:8080 \
ghcr.io/yosebyte/nodepass client://nodepass-server:10101/127.0.0.1:8080
```
### 方式5使用管理脚本(仅限Linux)
对于Linux系统我们提供了一键脚本
```bash
bash <(curl -sSL https://run.nodepass.eu/np.sh)
```
- 本脚本提供了简单易用的 master 模式,即 API 模式的安装、配置和管理功能。
- 详情请参阅[https://github.com/NodePassProject/npsh](https://github.com/NodePassProject/npsh)
## 验证安装
安装后通过检查版本来验证NodePass是否正确安装
```bash
nodepass
```
## 下一步
安装NodePass后您可以
- 了解基本[使用方法](/docs/zh/usage.md)
- 探索[配置选项](/docs/zh/configuration.md)
- 尝试一些[使用示例](/docs/zh/examples.md)
## 安装问题故障排除
如果在安装过程中遇到任何问题:
- 确保您的系统满足最低要求
- 检查是否具有安装软件的正确权限
- 对于Go相关问题使用`go version`验证您的Go安装
- 对于容器相关问题确保Docker正确安装并运行
- 查看我们的[故障排除指南](/docs/zh/troubleshooting.md)获取更多帮助

View File

@@ -0,0 +1,287 @@
# 故障排除指南
本指南帮助您诊断并解决使用NodePass时可能遇到的常见问题。对于每个问题我们提供可能的原因和逐步解决方案。
## 连接问题
### 无法建立隧道连接
**症状**:客户端无法连接到服务器的隧道端点,或连接立即断开。
**可能的原因和解决方案**
1. **网络连接问题**
- 使用`ping``telnet`验证与服务器地址的基本连接
- 检查指定的端口是否可达:`telnet server.example.com 10101`
- 确保没有防火墙阻止隧道端口通常为10101
2. **服务器未运行**
- 在Linux/macOS上使用`ps aux | grep nodepass`验证NodePass服务器是否运行
- 检查服务器日志中的任何启动错误
- 尝试重启服务器进程
3. **地址错误**
- 仔细检查客户端命令中的隧道地址格式
- 确保使用了正确的主机名/IP和端口
- 如果使用DNS名称验证它们是否解析为正确的IP地址
4. **TLS配置不匹配**
- 如果服务器需要TLS但客户端不支持连接将失败
- 检查服务器日志中的TLS握手错误
- 如果使用TLS模式2确保证书配置正确
### 数据未通过隧道流动
**症状**:隧道连接已建立,但应用程序数据未到达目的地。
**可能的原因和解决方案**
1. **目标服务未运行**
- 验证目标服务在服务器和客户端两侧是否运行
- 检查是否可以在本地直接连接到该服务
2. **端口冲突**
- 确保目标端口没有被其他应用程序占用
- 使用`netstat -tuln`检查端口使用情况
3. **协议不匹配**
- 验证您是否在隧道传输正确的协议TCP与UDP
- 某些应用程序需要特定的协议支持
4. **目标地址错误**
- 仔细检查服务器和客户端命令中的目标地址
- 对于服务器端目标,确保它们可从服务器访问
- 对于客户端目标,确保它们可从客户端访问
### 连接稳定性问题
**症状**:隧道最初工作但频繁断开或变得无响应。
**可能的原因和解决方案**
1. **网络不稳定**
- 检查您的网络中是否有数据包丢失或高延迟
- 考虑为生产部署使用更稳定的网络连接
2. **资源限制**
- 监控客户端和服务器的CPU和内存使用情况
- 如果资源耗尽,调整池参数(参见性能部分)
- 在Linux/macOS上使用`ulimit -n`检查文件描述符限制
3. **超时配置**
- 如果使用具有慢响应时间的UDP调整`UDP_READ_TIMEOUT`
- 考虑在操作系统级别调整TCP keepalive设置以支持长寿命连接
4. **服务器过载**
- 检查服务器日志中的连接过载迹象
- 调整`MAX_POOL_CAPACITY``SEMAPHORE_LIMIT`以处理负载
- 考虑用多个NodePass实例水平扩展
## 证书问题
### TLS握手失败
**症状**连接尝试因TLS握手错误而失败。
**可能的原因和解决方案**
1. **无效证书**
- 验证证书有效性:`openssl x509 -in cert.pem -text -noout`
- 确保证书没有过期
- 检查证书是否针对正确的域名/IP颁发
2. **证书文件丢失或无法访问**
- 确认证书和密钥的文件路径正确
- 验证文件权限允许NodePass进程读取它们
- 通过文本编辑器打开证书检查文件是否损坏
3. **证书信任问题**
- 如果使用自定义CA确保它们被正确信任
- 对于自签名证书确认使用TLS模式1
- 对于验证证书确保CA链完整
4. **密钥格式问题**
- 确保私钥格式正确通常为PEM
- 检查私钥是否有密码保护(不直接支持)
### 证书更新问题
**症状**:证书更新后,安全连接开始失败。
**可能的原因和解决方案**
1. **新证书未加载**
- 重启NodePass强制加载新证书
- 检查`RELOAD_INTERVAL`是否设置正确以自动检测变更
2. **证书链不完整**
- 确保证书文件中包含完整的证书链
- 验证链顺序:首先是您的证书,然后是中间证书
3. **密钥不匹配**
- 验证新证书是否与私钥匹配:
```bash
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
```
- 如果输出不同,证书和密钥不匹配
## 性能优化
### 高延迟
**症状**:连接工作但有明显延迟。
**可能的原因和解决方案**
1. **池配置**
- 增加`MIN_POOL_CAPACITY`以准备更多连接
- 减少`MIN_POOL_INTERVAL`以更快创建连接
- 如果连接队列堆积,调整`SEMAPHORE_LIMIT`
2. **网络路径**
- 检查网络拥塞或高延迟链路
- 考虑将NodePass部署在更靠近客户端或服务器的位置
- 使用traceroute识别潜在瓶颈
3. **TLS开销**
- 如果需要极低延迟且安全性不太重要考虑使用TLS模式0
- 为了平衡使用带会话恢复的TLS模式1
4. **资源竞争**
- 确保主机系统有足够的CPU和内存
- 检查是否有其他进程竞争资源
- 考虑为高流量部署使用专用主机
### CPU使用率高
**症状**NodePass进程消耗过多CPU资源。
**可能的原因和解决方案**
1. **池抖动**
- 如果池不断创建和销毁连接,调整时间
- 增加`MIN_POOL_INTERVAL`以减少连接创建频率
- 为`MIN_POOL_CAPACITY`和`MAX_POOL_CAPACITY`找到良好平衡
2. **过度日志记录**
- 在生产环境中将日志级别从debug降低到info或warn
- 检查日志是否写入缓慢设备
3. **TLS开销**
- TLS握手需要大量CPU考虑会话缓存
- 如果证书验证不太重要使用TLS模式1而不是模式2
4. **流量体积**
- 高吞吐量可能导致CPU饱和
- 考虑跨多个NodePass实例分配流量
- 对于非常高的吞吐量可能需要垂直扩展更多CPU核心
### 内存泄漏
**症状**NodePass内存使用随时间持续增长。
**可能的原因和解决方案**
1. **连接泄漏**
- 确保`SHUTDOWN_TIMEOUT`足够长以正确关闭连接
- 检查自定义脚本或管理代码中的错误处理
- 使用系统工具如`netstat`监控连接数量
2. **池大小问题**
- 如果`MAX_POOL_CAPACITY`非常大,内存使用会更高
- 监控实际池使用情况与配置容量
- 根据实际并发连接需求调整容量
3. **调试日志**
- 在高流量场景中,大量调试日志可能消耗内存
- 在生产环境中使用适当的日志级别
## UDP特定问题
### UDP数据丢失
**症状**UDP数据包无法通过隧道可靠转发。
**可能的原因和解决方案**
1. **缓冲区大小限制**
- 如果UDP数据包较大增加`UDP_DATA_BUF_SIZE`
- 默认8192字节对某些应用程序可能太小
2. **超时问题**
- 如果响应较慢,增加`UDP_READ_TIMEOUT`
- 对于响应时间变化的应用程序,找到最佳平衡点
3. **高数据包率**
- UDP一次处理一个数据报非常高的速率可能导致问题
- 考虑为高流量UDP应用增加池容量
4. **协议期望**
- 一些UDP应用期望特定的数据包顺序或时序行为
- NodePass提供尽力转发但无法保证超出网络提供的UDP属性
### UDP连接跟踪
**症状**UDP会话过早断开或无法建立。
**可能的原因和解决方案**
1. **连接映射**
- 验证客户端配置是否符合服务器期望
- 检查防火墙是否超时UDP会话跟踪
2. **应用UDP超时**
- 一些应用有内置UDP会话超时
- 可能需要调整应用特定的keepalive设置
## 主控API问题
### API可访问性问题
**症状**无法连接到主控API端点。
**可能的原因和解决方案**
1. **端点配置**
- 验证主控命令中的API地址和端口
- 检查API服务器是否绑定到正确的网络接口
2. **TLS配置**
- 如果使用HTTPSTLS模式1或2确保客户端工具支持TLS
- 对于测试,使用`curl -k`跳过证书验证
3. **自定义前缀问题**
- 如果使用自定义API前缀确保所有请求中都包含它
- 检查API客户端和脚本中的URL格式
### 实例管理失败
**症状**无法通过API创建、控制或删除实例。
**可能的原因和解决方案**
1. **JSON格式问题**
- 验证请求体是有效的JSON
- 检查API请求中的必填字段
2. **URL解析问题**
- 确保实例URL格式正确必要时进行URL编码
- 验证URL参数使用正确格式
3. **实例状态冲突**
- 无法删除运行中的实例,必须先停止
- 在执行操作前先用GET检查当前实例状态
4. **权限问题**
- 确保NodePass主控具有创建进程的足够权限
- 检查任何引用的证书或密钥的文件系统权限
## 下一步
如果您遇到本指南未涵盖的问题:
- 查看[项目仓库](https://github.com/yosebyte/nodepass)中的已知问题
- 将日志级别增加到`debug`以获取更详细信息
- 查看[工作原理](/docs/zh/how-it-works.md)部分以更好地理解内部机制
- 考虑加入社区讨论,从其他用户处获取帮助

283
nodepass/docs/zh/usage.md Normal file
View File

@@ -0,0 +1,283 @@
# 使用说明
NodePass创建一个带有未加密TCP控制通道的隧道并为数据交换提供可配置的TLS加密选项。本指南涵盖三种操作模式并说明如何有效地使用每种模式。
## 命令行语法
NodePass命令的一般语法是
```bash
nodepass "<core>://<tunnel_addr>/<target_addr>?log=<level>&tls=<mode>&crt=<cert_file>&key=<key_file>&min=<min_pool>&max=<max_pool>"
```
其中:
- `<core>`:指定操作模式(`server``client``master`
- `<tunnel_addr>`:控制通道通信的隧道端点地址
- `<target_addr>`业务数据的目标地址支持双向模式或在master模式下的API前缀
### 查询参数说明
通用查询参数:
- `log=<level>`:日志详细级别(`debug``info``warn``error``event`
- `min=<min_pool>`最小连接池容量默认64仅适用于client模式
- `max=<max_pool>`最大连接池容量默认8192仅适用于client模式
TLS相关参数仅适用于server/master模式
- `tls=<mode>`数据通道的TLS安全级别`0``1``2`
- `crt=<cert_file>`:证书文件路径(当`tls=2`时)
- `key=<key_file>`:私钥文件路径(当`tls=2`时)
## 运行模式
NodePass提供三种互补的运行模式以适应各种部署场景。
### 服务端模式
服务端模式建立隧道控制通道,并支持双向数据流转发。
```bash
nodepass "server://<tunnel_addr>/<target_addr>?log=<level>&tls=<mode>&crt=<cert_file>&key=<key_file>"
```
#### 参数
- `tunnel_addr`TCP隧道端点地址控制通道客户端将连接到此处(例如, 10.1.0.1:10101)
- `target_addr`:业务数据的目标地址,支持双向数据流模式(例如, 10.1.0.1:8080)
- `log`:日志级别(debug, info, warn, error, event)
- `tls`目标数据通道的TLS加密模式 (0, 1, 2)
- `0`无TLS加密明文TCP/UDP
- `1`:自签名证书(自动生成)
- `2`:自定义证书(需要`crt``key`参数)
- `crt`:证书文件路径(当`tls=2`时必需)
- `key`:私钥文件路径(当`tls=2`时必需)
#### 服务端模式工作原理
在服务端模式下NodePass支持两种数据流方向
**模式一:服务端接收流量**target_addr为本地地址
1.`tunnel_addr`上监听TCP隧道连接控制通道
2.`target_addr`上监听传入的TCP和UDP流量
3.`target_addr`收到连接时,通过控制通道向客户端发送信号
4. 为每个连接创建具有指定TLS加密级别的数据通道
**模式二:服务端发送流量**target_addr为远程地址
1.`tunnel_addr`上监听TCP隧道连接控制通道
2. 等待客户端在其本地监听,并通过隧道接收连接
3. 建立到远程`target_addr`的连接并转发数据
#### 示例
```bash
# 数据通道无TLS加密 - 服务端接收模式
nodepass "server://10.1.0.1:10101/10.1.0.1:8080?log=debug&tls=0"
# 自签名证书(自动生成) - 服务端发送模式
nodepass "server://10.1.0.1:10101/192.168.1.100:8080?log=debug&tls=1"
# 自定义域名证书 - 服务端接收模式
nodepass "server://10.1.0.1:10101/10.1.0.1:8080?log=debug&tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
### 客户端模式
客户端模式连接到NodePass服务端并支持双向数据流转发。
```bash
nodepass "client://<tunnel_addr>/<target_addr>?log=<level>&min=<min_pool>&max=<max_pool>"
```
#### 参数
- `tunnel_addr`要连接的NodePass服务端隧道端点地址(例如, 10.1.0.1:10101)
- `target_addr`:业务数据的目标地址,支持双向数据流模式(例如, 127.0.0.1:8080)
- `log`:日志级别(debug, info, warn, error, event)
- `min`最小连接池容量默认64
- `max`最大连接池容量默认8192
#### 客户端模式工作原理
在客户端模式下NodePass支持三种操作模式
**模式一:客户端单端转发**(当隧道地址为本地地址时)
1. 在本地隧道地址上监听TCP和UDP连接
2. 使用连接池技术预建立到目标地址的TCP连接消除连接延迟
3. 直接将接收到的流量转发到目标地址,实现高性能转发
4. 无需与服务端握手,实现点对点的直接转发
5. 适用于本地代理和简单转发场景
**模式二:客户端接收流量**(当服务端发送流量时)
1. 连接到服务端的TCP隧道端点控制通道
2. 在本地监听端口,等待通过隧道传入的连接
3. 建立到本地`target_addr`的连接并转发数据
**模式三:客户端发送流量**(当服务端接收流量时)
1. 连接到服务端的TCP隧道端点控制通道
2. 通过控制通道监听来自服务端的信号
3. 当收到信号时使用服务端指定的TLS安全级别建立数据连接
4. 建立到`target_addr`的本地连接并转发流量
#### 示例
```bash
# 客户端单端转发模式 - 本地代理监听1080端口转发到目标服务器
nodepass client://127.0.0.1:1080/target.example.com:8080?log=debug
# 连接到NodePass服务端并采用其TLS安全策略 - 客户端发送模式
nodepass client://server.example.com:10101/127.0.0.1:8080
# 使用调试日志连接 - 客户端接收模式
nodepass client://server.example.com:10101/192.168.1.100:8080?log=debug
# 自定义连接池容量 - 高性能配置
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=128&max=4096"
# 资源受限配置 - 小型连接池
nodepass "client://server.example.com:10101/127.0.0.1:8080?min=16&max=512&log=info"
```
### 主控模式 (API)
主控模式运行RESTful API服务器用于集中管理NodePass实例。
```bash
nodepass "master://<api_addr>[<prefix>]?log=<level>&tls=<mode>&crt=<cert_file>&key=<key_file>"
```
#### 参数
- `api_addr`API服务监听的地址例如0.0.0.0:9090
- `prefix`可选的API前缀路径例如/management。默认为`/api`
- `log`:日志级别(debug, info, warn, error, event)
- `tls`API服务的TLS加密模式(0, 1, 2)
- `0`无TLS加密HTTP
- `1`自签名证书带自动生成证书的HTTPS
- `2`自定义证书带提供证书的HTTPS
- `crt`:证书文件路径(当`tls=2`时必需)
- `key`:私钥文件路径(当`tls=2`时必需)
#### 主控模式工作原理
在主控模式下NodePass
1. 运行一个RESTful API服务器允许动态管理NodePass实例
2. 提供用于创建、启动、停止和监控客户端和服务端实例的端点
3. 包含用于轻松API探索的Swagger UI位于`{prefix}/v1/docs`
4. 自动继承通过API创建的实例的TLS和日志设置
#### API端点
所有端点都是相对于配置的前缀(默认:`/api`
- `GET {prefix}/v1/instances` - 列出所有实例
- `POST {prefix}/v1/instances` - 创建新实例JSON请求体: `{"url": "server://0.0.0.0:10101/0.0.0.0:8080"}`
- `GET {prefix}/v1/instances/{id}` - 获取实例详情
- `PATCH {prefix}/v1/instances/{id}` - 更新实例JSON请求体: `{"action": "start|stop|restart"}`
- `DELETE {prefix}/v1/instances/{id}` - 删除实例
- `GET {prefix}/v1/openapi.json` - OpenAPI规范
- `GET {prefix}/v1/docs` - Swagger UI文档
#### 示例
```bash
# 启动HTTP主控服务使用默认API前缀/api
nodepass "master://0.0.0.0:9090?log=info"
# 启动带有自定义API前缀的主控服务/management
nodepass "master://0.0.0.0:9090/management?log=info"
# 启动HTTPS主控服务自签名证书
nodepass "master://0.0.0.0:9090/admin?log=info&tls=1"
# 启动HTTPS主控服务自定义证书
nodepass "master://0.0.0.0:9090?log=info&tls=2&crt=/path/to/cert.pem&key=/path/to/key.pem"
```
## 管理NodePass实例
### 通过API创建和管理
您可以使用标准HTTP请求通过主控API管理NodePass实例
```bash
# 通过API创建和管理实例使用默认前缀
curl -X POST http://localhost:9090/api/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
# 使用自定义前缀
curl -X POST http://localhost:9090/admin/v1/instances \
-H "Content-Type: application/json" \
-d '{"url":"server://0.0.0.0:10101/0.0.0.0:8080?tls=1"}'
# 列出所有运行实例
curl http://localhost:9090/api/v1/instances
# 控制实例用实际实例ID替换{id}
curl -X PUT http://localhost:9090/api/v1/instances/{id} \
-H "Content-Type: application/json" \
-d '{"action":"restart"}'
```
## 双向数据流说明
NodePass支持灵活的双向数据流配置
### 客户端单端转发模式
- **客户端**:在本地隧道地址监听,使用连接池技术直接转发到目标地址
- **连接池优化**预建立TCP连接消除连接延迟提供高性能转发
- **无需服务端**:独立运行,不依赖服务端握手
- **使用场景**:本地代理、简单端口转发、测试环境、高性能转发
### 服务端接收模式 (dataFlow: "-")
- **服务端**在target_addr监听传入连接通过隧道转发到客户端
- **客户端**连接到本地target_addr提供服务
- **使用场景**:将内网服务暴露给外网访问
### 服务端发送模式 (dataFlow: "+")
- **服务端**连接到远程target_addr获取数据通过隧道发送到客户端
- **客户端**:在本地监听,接收来自服务端的连接
- **使用场景**:通过隧道代理访问远程服务
系统会根据隧道地址和目标地址自动选择合适的操作模式:
- 如果客户端的隧道地址为本地地址,启用单端转发模式
- 如果目标地址是本地地址,使用服务端接收模式
- 如果目标地址是远程地址,使用服务端发送模式
## 隧道密钥Tunnel Key
NodePass使用隧道密钥来验证客户端和服务端之间的连接。密钥可以通过两种方式指定
### 密钥获取规则
1. **显式密钥**在URL中指定用户名部分作为密钥
```bash
# 使用"mypassword"作为隧道密钥
nodepass server://mypassword@10.1.0.1:10101/10.1.0.1:8080
nodepass client://mypassword@10.1.0.1:10101/127.0.0.1:8080
```
2. **端口派生密钥**:如果未指定用户名,系统将使用端口号的十六进制值作为密钥
```bash
# 端口10101的十六进制值为"2775",将作为隧道密钥
nodepass server://10.1.0.1:10101/10.1.0.1:8080
nodepass client://10.1.0.1:10101/127.0.0.1:8080
```
### 握手流程
客户端与服务端的握手过程如下:
1. **客户端连接**:客户端连接到服务端的隧道地址
2. **密钥验证**客户端发送XOR加密的隧道密钥
3. **服务端验证**:服务端解密并验证密钥是否匹配
4. **配置同步**验证成功后服务端发送隧道配置信息包括TLS模式
5. **连接确立**:握手完成,开始数据传输
这种设计确保了只有拥有正确密钥的客户端才能建立隧道连接。
## 下一步
- 了解[配置选项](/docs/zh/configuration.md)以微调NodePass
- 探索常见部署场景的[使用示例](/docs/zh/examples.md)
- 理解NodePass内部[工作原理](/docs/zh/how-it-works.md)
- 如果遇到问题,请查看[故障排除指南](/docs/zh/troubleshooting.md)

10
nodepass/go.mod Normal file
View File

@@ -0,0 +1,10 @@
module github.com/yosebyte/nodepass
go 1.24.3
require (
github.com/NodePassProject/cert v1.0.0
github.com/NodePassProject/conn v1.0.1
github.com/NodePassProject/logs v1.0.1
github.com/NodePassProject/pool v1.0.8
)

8
nodepass/go.sum Normal file
View File

@@ -0,0 +1,8 @@
github.com/NodePassProject/cert v1.0.0 h1:cBNNvR+ja22AgNlUmeGWLcCM1vmnLTqpbCQ4Hdn5was=
github.com/NodePassProject/cert v1.0.0/go.mod h1:4EJDS3GozJ74dtICJ/xcq42WKKvF0tiTM9/M7Q9NF9c=
github.com/NodePassProject/conn v1.0.1 h1:vuzcQQj+cqENagzEYPwse9Vvlj/8vfkyNZCp5RvQMKk=
github.com/NodePassProject/conn v1.0.1/go.mod h1:mWe3Rylunp6Sx4v6pkSGgYZe2R+I/O+7nZ2od0yJ3aQ=
github.com/NodePassProject/logs v1.0.1 h1:WDHY1DcTO+7NydBzuRpxhEw6pWYayBdDjjZzU1uDKac=
github.com/NodePassProject/logs v1.0.1/go.mod h1:ocFTMNXBTnQFJFAhF+qobAzu7+y+wYPik7D+a1jPfis=
github.com/NodePassProject/pool v1.0.8 h1:zuqVdQj0OBarIo/P/BdpTxXk8kbjU2GYJJaVA5T+LwQ=
github.com/NodePassProject/pool v1.0.8/go.mod h1:kdRAEDK45j/+iHH4kRTpXt/wI28NIguJ13n/5NDXxkw=

171
nodepass/internal/client.go Normal file
View File

@@ -0,0 +1,171 @@
// 内部包,实现客户端模式功能
package internal
import (
"bufio"
"bytes"
"context"
"net"
"net/url"
"os"
"os/signal"
"syscall"
"time"
"github.com/NodePassProject/logs"
"github.com/NodePassProject/pool"
)
// Client 实现客户端模式功能
type Client struct {
Common // 继承共享功能
tunnelName string // 隧道名称
}
// NewClient 创建新的客户端实例
func NewClient(parsedURL *url.URL, logger *logs.Logger) *Client {
client := &Client{
Common: Common{
logger: logger,
semaphore: make(chan struct{}, semaphoreLimit),
errChan: make(chan error, 2),
signalChan: make(chan string, semaphoreLimit),
},
tunnelName: parsedURL.Hostname(),
}
// 初始化公共字段
client.getTunnelKey(parsedURL)
client.getPoolCapacity(parsedURL)
client.getAddress(parsedURL)
return client
}
// Run 管理客户端生命周期
func (c *Client) Run() {
c.logger.Info("Client started: %v@%v/%v", c.tunnelKey, c.tunnelAddr, c.targetTCPAddr)
// 启动客户端服务并处理重启
go func() {
for {
time.Sleep(serviceCooldown)
if err := c.start(); err != nil {
c.logger.Error("Client error: %v", err)
c.stop()
c.logger.Info("Client restarted: %v@%v/%v", c.tunnelKey, c.tunnelAddr, c.targetTCPAddr)
}
}
}()
// 监听系统信号以优雅关闭
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
<-ctx.Done()
stop()
// 执行关闭过程
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
defer cancel()
if err := c.shutdown(shutdownCtx, c.stop); err != nil {
c.logger.Error("Client shutdown error: %v", err)
} else {
c.logger.Info("Client shutdown complete")
}
}
// start 启动客户端服务
func (c *Client) start() error {
c.initContext()
// 通过是否监听成功判断单端转发或双端握手
if err := c.initTunnelListener(); err == nil {
// 初始化连接池
c.tunnelPool = pool.NewClientPool(
c.minPoolCapacity,
c.maxPoolCapacity,
minPoolInterval,
maxPoolInterval,
reportInterval,
c.tlsCode,
true,
c.tunnelName,
func() (net.Conn, error) {
return net.DialTCP("tcp", nil, c.targetTCPAddr)
})
go c.tunnelPool.ClientManager()
return c.singleLoop()
} else {
if err := c.tunnelHandshake(); err != nil {
return err
}
// 初始化连接池
c.tunnelPool = pool.NewClientPool(
c.minPoolCapacity,
c.maxPoolCapacity,
minPoolInterval,
maxPoolInterval,
reportInterval,
c.tlsCode,
false,
c.tunnelName,
func() (net.Conn, error) {
return net.DialTCP("tcp", nil, c.tunnelTCPAddr)
})
go c.tunnelPool.ClientManager()
switch c.dataFlow {
case "-":
go c.commonOnce()
go c.commonQueue()
case "+":
// 初始化目标监听器
if err := c.initTargetListener(); err != nil {
return err
}
go c.commonLoop()
}
return c.healthCheck()
}
}
// tunnelHandshake 与隧道服务端进行握手
func (c *Client) tunnelHandshake() error {
// 建立隧道TCP连接
tunnelTCPConn, err := net.DialTimeout("tcp", c.tunnelTCPAddr.String(), tcpDialTimeout)
if err != nil {
return err
}
c.tunnelTCPConn = tunnelTCPConn.(*net.TCPConn)
c.bufReader = bufio.NewReader(c.tunnelTCPConn)
c.tunnelTCPConn.SetKeepAlive(true)
c.tunnelTCPConn.SetKeepAlivePeriod(reportInterval)
// 发送隧道密钥
_, err = c.tunnelTCPConn.Write(append(c.xor([]byte(c.tunnelKey)), '\n'))
if err != nil {
return err
}
// 读取隧道URL
rawTunnelURL, err := c.bufReader.ReadBytes('\n')
if err != nil {
return err
}
tunnelSignal := string(c.xor(bytes.TrimSuffix(rawTunnelURL, []byte{'\n'})))
// 解析隧道URL
tunnelURL, err := url.Parse(tunnelSignal)
if err != nil {
return err
}
c.dataFlow = tunnelURL.Host
c.tlsCode = tunnelURL.Fragment
c.logger.Info("Tunnel signal <- : %v <- %v", tunnelSignal, c.tunnelTCPConn.RemoteAddr())
c.logger.Info("Tunnel handshaked: %v <-> %v", c.tunnelTCPConn.LocalAddr(), c.tunnelTCPConn.RemoteAddr())
return nil
}

848
nodepass/internal/common.go Normal file
View File

@@ -0,0 +1,848 @@
// 内部包,提供共享功能
package internal
import (
"bufio"
"bytes"
"context"
"fmt"
"net"
"net/url"
"os"
"strconv"
"strings"
"sync"
"time"
"github.com/NodePassProject/conn"
"github.com/NodePassProject/logs"
"github.com/NodePassProject/pool"
)
// Common 包含所有模式共享的核心功能
type Common struct {
mu sync.Mutex // 互斥锁
logger *logs.Logger // 日志记录器
tlsCode string // TLS模式代码
dataFlow string // 数据流向
tunnelKey string // 隧道密钥
tunnelAddr string // 隧道地址字符串
tunnelTCPAddr *net.TCPAddr // 隧道TCP地址
tunnelUDPAddr *net.UDPAddr // 隧道UDP地址
targetAddr string // 目标地址字符串
targetTCPAddr *net.TCPAddr // 目标TCP地址
targetUDPAddr *net.UDPAddr // 目标UDP地址
targetListener *net.TCPListener // 目标监听器
tunnelListener net.Listener // 隧道监听器
tunnelTCPConn *net.TCPConn // 隧道TCP连接
tunnelUDPConn *net.UDPConn // 隧道UDP连接
targetTCPConn *net.TCPConn // 目标TCP连接
targetUDPConn *net.UDPConn // 目标UDP连接
targetUDPSession sync.Map // 目标UDP会话
tunnelPool *pool.Pool // 隧道连接池
minPoolCapacity int // 最小池容量
maxPoolCapacity int // 最大池容量
semaphore chan struct{} // 信号量通道
bufReader *bufio.Reader // 缓冲读取器
signalChan chan string // 信号通道
errChan chan error // 错误通道
ctx context.Context // 上下文
cancel context.CancelFunc // 取消函数
}
// 配置变量,可通过环境变量调整
var (
semaphoreLimit = getEnvAsInt("NP_SEMAPHORE_LIMIT", 1024) // 信号量限制
udpDataBufSize = getEnvAsInt("NP_UDP_DATA_BUF_SIZE", 8192) // UDP缓冲区大小
udpReadTimeout = getEnvAsDuration("NP_UDP_READ_TIMEOUT", 20*time.Second) // UDP读取超时
udpDialTimeout = getEnvAsDuration("NP_UDP_DIAL_TIMEOUT", 20*time.Second) // UDP拨号超时
tcpReadTimeout = getEnvAsDuration("NP_TCP_READ_TIMEOUT", 20*time.Second) // TCP读取超时
tcpDialTimeout = getEnvAsDuration("NP_TCP_DIAL_TIMEOUT", 20*time.Second) // TCP拨号超时
minPoolInterval = getEnvAsDuration("NP_MIN_POOL_INTERVAL", 1*time.Second) // 最小池间隔
maxPoolInterval = getEnvAsDuration("NP_MAX_POOL_INTERVAL", 5*time.Second) // 最大池间隔
reportInterval = getEnvAsDuration("NP_REPORT_INTERVAL", 5*time.Second) // 报告间隔
serviceCooldown = getEnvAsDuration("NP_SERVICE_COOLDOWN", 3*time.Second) // 服务冷却时间
shutdownTimeout = getEnvAsDuration("NP_SHUTDOWN_TIMEOUT", 5*time.Second) // 关闭超时
ReloadInterval = getEnvAsDuration("NP_RELOAD_INTERVAL", 1*time.Hour) // 重载间隔
)
// getEnvAsInt 从环境变量获取整数值,如果不存在则使用默认值
func getEnvAsInt(name string, defaultValue int) int {
if valueStr, exists := os.LookupEnv(name); exists {
if value, err := strconv.Atoi(valueStr); err == nil && value >= 0 {
return value
}
}
return defaultValue
}
// getEnvAsDuration 从环境变量获取时间间隔,如果不存在则使用默认值
func getEnvAsDuration(name string, defaultValue time.Duration) time.Duration {
if valueStr, exists := os.LookupEnv(name); exists {
if value, err := time.ParseDuration(valueStr); err == nil && value >= 0 {
return value
}
}
return defaultValue
}
// xor 对数据进行异或处理
func (c *Common) xor(data []byte) []byte {
for i := range data {
data[i] ^= byte(len(c.tunnelKey) % 256)
}
return data
}
// getTunnelKey 从URL中获取隧道密钥
func (c *Common) getTunnelKey(parsedURL *url.URL) {
if key := parsedURL.User.Username(); key != "" {
c.tunnelKey = key
} else {
portStr := parsedURL.Port()
if portNum, err := strconv.Atoi(portStr); err == nil {
c.tunnelKey = fmt.Sprintf("%x", portNum)
} else {
c.tunnelKey = fmt.Sprintf("%x", portStr)
}
}
}
// getPoolCapacity 获取连接池容量设置
func (c *Common) getPoolCapacity(parsedURL *url.URL) {
if min := parsedURL.Query().Get("min"); min != "" {
if value, err := strconv.Atoi(min); err == nil && value > 0 {
c.minPoolCapacity = value
}
} else {
c.minPoolCapacity = 64
}
if max := parsedURL.Query().Get("max"); max != "" {
if value, err := strconv.Atoi(max); err == nil && value > 0 {
c.maxPoolCapacity = value
}
} else {
c.maxPoolCapacity = 8192
}
}
// getAddress 解析和设置地址信息
func (c *Common) getAddress(parsedURL *url.URL) {
// 解析隧道地址
c.tunnelAddr = parsedURL.Host
// 解析隧道TCP地址
if tunnelTCPAddr, err := net.ResolveTCPAddr("tcp", c.tunnelAddr); err == nil {
c.tunnelTCPAddr = tunnelTCPAddr
} else {
c.logger.Error("Resolve failed: %v", err)
}
// 解析隧道UDP地址
if tunnelUDPAddr, err := net.ResolveUDPAddr("udp", c.tunnelAddr); err == nil {
c.tunnelUDPAddr = tunnelUDPAddr
} else {
c.logger.Error("Resolve failed: %v", err)
}
// 处理目标地址
targetAddr := strings.TrimPrefix(parsedURL.Path, "/")
c.targetAddr = targetAddr
// 解析目标TCP地址
if targetTCPAddr, err := net.ResolveTCPAddr("tcp", targetAddr); err == nil {
c.targetTCPAddr = targetTCPAddr
} else {
c.logger.Error("Resolve failed: %v", err)
}
// 解析目标UDP地址
if targetUDPAddr, err := net.ResolveUDPAddr("udp", targetAddr); err == nil {
c.targetUDPAddr = targetUDPAddr
} else {
c.logger.Error("Resolve failed: %v", err)
}
}
// initContext 初始化上下文
func (c *Common) initContext() {
if c.cancel != nil {
c.cancel()
}
c.ctx, c.cancel = context.WithCancel(context.Background())
}
// initTargetListener 初始化目标监听器
func (c *Common) initTargetListener() error {
// 初始化目标TCP监听器
targetListener, err := net.ListenTCP("tcp", c.targetTCPAddr)
if err != nil {
if targetListener != nil {
targetListener.Close()
}
return err
}
c.targetListener = targetListener
// 初始化目标UDP监听器
targetUDPConn, err := net.ListenUDP("udp", c.targetUDPAddr)
if err != nil {
if targetUDPConn != nil {
targetUDPConn.Close()
}
return err
}
c.targetUDPConn = targetUDPConn
return nil
}
// initTunnelListener 初始化隧道监听器
func (c *Common) initTunnelListener() error {
// 初始化隧道TCP监听器
tunnelListener, err := net.ListenTCP("tcp", c.tunnelTCPAddr)
if err != nil {
if tunnelListener != nil {
tunnelListener.Close()
}
return err
}
c.tunnelListener = tunnelListener
// 初始化隧道UDP监听器
tunnelUDPConn, err := net.ListenUDP("udp", c.tunnelUDPAddr)
if err != nil {
if tunnelUDPConn != nil {
tunnelUDPConn.Close()
}
return err
}
c.tunnelUDPConn = tunnelUDPConn
return nil
}
// stop 共用停止服务
func (c *Common) stop() {
// 取消上下文
if c.cancel != nil {
c.cancel()
}
// 关闭隧道连接池
if c.tunnelPool != nil {
active := c.tunnelPool.Active()
c.tunnelPool.Close()
c.logger.Debug("Tunnel connection closed: pool active %v", active)
}
// 清理目标UDP会话
c.targetUDPSession.Range(func(key, value any) bool {
if conn, ok := value.(*net.UDPConn); ok {
conn.Close()
}
c.targetUDPSession.Delete(key)
return true
})
// 关闭目标UDP连接
if c.targetUDPConn != nil {
c.targetUDPConn.Close()
c.logger.Debug("Target connection closed: %v", c.targetUDPConn.LocalAddr())
}
// 关闭目标TCP连接
if c.targetTCPConn != nil {
c.targetTCPConn.Close()
c.logger.Debug("Target connection closed: %v", c.targetTCPConn.LocalAddr())
}
// 关闭隧道UDP连接
if c.tunnelUDPConn != nil {
c.tunnelUDPConn.Close()
c.logger.Debug("Tunnel connection closed: %v", c.tunnelUDPConn.LocalAddr())
}
// 关闭隧道TCP连接
if c.tunnelTCPConn != nil {
c.tunnelTCPConn.Close()
c.logger.Debug("Tunnel connection closed: %v", c.tunnelTCPConn.LocalAddr())
}
// 关闭目标监听器
if c.targetListener != nil {
c.targetListener.Close()
c.logger.Debug("Target listener closed: %v", c.targetListener.Addr())
}
// 关闭隧道监听器
if c.tunnelListener != nil {
c.tunnelListener.Close()
c.logger.Debug("Tunnel listener closed: %v", c.tunnelListener.Addr())
}
// 清空信号通道
for {
select {
case <-c.signalChan:
default:
return
}
}
}
// shutdown 共用优雅关闭
func (c *Common) shutdown(ctx context.Context, stopFunc func()) error {
done := make(chan struct{})
go func() {
defer close(done)
stopFunc()
}()
select {
case <-ctx.Done():
return ctx.Err()
case <-done:
return nil
}
}
// commonQueue 共用信号队列
func (c *Common) commonQueue() error {
for {
select {
case <-c.ctx.Done():
return c.ctx.Err()
default:
// 读取原始信号
rawSignal, err := c.bufReader.ReadBytes('\n')
if err != nil {
return err
}
signal := string(c.xor(bytes.TrimSuffix(rawSignal, []byte{'\n'})))
// 将信号发送到通道
select {
case c.signalChan <- signal:
default:
c.logger.Debug("Queue limit reached: %v", semaphoreLimit)
}
}
}
}
// healthCheck 共用健康度检查
func (c *Common) healthCheck() error {
flushURL := &url.URL{Fragment: "0"} // 连接池刷新信号
for {
select {
case <-c.ctx.Done():
return c.ctx.Err()
default:
if !c.mu.TryLock() {
continue
}
// 连接池健康度检查
if c.tunnelPool.ErrorCount() > c.tunnelPool.Active()/2 {
// 发送刷新信号到对端
_, err := c.tunnelTCPConn.Write(append(c.xor([]byte(flushURL.String())), '\n'))
if err != nil {
c.mu.Unlock()
return err
}
c.tunnelPool.Flush()
time.Sleep(reportInterval) // 等待连接池刷新完成
c.logger.Debug("Tunnel pool reset: %v active connections", c.tunnelPool.Active())
} else {
// 发送普通心跳包
_, err := c.tunnelTCPConn.Write([]byte("\n"))
if err != nil {
c.mu.Unlock()
return err
}
}
c.mu.Unlock()
time.Sleep(reportInterval)
}
}
}
// commonLoop 共用处理循环
func (c *Common) commonLoop() {
for {
select {
case <-c.ctx.Done():
return
default:
// 等待连接池准备就绪
if c.tunnelPool.Ready() {
go c.commonTCPLoop()
go c.commonUDPLoop()
return
}
time.Sleep(time.Millisecond)
}
}
}
// commonTCPLoop 共用TCP请求处理循环
func (c *Common) commonTCPLoop() {
for {
select {
case <-c.ctx.Done():
return
default:
// 接受来自目标的TCP连接
targetConn, err := c.targetListener.Accept()
if err != nil {
continue
}
defer func() {
if targetConn != nil {
targetConn.Close()
}
}()
c.targetTCPConn = targetConn.(*net.TCPConn)
c.logger.Debug("Target connection: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
// 使用信号量限制并发数
c.semaphore <- struct{}{}
go func(targetConn net.Conn) {
defer func() { <-c.semaphore }()
// 从连接池获取连接
id, remoteConn := c.tunnelPool.ServerGet()
if remoteConn == nil {
c.logger.Error("Get failed: %v not found", id)
c.tunnelPool.AddError()
return
}
c.logger.Debug("Tunnel connection: get %v <- pool active %v", id, c.tunnelPool.Active())
defer func() {
c.tunnelPool.Put(id, remoteConn)
c.logger.Debug("Tunnel connection: put %v -> pool active %v", id, c.tunnelPool.Active())
}()
c.logger.Debug("Tunnel connection: %v <-> %v", remoteConn.LocalAddr(), remoteConn.RemoteAddr())
// 构建并发送启动URL到客户端
launchURL := &url.URL{
Host: id,
Fragment: "1", // TCP模式
}
c.mu.Lock()
_, err = c.tunnelTCPConn.Write(append(c.xor([]byte(launchURL.String())), '\n'))
c.mu.Unlock()
if err != nil {
c.logger.Error("Write failed: %v", err)
return
}
c.logger.Debug("TCP launch signal: %v -> %v", id, c.tunnelTCPConn.RemoteAddr())
c.logger.Debug("Starting exchange: %v <-> %v", remoteConn.LocalAddr(), targetConn.LocalAddr())
// 交换数据
rx, tx, _ := conn.DataExchange(remoteConn, targetConn, tcpReadTimeout)
// 交换完成,广播统计信息
c.logger.Event("Exchange complete: TRAFFIC_STATS|TCP_RX=%v|TCP_TX=%v|UDP_RX=0|UDP_TX=0", rx, tx)
}(targetConn)
}
}
}
// commonUDPLoop 共用UDP请求处理循环
func (c *Common) commonUDPLoop() {
for {
select {
case <-c.ctx.Done():
return
default:
// 读取来自目标的UDP数据
buffer := make([]byte, udpDataBufSize)
n, clientAddr, err := c.targetUDPConn.ReadFromUDP(buffer)
if err != nil {
continue
}
c.logger.Debug("Target connection: %v <-> %v", c.targetUDPConn.LocalAddr(), clientAddr)
// 从连接池获取连接
id, remoteConn := c.tunnelPool.ServerGet()
if remoteConn == nil {
c.logger.Error("Get failed: %v not found", id)
c.tunnelPool.AddError()
continue
}
c.logger.Debug("Tunnel connection: get %v <- pool active %v", id, c.tunnelPool.Active())
defer func() {
c.tunnelPool.Put(id, remoteConn)
c.logger.Debug("Tunnel connection: put %v -> pool active %v", id, c.tunnelPool.Active())
}()
c.logger.Debug("Tunnel connection: %v <-> %v", remoteConn.LocalAddr(), remoteConn.RemoteAddr())
// 使用信号量限制并发数
c.semaphore <- struct{}{}
go func(buffer []byte, n int, clientAddr *net.UDPAddr, remoteConn net.Conn) {
defer func() { <-c.semaphore }()
// 构建并发送启动URL到客户端
launchURL := &url.URL{
Host: id,
Fragment: "2", // UDP模式
}
c.mu.Lock()
_, err = c.tunnelTCPConn.Write(append(c.xor([]byte(launchURL.String())), '\n'))
c.mu.Unlock()
if err != nil {
c.logger.Error("Write failed: %v", err)
return
}
c.logger.Debug("UDP launch signal: %v -> %v", id, c.tunnelTCPConn.RemoteAddr())
c.logger.Debug("Starting transfer: %v <-> %v", remoteConn.LocalAddr(), c.targetUDPConn.LocalAddr())
// 处理UDP/TCP数据传输
rx, tx, _ := conn.DataTransfer(
c.targetUDPConn,
remoteConn,
clientAddr,
buffer[:n],
udpDataBufSize,
tcpReadTimeout,
)
// 传输完成,广播统计信息
c.logger.Event("Transfer complete: TRAFFIC_STATS|TCP_RX=0|TCP_TX=0|UDP_RX=%v|UDP_TX=%v", rx, tx)
}(buffer, n, clientAddr, remoteConn)
}
}
}
// commonOnce 共用处理单个请求
func (c *Common) commonOnce() {
for {
// 等待连接池准备就绪
if !c.tunnelPool.Ready() {
time.Sleep(time.Millisecond)
continue
}
select {
case <-c.ctx.Done():
return
case signal := <-c.signalChan:
// 解析信号URL
signalURL, err := url.Parse(signal)
if err != nil {
c.logger.Error("Parse failed: %v", err)
continue
}
// 处理信号
switch signalURL.Fragment {
case "0": // 连接池刷新
go func() {
c.tunnelPool.Flush()
time.Sleep(reportInterval) // 等待连接池刷新完成
c.logger.Debug("Tunnel pool reset: %v active connections", c.tunnelPool.Active())
}()
case "1": // TCP
go c.commonTCPOnce(signalURL.Host)
case "2": // UDP
go c.commonUDPOnce(signalURL.Host)
default:
// 健康检查或无效信号
}
}
}
}
// commonTCPOnce 共用处理单个TCP请求
func (c *Common) commonTCPOnce(id string) {
c.logger.Debug("TCP launch signal: %v <- %v", id, c.tunnelTCPConn.RemoteAddr())
// 从连接池获取连接
remoteConn := c.tunnelPool.ClientGet(id)
if remoteConn == nil {
c.logger.Error("Get failed: %v not found", id)
return
}
c.logger.Debug("Tunnel connection: get %v <- pool active %v", id, c.tunnelPool.Active())
defer func() {
c.tunnelPool.Put(id, remoteConn)
c.logger.Debug("Tunnel connection: put %v -> pool active %v", id, c.tunnelPool.Active())
}()
c.logger.Debug("Tunnel connection: %v <-> %v", remoteConn.LocalAddr(), remoteConn.RemoteAddr())
// 连接到目标TCP地址
targetConn, err := net.DialTimeout("tcp", c.targetTCPAddr.String(), tcpDialTimeout)
if err != nil {
c.logger.Error("Dial failed: %v", err)
return
}
defer func() {
if targetConn != nil {
targetConn.Close()
}
}()
c.targetTCPConn = targetConn.(*net.TCPConn)
c.logger.Debug("Target connection: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
c.logger.Debug("Starting exchange: %v <-> %v", remoteConn.LocalAddr(), targetConn.LocalAddr())
// 交换数据
rx, tx, _ := conn.DataExchange(remoteConn, targetConn, tcpReadTimeout)
// 交换完成,广播统计信息
c.logger.Event("Exchange complete: TRAFFIC_STATS|TCP_RX=%v|TCP_TX=%v|UDP_RX=0|UDP_TX=0", rx, tx)
}
// commonUDPOnce 共用处理单个UDP请求
func (c *Common) commonUDPOnce(id string) {
c.logger.Debug("UDP launch signal: %v <- %v", id, c.tunnelTCPConn.RemoteAddr())
// 从连接池获取连接
remoteConn := c.tunnelPool.ClientGet(id)
if remoteConn == nil {
c.logger.Error("Get failed: %v not found", id)
return
}
c.logger.Debug("Tunnel connection: get %v <- pool active %v", id, c.tunnelPool.Active())
defer func() {
c.tunnelPool.Put(id, remoteConn)
c.logger.Debug("Tunnel connection: put %v -> pool active %v", id, c.tunnelPool.Active())
}()
c.logger.Debug("Tunnel connection: %v <-> %v", remoteConn.LocalAddr(), remoteConn.RemoteAddr())
// 连接到目标UDP地址
targetConn, err := net.DialTimeout("udp", c.targetUDPAddr.String(), udpDialTimeout)
if err != nil {
c.logger.Error("Dial failed: %v", err)
return
}
defer func() {
if targetConn != nil {
targetConn.Close()
}
}()
c.targetUDPConn = targetConn.(*net.UDPConn)
c.logger.Debug("Target connection: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
c.logger.Debug("Starting transfer: %v <-> %v", remoteConn.LocalAddr(), targetConn.LocalAddr())
// 处理UDP/TCP数据传输
rx, tx, _ := conn.DataTransfer(
c.targetUDPConn,
remoteConn,
nil,
nil,
udpDataBufSize,
udpReadTimeout,
)
// 传输完成,广播统计信息
c.logger.Event("Transfer complete: TRAFFIC_STATS|TCP_RX=0|TCP_TX=0|UDP_RX=%v|UDP_TX=%v", rx, tx)
}
// singleLoop 单端转发处理循环
func (c *Common) singleLoop() error {
for {
select {
case <-c.ctx.Done():
return context.Canceled
default:
go func() {
c.errChan <- c.singleTCPLoop()
}()
go func() {
c.errChan <- c.singleUDPLoop()
}()
return <-c.errChan
}
}
}
// singleTCPLoop 单端转发TCP处理循环
func (c *Common) singleTCPLoop() error {
for {
select {
case <-c.ctx.Done():
return context.Canceled
default:
// 接受来自隧道的TCP连接
tunnelConn, err := c.tunnelListener.Accept()
if err != nil {
continue
}
defer func() {
if tunnelConn != nil {
tunnelConn.Close()
}
}()
c.tunnelTCPConn = tunnelConn.(*net.TCPConn)
c.logger.Debug("Tunnel connection: %v <-> %v", tunnelConn.LocalAddr(), tunnelConn.RemoteAddr())
// 使用信号量限制并发数
c.semaphore <- struct{}{}
go func(tunnelConn net.Conn) {
defer func() { <-c.semaphore }()
// 从连接池中获取连接
targetConn := c.tunnelPool.ClientGet("")
if targetConn == nil {
c.logger.Error("Get failed: no target connection available")
return
}
c.logger.Debug("Target connection: pool active %v / %v per %v", c.tunnelPool.Active(), c.tunnelPool.Capacity(), c.tunnelPool.Interval())
defer func() {
if targetConn != nil {
targetConn.Close()
}
}()
c.targetTCPConn = targetConn.(*net.TCPConn)
c.logger.Debug("Target connection: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
c.logger.Debug("Starting exchange: %v <-> %v", tunnelConn.LocalAddr(), targetConn.LocalAddr())
// 交换数据
rx, tx, _ := conn.DataExchange(tunnelConn, targetConn, tcpReadTimeout)
// 交换完成,广播统计信息
c.logger.Event("Exchange complete: TRAFFIC_STATS|TCP_RX=%v|TCP_TX=%v|UDP_RX=0|UDP_TX=0", rx, tx)
}(tunnelConn)
}
}
}
// singleUDPLoop 单端转发UDP处理循环
func (c *Common) singleUDPLoop() error {
for {
select {
case <-c.ctx.Done():
return context.Canceled
default:
buffer := make([]byte, udpDataBufSize)
// 读取来自隧道的UDP数据
rx, clientAddr, err := c.tunnelUDPConn.ReadFromUDP(buffer)
if err != nil {
continue
}
c.logger.Debug("Tunnel connection: %v <-> %v", c.tunnelUDPConn.LocalAddr(), clientAddr)
var targetConn *net.UDPConn
sessionKey := clientAddr.String()
// 获取或创建目标UDP会话
if session, ok := c.targetUDPSession.Load(sessionKey); ok {
// 复用现有会话
targetConn = session.(*net.UDPConn)
c.logger.Debug("Using UDP session: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
} else {
// 创建新的会话
session, err := net.DialTimeout("udp", c.targetUDPAddr.String(), udpDialTimeout)
if err != nil {
c.logger.Error("Dial failed: %v", err)
continue
}
c.targetUDPSession.Store(sessionKey, session)
targetConn = session.(*net.UDPConn)
c.logger.Debug("Target connection: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
// 使用信号量限制并发数
c.semaphore <- struct{}{}
go func(targetConn *net.UDPConn, clientAddr *net.UDPAddr, sessionKey string) {
defer func() { <-c.semaphore }()
buffer := make([]byte, udpDataBufSize)
for {
select {
case <-c.ctx.Done():
return
default:
// 设置UDP读取超时
if err := targetConn.SetReadDeadline(time.Now().Add(udpReadTimeout)); err != nil {
c.logger.Error("SetReadDeadline failed: %v", err)
c.targetUDPSession.Delete(sessionKey)
targetConn.Close()
return
}
// 从UDP读取响应
n, err := targetConn.Read(buffer)
if err != nil {
// 检查是否为超时错误
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
c.logger.Debug("UDP session abort: %v", err)
} else {
c.logger.Error("Read failed: %v", err)
}
c.targetUDPSession.Delete(sessionKey)
targetConn.Close()
return
}
// 将响应写回隧道UDP连接
tx, err := c.tunnelUDPConn.WriteToUDP(buffer[:n], clientAddr)
if err != nil {
c.logger.Error("WriteToUDP failed: %v", err)
c.targetUDPSession.Delete(sessionKey)
targetConn.Close()
return
}
// 传输完成,广播统计信息
c.logger.Event("Transfer complete: TRAFFIC_STATS|TCP_RX=0|TCP_TX=0|UDP_RX=0|UDP_TX=%v", tx)
}
}
}(targetConn, clientAddr, sessionKey)
}
// 将初始数据发送到目标UDP连接
c.logger.Debug("Starting transfer: %v <-> %v", targetConn.LocalAddr(), c.tunnelUDPConn.LocalAddr())
_, err = targetConn.Write(buffer[:rx])
if err != nil {
c.logger.Error("Write failed: %v", err)
c.targetUDPSession.Delete(sessionKey)
targetConn.Close()
return err
}
// 传输完成,广播统计信息
c.logger.Event("Transfer complete: TRAFFIC_STATS|TCP_RX=0|TCP_TX=0|UDP_RX=%v|UDP_TX=0", rx)
}
}
}

1384
nodepass/internal/master.go Normal file

File diff suppressed because it is too large Load Diff

175
nodepass/internal/server.go Normal file
View File

@@ -0,0 +1,175 @@
// 内部包,实现服务端模式功能
package internal
import (
"bufio"
"bytes"
"context"
"crypto/tls"
"net"
"net/url"
"os"
"os/signal"
"syscall"
"time"
"github.com/NodePassProject/logs"
"github.com/NodePassProject/pool"
)
// Server 实现服务端模式功能
type Server struct {
Common // 继承共享功能
tlsConfig *tls.Config // TLS配置
clientIP string // 客户端IP
}
// NewServer 创建新的服务端实例
func NewServer(parsedURL *url.URL, tlsCode string, tlsConfig *tls.Config, logger *logs.Logger) *Server {
server := &Server{
Common: Common{
tlsCode: tlsCode,
dataFlow: "+",
logger: logger,
semaphore: make(chan struct{}, semaphoreLimit),
signalChan: make(chan string, semaphoreLimit),
},
tlsConfig: tlsConfig,
}
// 初始化公共字段
server.getTunnelKey(parsedURL)
server.getAddress(parsedURL)
return server
}
// Run 管理服务端生命周期
func (s *Server) Run() {
s.logger.Info("Server started: %v@%v/%v", s.tunnelKey, s.tunnelAddr, s.targetTCPAddr)
// 启动服务端并处理重启
go func() {
for {
time.Sleep(serviceCooldown)
if err := s.start(); err != nil {
s.logger.Error("Server error: %v", err)
s.stop()
s.logger.Info("Server restarted: %v@%v/%v", s.tunnelKey, s.tunnelAddr, s.targetTCPAddr)
}
}
}()
// 监听系统信号以优雅关闭
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
<-ctx.Done()
stop()
// 执行关闭过程
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
defer cancel()
if err := s.shutdown(shutdownCtx, s.stop); err != nil {
s.logger.Error("Server shutdown error: %v", err)
} else {
s.logger.Info("Server shutdown complete")
}
}
// start 启动服务端
func (s *Server) start() error {
s.initContext()
// 初始化隧道监听器
if err := s.initTunnelListener(); err != nil {
return err
}
// 通过是否监听成功判断数据流向
if err := s.initTargetListener(); err == nil {
s.dataFlow = "-"
}
// 与客户端进行握手
if err := s.tunnelHandshake(); err != nil {
return err
}
// 握手之后把UDP监听关掉
if s.tunnelUDPConn != nil {
s.tunnelUDPConn.Close()
}
// 初始化隧道连接池
s.tunnelPool = pool.NewServerPool(
s.clientIP,
s.tlsConfig,
s.tunnelListener,
reportInterval)
go s.tunnelPool.ServerManager()
switch s.dataFlow {
case "-":
go s.commonLoop()
case "+":
go s.commonOnce()
go s.commonQueue()
}
return s.healthCheck()
}
// tunnelHandshake 与客户端进行握手
func (s *Server) tunnelHandshake() error {
// 接受隧道连接
for {
tunnelTCPConn, err := s.tunnelListener.Accept()
if err != nil {
s.logger.Error("Accept error: %v", err)
time.Sleep(serviceCooldown)
continue
}
tunnelTCPConn.SetReadDeadline(time.Now().Add(tcpReadTimeout))
bufReader := bufio.NewReader(tunnelTCPConn)
rawTunnelKey, err := bufReader.ReadString('\n')
if err != nil {
s.logger.Warn("Handshake timeout: %v", tunnelTCPConn.RemoteAddr())
tunnelTCPConn.Close()
time.Sleep(serviceCooldown)
continue
}
tunnelTCPConn.SetReadDeadline(time.Time{})
tunnelKey := string(s.xor(bytes.TrimSuffix([]byte(rawTunnelKey), []byte{'\n'})))
if tunnelKey != s.tunnelKey {
s.logger.Warn("Access denied: %v", tunnelTCPConn.RemoteAddr())
tunnelTCPConn.Close()
time.Sleep(serviceCooldown)
continue
} else {
s.tunnelTCPConn = tunnelTCPConn.(*net.TCPConn)
s.bufReader = bufio.NewReader(s.tunnelTCPConn)
s.tunnelTCPConn.SetKeepAlive(true)
s.tunnelTCPConn.SetKeepAlivePeriod(reportInterval)
// 记录客户端IP
s.clientIP = s.tunnelTCPConn.RemoteAddr().(*net.TCPAddr).IP.String()
break
}
}
// 构建并发送隧道URL到客户端
tunnelURL := &url.URL{
Host: s.dataFlow,
Fragment: s.tlsCode,
}
_, err := s.tunnelTCPConn.Write(append(s.xor([]byte(tunnelURL.String())), '\n'))
if err != nil {
return err
}
s.logger.Info("Tunnel signal -> : %v -> %v", tunnelURL.String(), s.tunnelTCPConn.RemoteAddr())
s.logger.Info("Tunnel handshaked: %v <-> %v", s.tunnelTCPConn.LocalAddr(), s.tunnelTCPConn.RemoteAddr())
return nil
}