Skip to content

Commit

Permalink
Merge pull request #427 from ehang-io/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
ffdfgdfg authored Mar 1, 2020
2 parents 2f9ee71 + 7014f91 commit 8e65577
Show file tree
Hide file tree
Showing 76 changed files with 13,938 additions and 26,030 deletions.
2 changes: 1 addition & 1 deletion Dockerfile.npc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang as builder
FROM golang:1.13.8 as builder
WORKDIR /go/src/ehang.io/nps
COPY . .
RUN go get -d -v ./...
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.nps
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang as builder
FROM golang:1.13.8 as builder
WORKDIR /go/src/ehang.io/nps
COPY . .
RUN go get -d -v ./...
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ For linux、darwin ```sudo ./nps install```

For windows, run cmd as administrator and enter the installation directory ```nps.exe install```

- default ports

The default configuration file of nps use 80,443,8080,8024 ports

80 and 443 ports for host mode default ports

8080 for web management access port

8024 for net bridge port, to communicate between server and client

- start up

For linux、darwin ```sudo nps start```
Expand Down
10 changes: 10 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ nps是一款轻量级、高性能、功能强大的**内网穿透**代理服务

对于windows,管理员身份运行cmd,进入安装目录 ```nps.exe install```

- 默认端口

nps默认配置文件使用了80,443,8080,8024端口

80与443端口为域名解析模式默认端口

8080为web管理访问端口

8024为网桥端口,用于客户端与服务器通信

- 启动

对于linux|darwin ```sudo nps start```
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#/bash/sh
export VERSION=0.26.3
export VERSION=0.26.4

sudo apt-get install gcc-mingw-w64-i686
env GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc go build -ldflags "-s -w -extldflags -static -extldflags -static" -buildmode=c-shared -o npc_sdk.dll cmd/npc/sdk.go
Expand Down
26 changes: 12 additions & 14 deletions client/control.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"bufio"
"encoding/base64"
"encoding/binary"
"errors"
Expand All @@ -11,7 +12,6 @@ import (
"math/rand"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
Expand Down Expand Up @@ -253,30 +253,28 @@ func NewConn(tp string, vkey string, server string, connType string, proxyUrl st

//http proxy connection
func NewHttpProxyConn(url *url.URL, remoteAddr string) (net.Conn, error) {
req := &http.Request{
Method: "CONNECT",
URL: url,
Host: remoteAddr,
Header: http.Header{},
Proto: "HTTP/1.1",
}
password, _ := url.User.Password()
req.Header.Set("Authorization", "Basic "+basicAuth(strings.Trim(url.User.Username(), " "), password))
b, err := httputil.DumpRequest(req, false)
req, err := http.NewRequest("CONNECT", "http://"+remoteAddr, nil)
if err != nil {
return nil, err
}
password, _ := url.User.Password()
req.Header.Set("Authorization", "Basic "+basicAuth(strings.Trim(url.User.Username(), " "), password))
// we make a http proxy request
proxyConn, err := net.Dial("tcp", url.Host)
if err != nil {
return nil, err
}
if _, err := proxyConn.Write(b); err != nil {
if err := req.Write(proxyConn); err != nil {
return nil, err
}
buf := make([]byte, 1024)
if _, err := proxyConn.Read(buf); err != nil {
res, err := http.ReadResponse(bufio.NewReader(proxyConn), req)
if err != nil {
return nil, err
}
_ = res.Body.Close()
if res.StatusCode != 200 {
return nil, errors.New("Proxy error " + res.Status)
}
return proxyConn, nil
}

Expand Down
75 changes: 43 additions & 32 deletions cmd/npc/npc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/ccding/go-stun/stun"
"github.com/kardianos/service"
"os"
"os/exec"
"runtime"
"strings"
"sync"
Expand All @@ -35,33 +36,9 @@ var (
logPath = flag.String("log_path", "", "npc log path")
debug = flag.Bool("debug", true, "npc debug")
pprofAddr = flag.String("pprof", "", "PProf debug addr (ip:port)")
stunAddr = flag.String("stun_addr", "stun.stunprotocol.org:3478", "stun server address (eg:stun.stunprotocol.org:3478)")
)

const systemdScript = `[Unit]
Description={{.Description}}
ConditionFileIsExecutable={{.Path|cmdEscape}}
{{range $i, $dep := .Dependencies}}
{{$dep}} {{end}}
[Service]
LimitNOFILE=65536
StartLimitInterval=5
StartLimitBurst=10
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
{{if .UserName}}User={{.UserName}}{{end}}
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
{{if and .LogOutput .HasOutputFileSupport -}}
StandardOutput=file:/var/log/{{.Name}}.out
StandardError=file:/var/log/{{.Name}}.err
{{- end}}
Restart=always
RestartSec=120
[Install]
WantedBy=multi-user.target
`

func main() {
flag.Parse()
logs.Reset()
Expand Down Expand Up @@ -91,7 +68,8 @@ func main() {
svcConfig.Dependencies = []string{
"Requires=network.target",
"After=network-online.target syslog.target"}
svcConfig.Option["SystemdScript"] = systemdScript
svcConfig.Option["SystemdScript"] = install.SystemdScript
svcConfig.Option["SysvScript"] = install.SysvScript
}
for _, v := range os.Args[1:] {
switch v {
Expand Down Expand Up @@ -130,23 +108,56 @@ func main() {
install.UpdateNpc()
return
case "nat":
nat, host, err := stun.NewClient().Discover()
c := stun.NewClient()
c.SetServerAddr(*stunAddr)
nat, host, err := c.Discover()
if err != nil || host == nil {
logs.Error("get nat type error", err)
return
}
fmt.Printf("nat type: %s \npublic address: %s\n", nat.String(), host.String())
os.Exit(0)
case "install", "start", "stop", "uninstall", "restart":
if os.Args[1] == "install" {
service.Control(s, "stop")
service.Control(s, "uninstall")
install.InstallNpc()
case "start", "stop", "restart":
// support busyBox and sysV, for openWrt
if service.Platform() == "unix-systemv" {
logs.Info("unix-systemv service")
cmd := exec.Command("/etc/init.d/"+svcConfig.Name, os.Args[1])
err := cmd.Run()
if err != nil {
logs.Error(err)
}
return
}
err := service.Control(s, os.Args[1])
if err != nil {
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
}
return
case "install":
service.Control(s, "stop")
service.Control(s, "uninstall")
install.InstallNpc()
err := service.Control(s, os.Args[1])
if err != nil {
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
}
if service.Platform() == "unix-systemv" {
logs.Info("unix-systemv service")
confPath := "/etc/init.d/" + svcConfig.Name
os.Symlink(confPath, "/etc/rc.d/S90"+svcConfig.Name)
os.Symlink(confPath, "/etc/rc.d/K02"+svcConfig.Name)
}
return
case "uninstall":
err := service.Control(s, os.Args[1])
if err != nil {
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
}
if service.Platform() == "unix-systemv" {
logs.Info("unix-systemv service")
os.Remove("/etc/rc.d/S90" + svcConfig.Name)
os.Remove("/etc/rc.d/K02" + svcConfig.Name)
}
return
}
}
Expand Down
57 changes: 30 additions & 27 deletions cmd/nps/nps.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"flag"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
Expand All @@ -29,31 +30,6 @@ var (
level string
)

const systemdScript = `[Unit]
Description={{.Description}}
ConditionFileIsExecutable={{.Path|cmdEscape}}
{{range $i, $dep := .Dependencies}}
{{$dep}} {{end}}
[Service]
LimitNOFILE=65536
StartLimitInterval=5
StartLimitBurst=10
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
{{if .UserName}}User={{.UserName}}{{end}}
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
{{if and .LogOutput .HasOutputFileSupport -}}
StandardOutput=file:/var/log/{{.Name}}.out
StandardError=file:/var/log/{{.Name}}.err
{{- end}}
Restart=always
RestartSec=120
[Install]
WantedBy=multi-user.target
`

func main() {
flag.Parse()
// init log
Expand Down Expand Up @@ -92,7 +68,8 @@ func main() {
svcConfig.Dependencies = []string{
"Requires=network.target",
"After=network-online.target syslog.target"}
svcConfig.Option["SystemdScript"] = systemdScript
svcConfig.Option["SystemdScript"] = install.SystemdScript
svcConfig.Option["SysvScript"] = install.SysvScript
}
prg := &nps{}
prg.exit = make(chan struct{})
Expand Down Expand Up @@ -127,12 +104,38 @@ func main() {
if err != nil {
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
}
if service.Platform() == "unix-systemv" {
logs.Info("unix-systemv service")
confPath := "/etc/init.d/" + svcConfig.Name
os.Symlink(confPath, "/etc/rc.d/S90"+svcConfig.Name)
os.Symlink(confPath, "/etc/rc.d/K02"+svcConfig.Name)
}
return
case "start", "restart", "stop":
if service.Platform() == "unix-systemv" {
logs.Info("unix-systemv service")
cmd := exec.Command("/etc/init.d/"+svcConfig.Name, os.Args[1])
err := cmd.Run()
if err != nil {
logs.Error(err)
}
return
}
err := service.Control(s, os.Args[1])
if err != nil {
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
}
return
case "start", "restart", "stop", "uninstall":
case "uninstall":
err := service.Control(s, os.Args[1])
if err != nil {
logs.Error("Valid actions: %q\n%s", service.ControlAction, err.Error())
}
if service.Platform() == "unix-systemv" {
logs.Info("unix-systemv service")
os.Remove("/etc/rc.d/S90" + svcConfig.Name)
os.Remove("/etc/rc.d/K02" + svcConfig.Name)
}
return
case "update":
install.UpdateNps()
Expand Down
2 changes: 1 addition & 1 deletion docs/_coverpage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![logo](logo.svg)

# NPS <small>0.26.3</small>
# NPS <small>0.26.4</small>

> 一款轻量级、高性能、功能强大的内网穿透代理服务器
Expand Down
3 changes: 3 additions & 0 deletions docs/_navbar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* [![GitHub stars](https://img.shields.io/github/stars/ehang-io/nps?style=social)](https://github.com/ehang-io/nps/stargazers)

* [![GitHub forks](https://img.shields.io/github/forks/ehang-io/nps?style=social)](https://github.com/ehang-io/nps/network)
6 changes: 5 additions & 1 deletion docs/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

**适用范围:** 小程序开发、微信公众号开发、产品演示

**注意:域名解析模式为http反向代理,不是dns服务器,在web上能够轻松灵活配置**

**假设场景:**
- 有一个域名proxy.com,有一台公网机器ip为1.1.1.1
- 两个内网开发站点127.0.0.1:81,127.0.0.1:82
Expand Down Expand Up @@ -77,6 +79,8 @@
- 在刚才创建的客户端隧道管理中添加一条http代理,填写监听的端口(8004),保存。
- 在外网环境的本机配置http代理,ip为公网服务器ip(1.1.1.1),端口为填写的监听端口(8004),即可访问了

**注意:对于私密代理与p2p,除了统一配置的客户端和服务端,还需要一个客户端作为访问端提供一个端口来访问**

## 私密代理

**适用范围:** 无需占用多余的端口、安全性要求较高可以防止其他人连接的tcp服务,例如ssh。
Expand All @@ -95,7 +99,7 @@

**注意:** password为web管理上添加的唯一密钥,具体命令可查看web管理上的命令提示

假设10.1.50.2用户名为root,现在执行`ssh -p 2000 root@1.1.1.1`即可访问ssh
假设10.1.50.2用户名为root,现在执行`ssh -p 2000 root@127.0.0.1`即可访问ssh


## p2p服务
Expand Down
1 change: 1 addition & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
repo: '',
loadSidebar: true,
coverpage: true,
loadNavbar: true,
subMaxLevel: 2,
maxLevel: 4,
search: {
Expand Down
4 changes: 2 additions & 2 deletions docs/npc_extend.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# 增强功能
## nat类型检测
```
./npc nat
./npc nat -stun_addr=stun.stunprotocol.org:3478
```
如果p2p双方都是Symmetric Nat,肯定不能成功,其他组合都有较大成功率。
如果p2p双方都是Symmetric Nat,肯定不能成功,其他组合都有较大成功率。`stun_addr`可以指定stun服务器地址。
## 状态检查
```
./npc status -config=npc配置文件路径
Expand Down
Loading

0 comments on commit 8e65577

Please sign in to comment.