feat: update build workflow, enhance README, and modify license for version 1.4-01
Build and Release / release (push) Successful in 1m36s
Build and Release / release (push) Successful in 1m36s
This commit is contained in:
+48
-48
@@ -1,48 +1,48 @@
|
|||||||
name: Build and Release
|
name: Build and Release
|
||||||
run-name: ${{ gitea.actor }} build 🚀
|
run-name: ${{ gitea.actor }} build 🚀
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: azenkain/go-node:latest
|
image: azenkain/go-node:latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Download Go dependencies
|
- name: Download Go dependencies
|
||||||
run: go mod download
|
run: go mod download
|
||||||
|
|
||||||
- name: Build for Windows x64
|
- name: Build for Windows x64
|
||||||
run: GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-windows-amd64.exe .
|
run: GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-windows-amd64.exe .
|
||||||
|
|
||||||
- name: Build for Windows ARM64
|
- name: Build for Windows ARM64
|
||||||
run: GOOS=windows GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-windows-arm64.exe .
|
run: GOOS=windows GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-windows-arm64.exe .
|
||||||
|
|
||||||
- name: Build for macOS x64
|
- name: Build for macOS x64
|
||||||
run: GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-macos-amd64 .
|
run: GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-macos-amd64 .
|
||||||
|
|
||||||
- name: Build for macOS ARM64
|
- name: Build for macOS ARM64
|
||||||
run: GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-macos-arm64 .
|
run: GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-macos-arm64 .
|
||||||
|
|
||||||
- name: Build for Linux x64
|
- name: Build for Linux x64
|
||||||
run: GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-linux-amd64 .
|
run: GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-linux-amd64 .
|
||||||
|
|
||||||
- name: Build for Linux ARM64
|
- name: Build for Linux ARM64
|
||||||
run: GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-linux-arm64 .
|
run: GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o firefly-go-proxy-linux-arm64 .
|
||||||
|
|
||||||
- name: Grant execute permissions
|
- name: Grant execute permissions
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./script/publish/publish-script
|
chmod +x ./script/publish/publish-script
|
||||||
|
|
||||||
- name: Publish components to API
|
- name: Publish components to API
|
||||||
run: ./script/publish/publish-script
|
run: ./script/publish/publish-script
|
||||||
env:
|
env:
|
||||||
ENV_ROBOT_TOKEN: ${{ secrets.ENV_ROBOT_TOKEN }}
|
ENV_ROBOT_TOKEN: ${{ secrets.ENV_ROBOT_TOKEN }}
|
||||||
ENV_GAME_IDS: ${{ secrets.ENV_GAME_IDS }}
|
ENV_GAME_IDS: ${{ secrets.ENV_GAME_IDS }}
|
||||||
ENV_COMPONENT_TYPE: PROXY
|
ENV_COMPONENT_TYPE: PROXY
|
||||||
ENV_FILES: "firefly-go-proxy-windows-amd64.exe,firefly-go-proxy-windows-arm64.exe,firefly-go-proxy-macos-amd64,firefly-go-proxy-macos-arm64,firefly-go-proxy-linux-amd64,firefly-go-proxy-linux-arm64"
|
ENV_FILES: "firefly-go-proxy-windows-amd64.exe,firefly-go-proxy-windows-arm64.exe,firefly-go-proxy-macos-amd64,firefly-go-proxy-macos-arm64,firefly-go-proxy-linux-amd64,firefly-go-proxy-linux-arm64"
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2025 Firefly-Shelter
|
Copyright (c) 2025 Firefly-Shelter
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||||
following conditions:
|
following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||||
portions of the Software.
|
portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||||
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ build_mac_arm64:
|
|||||||
build_ico:
|
build_ico:
|
||||||
@echo Building application icon...
|
@echo Building application icon...
|
||||||
magick logo.jpg -define icon:auto-resize=256,128,64,48,32,16 ./logo.ico
|
magick logo.jpg -define icon:auto-resize=256,128,64,48,32,16 ./logo.ico
|
||||||
@echo Done!
|
@echo Done!
|
||||||
|
|
||||||
set_logo:
|
set_logo:
|
||||||
@echo Embedding application icon...
|
@echo Embedding application icon...
|
||||||
go-winres simply --icon ./logo.ico
|
go-winres simply --icon ./logo.ico
|
||||||
@echo Done!
|
@echo Done!
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
# Firefly Go Proxy
|
# Firefly Go Proxy
|
||||||
|
|
||||||
A lightweight HTTP/HTTPS proxy server with domain redirection and request blocking capabilities. This tool is designed to help with local development and testing by intercepting and modifying HTTP/HTTPS traffic.
|
A lightweight HTTP/HTTPS proxy server with domain redirection and request blocking capabilities. This tool is designed to help with local development and testing by intercepting and modifying HTTP/HTTPS traffic.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- HTTP/HTTPS proxy with MITM support
|
- HTTP/HTTPS proxy with MITM support
|
||||||
- Domain-based request redirection
|
- Domain-based request redirection
|
||||||
- URL pattern blocking
|
- URL pattern blocking
|
||||||
- Automatic certificate management
|
- Automatic certificate management
|
||||||
- Cross-platform support (Windows, macOS, Linux)
|
- Cross-platform support (Windows, macOS, Linux)
|
||||||
- System proxy configuration
|
- System proxy configuration
|
||||||
- Automatic admin prompt on macOS/Linux for certificate/proxy setup
|
- Automatic admin prompt on macOS/Linux for certificate/proxy setup
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Go 1.22 or higher
|
- Go 1.22 or higher
|
||||||
- Git
|
- Git
|
||||||
|
|
||||||
### Building from source
|
### Building from source
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd firefly-go-proxy
|
cd firefly-go-proxy
|
||||||
go build
|
go build
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Basic usage
|
### Basic usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./firefly-proxy [flags] //linux|macos
|
./firefly-proxy [flags] //linux|macos
|
||||||
./firefly-proxy.exe [flags] //windows
|
./firefly-proxy.exe [flags] //windows
|
||||||
```
|
```
|
||||||
|
|
||||||
### Available Flags
|
### Available Flags
|
||||||
|
|
||||||
- `-r`: Redirect target host (default: "127.0.0.1:21000")
|
- `-r`: Redirect target host (default: "127.0.0.1:21000")
|
||||||
- `-b`: Comma-separated list of blocked ports
|
- `-b`: Comma-separated list of blocked ports
|
||||||
- `-p`: Proxy listen port (default: auto)
|
- `-p`: Proxy listen port (default: auto)
|
||||||
@@ -44,25 +44,25 @@ go build
|
|||||||
- `-no-sys`: Run only the proxy server; skip certificate installation, system proxy setup, and macOS/Linux admin relaunch
|
- `-no-sys`: Run only the proxy server; skip certificate installation, system proxy setup, and macOS/Linux admin relaunch
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
1. Start proxy with default settings:
|
1. Start proxy with default settings:
|
||||||
```bash
|
```bash
|
||||||
./firefly-proxy //linux|macos
|
./firefly-proxy //linux|macos
|
||||||
./firefly-proxy.exe //windows
|
./firefly-proxy.exe //windows
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Redirect traffic to a different host:
|
2. Redirect traffic to a different host:
|
||||||
```bash
|
```bash
|
||||||
./firefly-proxy -r 192.168.1.100:8080 //linux|macos
|
./firefly-proxy -r 192.168.1.100:8080 //linux|macos
|
||||||
./firefly-proxy.exe -r 192.168.1.100:8080 //windows
|
./firefly-proxy.exe -r 192.168.1.100:8080 //windows
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Block specific ports:
|
3. Block specific ports:
|
||||||
```bash
|
```bash
|
||||||
./firefly-proxy -b "80,443,8080" //linux|macos
|
./firefly-proxy -b "80,443,8080" //linux|macos
|
||||||
./firefly-proxy.exe -b "80,443,8080" //windows
|
./firefly-proxy.exe -b "80,443,8080" //windows
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Run an executable with admin privileges:
|
4. Run an executable with admin privileges:
|
||||||
```bash
|
```bash
|
||||||
./firefly-proxy -e "/path/to/your/executable" //linux|macos
|
./firefly-proxy -e "/path/to/your/executable" //linux|macos
|
||||||
@@ -82,17 +82,17 @@ go build
|
|||||||
./firefly-proxy -no-sys -p 8888 //linux|macos
|
./firefly-proxy -no-sys -p 8888 //linux|macos
|
||||||
./firefly-proxy.exe -no-sys -p 8888 //windows
|
./firefly-proxy.exe -no-sys -p 8888 //windows
|
||||||
```
|
```
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
The proxy intercepts HTTP/HTTPS traffic and can:
|
The proxy intercepts HTTP/HTTPS traffic and can:
|
||||||
- Redirect requests based on domain names
|
- Redirect requests based on domain names
|
||||||
- Block specific URLs or patterns
|
- Block specific URLs or patterns
|
||||||
- Handle SSL/TLS connections with custom CA certificates
|
- Handle SSL/TLS connections with custom CA certificates
|
||||||
- Automatically configure system proxy settings
|
- Automatically configure system proxy settings
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CertStorage struct {
|
type CertStorage struct {
|
||||||
certs map[string]*tls.Certificate
|
certs map[string]*tls.Certificate
|
||||||
mtx sync.RWMutex
|
mtx sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *CertStorage) Fetch(hostname string, gen func() (*tls.Certificate, error)) (*tls.Certificate, error) {
|
func (cs *CertStorage) Fetch(hostname string, gen func() (*tls.Certificate, error)) (*tls.Certificate, error) {
|
||||||
cs.mtx.RLock()
|
cs.mtx.RLock()
|
||||||
cert, ok := cs.certs[hostname]
|
cert, ok := cs.certs[hostname]
|
||||||
cs.mtx.RUnlock()
|
cs.mtx.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := gen()
|
cert, err := gen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs.mtx.Lock()
|
cs.mtx.Lock()
|
||||||
cs.certs[hostname] = cert
|
cs.certs[hostname] = cert
|
||||||
cs.mtx.Unlock()
|
cs.mtx.Unlock()
|
||||||
|
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCertStorage() *CertStorage {
|
func NewCertStorage() *CertStorage {
|
||||||
return &CertStorage{
|
return &CertStorage{
|
||||||
certs: make(map[string]*tls.Certificate),
|
certs: make(map[string]*tls.Certificate),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+62
-62
@@ -1,62 +1,62 @@
|
|||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func installCA(absPath string) error {
|
func installCA(absPath string) error {
|
||||||
// Detect distro
|
// Detect distro
|
||||||
data, err := os.ReadFile("/etc/os-release")
|
data, err := os.ReadFile("/etc/os-release")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot detect distro: %v", err)
|
return fmt.Errorf("cannot detect distro: %v", err)
|
||||||
}
|
}
|
||||||
content := string(data)
|
content := string(data)
|
||||||
|
|
||||||
// Debian/Ubuntu/Kali
|
// Debian/Ubuntu/Kali
|
||||||
if strings.Contains(content, "ID=debian") ||
|
if strings.Contains(content, "ID=debian") ||
|
||||||
strings.Contains(content, "ID=ubuntu") ||
|
strings.Contains(content, "ID=ubuntu") ||
|
||||||
strings.Contains(content, "ID=kali") {
|
strings.Contains(content, "ID=kali") {
|
||||||
|
|
||||||
destDir := "/usr/local/share/ca-certificates"
|
destDir := "/usr/local/share/ca-certificates"
|
||||||
if err := os.MkdirAll(destDir, 0755); err != nil {
|
if err := os.MkdirAll(destDir, 0755); err != nil {
|
||||||
return fmt.Errorf("failed to create cert dir: %v", err)
|
return fmt.Errorf("failed to create cert dir: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := filepath.Base(absPath)
|
filename := filepath.Base(absPath)
|
||||||
destPath := filepath.Join(destDir, filename)
|
destPath := filepath.Join(destDir, filename)
|
||||||
|
|
||||||
inputData, err := os.ReadFile(absPath)
|
inputData, err := os.ReadFile(absPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read source file: %v", err)
|
return fmt.Errorf("failed to read source file: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(destPath, inputData, 0644); err != nil {
|
if err := os.WriteFile(destPath, inputData, 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write cert file to system: %v", err)
|
return fmt.Errorf("failed to write cert file to system: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Updating certificates for Debian/Ubuntu...\n")
|
fmt.Printf("Updating certificates for Debian/Ubuntu...\n")
|
||||||
cmd := exec.Command("update-ca-certificates")
|
cmd := exec.Command("update-ca-certificates")
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arch / Manjaro
|
// Arch / Manjaro
|
||||||
if strings.Contains(content, "ID=arch") ||
|
if strings.Contains(content, "ID=arch") ||
|
||||||
strings.Contains(content, "ID=manjaro") {
|
strings.Contains(content, "ID=manjaro") {
|
||||||
|
|
||||||
cmd := exec.Command("trust", "anchor", "--store", absPath)
|
cmd := exec.Command("trust", "anchor", "--store", absPath)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("unsupported Linux distribution")
|
return fmt.Errorf("unsupported Linux distribution")
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
//go:build !windows && !darwin && !linux
|
//go:build !windows && !darwin && !linux
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func installCA(certPath string) error {
|
func installCA(certPath string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-17
@@ -1,17 +1,17 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func installCA(absPath string) error {
|
func installCA(absPath string) error {
|
||||||
cmd := exec.Command("certutil", "-addstore", "-user", "root", absPath)
|
cmd := exec.Command("certutil", "-addstore", "-user", "root", absPath)
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
output := zerolog.ConsoleWriter{
|
output := zerolog.ConsoleWriter{
|
||||||
Out: os.Stdout,
|
Out: os.Stdout,
|
||||||
PartsOrder: []string{"level", "message"},
|
PartsOrder: []string{"level", "message"},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Logger = zerolog.New(output).With().Logger()
|
log.Logger = zerolog.New(output).With().Logger()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -32,8 +34,17 @@ func rawQueryFromRequestURI(requestURI string) string {
|
|||||||
return rawQuery
|
return rawQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseRedirect(r string) (scheme, host string) {
|
||||||
|
if strings.Contains(r, "://") {
|
||||||
|
if u, err := url.Parse(r); err == nil && u.Host != "" {
|
||||||
|
return u.Scheme, u.Host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "http", r
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
redirectHost := flag.String("r", "127.0.0.1:21000", "redirect target host")
|
redirectHost := flag.String("r", "127.0.0.1:21000", "redirect target (host:port or full URL)")
|
||||||
blockedStr := flag.String("b", "", "comma separated list of blocked ports")
|
blockedStr := flag.String("b", "", "comma separated list of blocked ports")
|
||||||
proxyPort := flag.Int("p", 0, "proxy listen port (default: auto)")
|
proxyPort := flag.Int("p", 0, "proxy listen port (default: auto)")
|
||||||
exePath := flag.String("e", "", "path to the executable")
|
exePath := flag.String("e", "", "path to the executable")
|
||||||
@@ -41,6 +52,8 @@ func main() {
|
|||||||
noSys := flag.Bool("no-sys", false, "skip certificate installation and system proxy setup")
|
noSys := flag.Bool("no-sys", false, "skip certificate installation and system proxy setup")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
redirectScheme, redirectTarget := parseRedirect(*redirectHost)
|
||||||
|
|
||||||
if !*noSys {
|
if !*noSys {
|
||||||
relaunched, err := relaunchWithAdminIfNeeded()
|
relaunched, err := relaunchWithAdminIfNeeded()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -119,6 +132,7 @@ func main() {
|
|||||||
MaxIdleConnsPerHost: 100,
|
MaxIdleConnsPerHost: 100,
|
||||||
IdleConnTimeout: 90 * time.Second,
|
IdleConnTimeout: 90 * time.Second,
|
||||||
DisableCompression: false,
|
DisableCompression: false,
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
}
|
}
|
||||||
proxy.CertStore = NewCertStorage()
|
proxy.CertStore = NewCertStorage()
|
||||||
proxy.OnRequest().HandleConnect(customAlwaysMitm)
|
proxy.OnRequest().HandleConnect(customAlwaysMitm)
|
||||||
@@ -171,8 +185,9 @@ func main() {
|
|||||||
Str("raw_query", rawQuery).
|
Str("raw_query", rawQuery).
|
||||||
Msg("Force redirect")
|
Msg("Force redirect")
|
||||||
|
|
||||||
req.URL.Scheme = "http"
|
req.URL.Scheme = redirectScheme
|
||||||
req.URL.Host = *redirectHost
|
req.URL.Host = redirectTarget
|
||||||
|
req.Host = redirectTarget
|
||||||
req.URL.RawQuery = rawQuery
|
req.URL.RawQuery = rawQuery
|
||||||
req.RequestURI = ""
|
req.RequestURI = ""
|
||||||
zlog.Info().Str("to_url", req.URL.String()).Msg("Force redirected")
|
zlog.Info().Str("to_url", req.URL.String()).Msg("Force redirected")
|
||||||
@@ -184,8 +199,9 @@ func main() {
|
|||||||
Str("from_url", full).
|
Str("from_url", full).
|
||||||
Str("raw_query", rawQuery).
|
Str("raw_query", rawQuery).
|
||||||
Msg("Redirect domain")
|
Msg("Redirect domain")
|
||||||
req.URL.Scheme = "http"
|
req.URL.Scheme = redirectScheme
|
||||||
req.URL.Host = *redirectHost
|
req.URL.Host = redirectTarget
|
||||||
|
req.Host = redirectTarget
|
||||||
req.URL.RawQuery = rawQuery
|
req.URL.RawQuery = rawQuery
|
||||||
req.RequestURI = ""
|
req.RequestURI = ""
|
||||||
zlog.Info().Str("to_url", req.URL.String()).Msg("Redirected domain")
|
zlog.Info().Str("to_url", req.URL.String()).Msg("Redirected domain")
|
||||||
@@ -246,4 +262,4 @@ func main() {
|
|||||||
if err := srv.Shutdown(ctx); err != nil {
|
if err := srv.Shutdown(ctx); err != nil {
|
||||||
zlog.Error().Err(err).Msg("Server shutdown error")
|
zlog.Error().Err(err).Msg("Server shutdown error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
//go:build !windows && !darwin && !linux
|
//go:build !windows && !darwin && !linux
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func runWithAdmin(exePath string, env []string) error {
|
func runWithAdmin(exePath string, env []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -1,15 +1,15 @@
|
|||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runWithAdmin(exePath string, env []string) error {
|
func runWithAdmin(exePath string, env []string) error {
|
||||||
cmd := exec.Command("pkexec", exePath)
|
cmd := exec.Command("pkexec", exePath)
|
||||||
cmd.Env = append(os.Environ(), env...)
|
cmd.Env = append(os.Environ(), env...)
|
||||||
return cmd.Start()
|
return cmd.Start()
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -1,15 +1,15 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runWithAdmin(exePath string, env []string) error {
|
func runWithAdmin(exePath string, env []string) error {
|
||||||
cmd := exec.Command("powershell", "Start-Process", exePath, "-Verb", "runAs")
|
cmd := exec.Command("powershell", "Start-Process", exePath, "-Verb", "runAs")
|
||||||
cmd.Env = append(os.Environ(), env...)
|
cmd.Env = append(os.Environ(), env...)
|
||||||
return cmd.Start()
|
return cmd.Start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
### UPDATE
|
### UPDATE
|
||||||
- Support linux, macos, window
|
- Support linux, macos, window
|
||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"tag": "1.3-03",
|
"tag": "1.4-01",
|
||||||
"title": "PreBuild Version 1.3 - 03"
|
"title": "PreBuild Version 1.4 - 01"
|
||||||
}
|
}
|
||||||
|
|
||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
//go:build !windows && !darwin && !linux
|
//go:build !windows && !darwin && !linux
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func setProxy(enable bool, host string, port string) error {
|
func setProxy(enable bool, host string, port string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
+24
-24
@@ -1,24 +1,24 @@
|
|||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func setProxy(enable bool, host string, port string) error {
|
func setProxy(enable bool, host string, port string) error {
|
||||||
|
|
||||||
httpProxy1 := fmt.Sprintf("HTTP_PROXY=http://%s:%s", host, port)
|
httpProxy1 := fmt.Sprintf("HTTP_PROXY=http://%s:%s", host, port)
|
||||||
httpProxy2 := fmt.Sprintf("http_proxy=http://%s:%s", host, port)
|
httpProxy2 := fmt.Sprintf("http_proxy=http://%s:%s", host, port)
|
||||||
|
|
||||||
ENV_CONFIG = append(ENV_CONFIG, httpProxy1, httpProxy2)
|
ENV_CONFIG = append(ENV_CONFIG, httpProxy1, httpProxy2)
|
||||||
|
|
||||||
httpsProxy1 := fmt.Sprintf("HTTPS_PROXY=http://%s:%s", host, port)
|
httpsProxy1 := fmt.Sprintf("HTTPS_PROXY=http://%s:%s", host, port)
|
||||||
httpsProxy2 := fmt.Sprintf("https_proxy=http://%s:%s", host, port)
|
httpsProxy2 := fmt.Sprintf("https_proxy=http://%s:%s", host, port)
|
||||||
ENV_CONFIG = append(ENV_CONFIG, httpsProxy1, httpsProxy2)
|
ENV_CONFIG = append(ENV_CONFIG, httpsProxy1, httpsProxy2)
|
||||||
|
|
||||||
if enable {
|
if enable {
|
||||||
ENV_CONFIG = make([]string, 0)
|
ENV_CONFIG = make([]string, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-43
@@ -1,43 +1,43 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setProxy(enable bool, host string, port string) error {
|
func setProxy(enable bool, host string, port string) error {
|
||||||
k, _, err := registry.CreateKey(
|
k, _, err := registry.CreateKey(
|
||||||
registry.CURRENT_USER,
|
registry.CURRENT_USER,
|
||||||
`Software\Microsoft\Windows\CurrentVersion\Internet Settings`,
|
`Software\Microsoft\Windows\CurrentVersion\Internet Settings`,
|
||||||
registry.SET_VALUE,
|
registry.SET_VALUE,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if enable {
|
if enable {
|
||||||
k.SetDWordValue("ProxyEnable", 1)
|
k.SetDWordValue("ProxyEnable", 1)
|
||||||
|
|
||||||
addr := fmt.Sprintf("%s:%s", host, port)
|
addr := fmt.Sprintf("%s:%s", host, port)
|
||||||
val := fmt.Sprintf("http=%s;https=%s", addr, addr)
|
val := fmt.Sprintf("http=%s;https=%s", addr, addr)
|
||||||
|
|
||||||
k.SetStringValue("ProxyServer", val)
|
k.SetStringValue("ProxyServer", val)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
k.SetDWordValue("ProxyEnable", 0)
|
k.SetDWordValue("ProxyEnable", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Close()
|
k.Close()
|
||||||
|
|
||||||
d := syscall.NewLazyDLL("wininet.dll")
|
d := syscall.NewLazyDLL("wininet.dll")
|
||||||
o := d.NewProc("InternetSetOptionW")
|
o := d.NewProc("InternetSetOptionW")
|
||||||
o.Call(0, 39, 0, 0)
|
o.Call(0, 39, 0, 0)
|
||||||
o.Call(0, 37, 0, 0)
|
o.Call(0, 37, 0, 0)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user