This commit is contained in:
xvzc 2023-09-08 17:35:41 +09:00
parent c7774f6d99
commit 363f022c91
11 changed files with 90 additions and 56 deletions

View File

@ -1,3 +0,0 @@
FROM golang:1.17-alpine
WORKDIR /app

10
build
View File

@ -1,6 +1,8 @@
#!/bin/sh #!/bin/sh
docker build ./ --file ./Dockerfile.build --tag spoof-dpi:latest && \ docker run --rm \
docker run --rm \ -it \
-v $(pwd):/app spoof-dpi:latest \ --workdir /app/ \
sh make-releases.sh -v $(pwd):/app \
golang:1.17-alpine \
sh make-releases.sh

View File

@ -16,7 +16,7 @@ func main() {
util.ParseArgs() util.ParseArgs()
config := util.GetConfig() config := util.GetConfig()
p := proxy.New(*config.Addr, *config.Port) p := proxy.New(config)
doh.Init(*config.Dns) doh.Init(*config.Dns)
if *config.Debug { if *config.Debug {
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
@ -28,10 +28,10 @@ func main() {
FullTimestamp: true, FullTimestamp: true,
}) })
if *config.Banner { if *config.NoBanner {
util.PrintColoredBanner()
} else {
util.PrintSimpleInfo() util.PrintSimpleInfo()
} else {
util.PrintColoredBanner()
} }
if err := util.SetOsProxy(*config.Port); err != nil { if err := util.SetOsProxy(*config.Port); err != nil {

View File

@ -1,7 +1,7 @@
#!bin/bash #!bin/bash
curl "https://api.github.com/repos/xvzc/SpoofDPI/releases/latest" | curl "https://api.github.com/repos/xvzc/SpoofDPI/releases/latest" |
grep '"tag_name":' | grep '"tag_name":' |
sed -E 's/.*"([^"]+)".*/\1/' | sed -E 's/.*"([^"]+)".*/\1/' |
xargs -I {} curl -OL "https://github.com/xvzc/SpoofDPI/releases/download/"\{\}"/spoof-dpi-${1}.tar.gz" xargs -I {} curl -OL "https://github.com/xvzc/SpoofDPI/releases/download/"\{\}"/spoof-dpi-${1}.tar.gz"

View File

@ -59,7 +59,7 @@ func (conn *Conn) ReadBytes() ([]byte, error) {
return ret, nil return ret, nil
} }
func (lConn *Conn) HandleHttp(p *packet.HttpPacket) { func (lConn *Conn) HandleHttp(p *packet.HttpPacket, timeout int) {
p.Tidy() p.Tidy()
ip, err := doh.Lookup(p.Domain()) ip, err := doh.Lookup(p.Domain())
@ -93,7 +93,7 @@ func (lConn *Conn) HandleHttp(p *packet.HttpPacket) {
log.Debug("[HTTP] New connection to the server ", p.Domain(), " ", rConn.LocalAddr()) log.Debug("[HTTP] New connection to the server ", p.Domain(), " ", rConn.LocalAddr())
go rConn.Serve(lConn, "[HTTP]", lConn.RemoteAddr().String(), p.Domain()) go rConn.Serve(lConn, "[HTTP]", lConn.RemoteAddr().String(), p.Domain(), timeout)
_, err = rConn.Write(p.Raw()) _, err = rConn.Write(p.Raw())
if err != nil { if err != nil {
@ -103,11 +103,11 @@ func (lConn *Conn) HandleHttp(p *packet.HttpPacket) {
log.Debug("[HTTP] Sent a request to ", p.Domain()) log.Debug("[HTTP] Sent a request to ", p.Domain())
lConn.Serve(rConn, "[HTTP]", lConn.RemoteAddr().String(), p.Domain()) lConn.Serve(rConn, "[HTTP]", lConn.RemoteAddr().String(), p.Domain(), timeout)
} }
func (lConn *Conn) HandleHttps(p *packet.HttpPacket) { func (lConn *Conn) HandleHttps(p *packet.HttpPacket, timeout int) {
ip, err := doh.Lookup(p.Domain()) ip, err := doh.Lookup(p.Domain())
if err != nil { if err != nil {
log.Error("[HTTPS DOH] Error looking up for domain: ", p.Domain(), " ", err) log.Error("[HTTPS DOH] Error looking up for domain: ", p.Domain(), " ", err)
@ -162,21 +162,26 @@ func (lConn *Conn) HandleHttps(p *packet.HttpPacket) {
chunks := pkt.SplitInChunks() chunks := pkt.SplitInChunks()
go rConn.Serve(lConn, "[HTTPS]", rConn.RemoteAddr().String(), p.Domain()) go rConn.Serve(lConn, "[HTTPS]", rConn.RemoteAddr().String(), p.Domain(), timeout)
if _, err := rConn.WriteChunks(chunks); err != nil { if _, err := rConn.WriteChunks(chunks); err != nil {
log.Debug("[HTTPS] Error writing client hello to ", p.Domain(), err) log.Debug("[HTTPS] Error writing client hello to ", p.Domain(), err)
return return
} }
lConn.Serve(rConn, "[HTTPS]", lConn.RemoteAddr().String(), p.Domain()) lConn.Serve(rConn, "[HTTPS]", lConn.RemoteAddr().String(), p.Domain(), timeout)
} }
func (from *Conn) Serve(to *Conn, proto string, fd string, td string) { func (from *Conn) Serve(to *Conn, proto string, fd string, td string, timeout int) {
proto += " " proto += " "
for { for {
from.SetReadDeadline(time.Now().Add(2000 * time.Millisecond)) if timeout > 0 {
from.SetReadDeadline(
time.Now().Add(time.Millisecond * time.Duration(timeout)),
)
}
buf, err := from.ReadBytes() buf, err := from.ReadBytes()
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {

View File

@ -1,22 +1,26 @@
package proxy package proxy
import ( import (
"fmt"
"os" "os"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/xvzc/SpoofDPI/net" "github.com/xvzc/SpoofDPI/net"
"github.com/xvzc/SpoofDPI/packet" "github.com/xvzc/SpoofDPI/packet"
"github.com/xvzc/SpoofDPI/util"
) )
type Proxy struct { type Proxy struct {
addr string addr string
port int port int
timeout int
} }
func New(addr string, port int) *Proxy { func New(config *util.Config) *Proxy {
return &Proxy{ return &Proxy{
addr: addr, addr: *config.Addr,
port: port, port: *config.Port,
timeout: *config.Timeout,
} }
} }
@ -35,7 +39,11 @@ func (p *Proxy) Start() {
os.Exit(1) os.Exit(1)
} }
log.Println("Created a listener on :", p.Port()) if p.timeout > 0 {
log.Println(fmt.Sprintf("Connection timeout is set to %dms", p.timeout))
}
log.Println("Created a listener on port", p.Port())
for { for {
conn, err := l.Accept() conn, err := l.Accept()
@ -65,10 +73,10 @@ func (p *Proxy) Start() {
if pkt.IsConnectMethod() { if pkt.IsConnectMethod() {
log.Debug("[HTTPS] Start") log.Debug("[HTTPS] Start")
conn.HandleHttps(pkt) conn.HandleHttps(pkt, p.timeout)
} else { } else {
log.Debug("[HTTP] Start") log.Debug("[HTTP] Start")
conn.HandleHttp(pkt) conn.HandleHttp(pkt, p.timeout)
} }
}() }()
} }

View File

@ -52,9 +52,11 @@ You can also build your own
Usage: spoof-dpi [options...] Usage: spoof-dpi [options...]
--addr=<addr> | default: 127.0.0.1 --addr=<addr> | default: 127.0.0.1
--dns=<addr> | default: 8.8.8.8 --dns=<addr> | default: 8.8.8.8
--port=<port> | default: 8080 --port=<number> | default: 8080
--debug=<bool> | default: false --debug=<bool> | default: false
--banner=<bool> | default: true --no-banner=<bool> | default: false
--timeout=<number> | default: 0
| Enforces specific connection timeout. Set 0 to turn off
--url=<url> | Can be used multiple times. If set, --url=<url> | Can be used multiple times. If set,
| it will bypass DPI only for this url. | it will bypass DPI only for this url.
| Example: --url=google.com --url=github.com | Example: --url=google.com --url=github.com

View File

@ -50,11 +50,19 @@ wget -O - https://raw.githubusercontent.com/xvzc/SpoofDPI/main/install.sh | bash
# 사용법 # 사용법
``` ```
Usage: spoof-dpi [options...] Usage: spoof-dpi [options...]
--addr=<addr> | default: 127.0.0.1 --addr=<addr> | default: 127.0.0.1
--dns=<addr> | default: 8.8.8.8 --dns=<addr> | default: 8.8.8.8
--port=<port> | default: 8080 --port=<number> | default: 8080
--debug=<bool> | default: false --debug=<bool> | default: false
--banner=<bool> | default: true --no-banner=<bool> | default: false
--timeout=<number> | default: 0
| Enforces specific connection timeout. Set 0 to turn off
--url=<url> | Can be used multiple times. If set,
| it will bypass DPI only for this url.
| Example: --url=google.com --url=github.com
--pattern=<regex> | If set, it will bypass DPI only for packets
| that matches this regex pattern.
| Example: --pattern="google|github"
``` ```
> 만약 브라우저에서 Hotspot Shield와 같은 크롬 VPN 확장프로그램을 사용중이라면 > 만약 브라우저에서 Hotspot Shield와 같은 크롬 VPN 확장프로그램을 사용중이라면
Settings > Extension 으로 이동해 비활성화 해주시기바랍니다. Settings > Extension 으로 이동해 비활성화 해주시기바랍니다.

View File

@ -53,9 +53,11 @@ wget -O - https://raw.githubusercontent.com/xvzc/SpoofDPI/main/install.sh | bash
Usage: spoof-dpi [options...] Usage: spoof-dpi [options...]
--addr=<addr> | default: 127.0.0.1 --addr=<addr> | default: 127.0.0.1
--dns=<addr> | default: 8.8.8.8 --dns=<addr> | default: 8.8.8.8
--port=<port> | default: 8080 --port=<number> | default: 8080
--debug=<bool> | default: false --debug=<bool> | default: false
--banner=<bool> | default: true --no-banner=<bool> | default: false
--timeout=<number> | default: 0
| Enforces specific connection timeout. Set 0 to turn off
--url=<url> | Can be used multiple times. If set, --url=<url> | Can be used multiple times. If set,
| it will bypass DPI only for this url. | it will bypass DPI only for this url.
| Example: --url=google.com --url=github.com | Example: --url=google.com --url=github.com

View File

@ -57,11 +57,19 @@ You can also build your own
``` ```
Usage: spoof-dpi [options...] Usage: spoof-dpi [options...]
--addr=<addr> | default: 127.0.0.1 --addr=<addr> | default: 127.0.0.1
--dns=<addr> | default: 8.8.8.8 --dns=<addr> | default: 8.8.8.8
--port=<port> | default: 8080 --port=<number> | default: 8080
--debug=<bool> | default: false --debug=<bool> | default: false
--banner=<bool> | default: true --no-banner=<bool> | default: false
--timeout=<number> | default: 0
| Enforces specific connection timeout. Set 0 to turn off
--url=<url> | Can be used multiple times. If set,
| it will bypass DPI only for this url.
| Example: --url=google.com --url=github.com
--pattern=<regex> | If set, it will bypass DPI only for packets
| that matches this regex pattern.
| Example: --pattern="google|github"
``` ```
> 如果你在 Chrome 浏览器使用其他 VPN 扩展比如 Hotspot Shield 请去 设置 > 扩展程序禁用它们 > 如果你在 Chrome 浏览器使用其他 VPN 扩展比如 Hotspot Shield 请去 设置 > 扩展程序禁用它们

View File

@ -15,7 +15,8 @@ type Config struct {
Port *int Port *int
Dns *string Dns *string
Debug *bool Debug *bool
Banner *bool NoBanner *bool
Timeout *int
AllowedPattern *regexp.Regexp AllowedPattern *regexp.Regexp
AllowedUrls *regexp.Regexp AllowedUrls *regexp.Regexp
} }
@ -54,7 +55,8 @@ func ParseArgs() {
config.Port = flag.Int("port", 8080, "port") config.Port = flag.Int("port", 8080, "port")
config.Dns = flag.String("dns", "8.8.8.8", "DNS server") config.Dns = flag.String("dns", "8.8.8.8", "DNS server")
config.Debug = flag.Bool("debug", false, "true | false") config.Debug = flag.Bool("debug", false, "true | false")
config.Banner = flag.Bool("banner", true, "true | false") config.NoBanner = flag.Bool("no-banner", false, "true | false")
config.Timeout = flag.Int("timeout", 0, "timeout in milliseconds")
flag.Var(&allowedHosts, "url", "Bypass DPI only on this url, can be passed multiple times") flag.Var(&allowedHosts, "url", "Bypass DPI only on this url, can be passed multiple times")
allowedPattern = flag.String( allowedPattern = flag.String(
@ -86,26 +88,26 @@ func PrintColoredBanner() {
pterm.DefaultBigText.WithLetters(cyan, purple).Render() pterm.DefaultBigText.WithLetters(cyan, purple).Render()
pterm.DefaultBulletList.WithItems([]pterm.BulletListItem{ pterm.DefaultBulletList.WithItems([]pterm.BulletListItem{
{Level: 0, Text: "ADDR : " + *config.Addr}, {Level: 0, Text: "ADDR : " + fmt.Sprint(*config.Addr)},
{Level: 0, Text: "PORT : " + fmt.Sprint(*config.Port)}, {Level: 0, Text: "PORT : " + fmt.Sprint(*config.Port)},
{Level: 0, Text: "DNS : " + *config.Dns}, {Level: 0, Text: "DNS : " + fmt.Sprint(*config.Dns)},
{Level: 0, Text: "DEBUG : " + fmt.Sprint(*config.Debug)}, {Level: 0, Text: "DEBUG : " + fmt.Sprint(*config.Debug)},
}).Render() }).Render()
if allowedHosts != nil && len(allowedHosts) > 0 { if allowedHosts != nil && len(allowedHosts) > 0 {
log.Info("White listed urls: ", allowedHosts) log.Info("White listed urls: ", allowedHosts)
} }
if *allowedPattern != "" { if *allowedPattern != "" {
log.Info("Regex Pattern: ", *allowedPattern) log.Info("Regex Pattern: ", *allowedPattern)
} }
} }
func PrintSimpleInfo() { func PrintSimpleInfo() {
fmt.Println("") fmt.Println("")
fmt.Println("- ADDR : ", *config.Addr) fmt.Println("- ADDR : ", *config.Addr)
fmt.Println("- PORT : ", *config.Port) fmt.Println("- PORT : ", *config.Port)
fmt.Println("- DNS : ", *config.Dns) fmt.Println("- DNS : ", *config.Dns)
fmt.Println("- DEBUG : ", *config.Debug) fmt.Println("- DEBUG : ", *config.Debug)
fmt.Println("") fmt.Println("")
} }