Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic warp reserved field by default, add win32, include wintun.dll and other cleanups #132

Merged
merged 8 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 50 additions & 9 deletions .github/workflows/go-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ jobs:
goarch: amd64
- goos: windows
goarch: arm64
- goos: windows
goarch: 386

runs-on: ubuntu-latest
env:
Expand All @@ -68,19 +70,55 @@ jobs:
go-version: '1.22'
check-latest: true

- name: Cache wintun
id: cache
uses: actions/cache@v4
if: matrix.goos == 'windows'
env:
cache-name: cache-wintun
with:
path: ~/wintun-0.14.1.zip
key: wintun-0.14.1.zip

- name: Download wintun
if: matrix.goos == 'windows' && steps.cache.outputs.cache-hit != 'true'
run: |
curl -LO https://www.wintun.net/builds/wintun-0.14.1.zip --output-dir ~/
ls -lah ~/

- name: Validate wintun
if: matrix.goos == 'windows'
run: |
pushd ~/
echo "07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51 wintun-0.14.1.zip" | sha256sum --check --status
unzip ~/wintun-0.14.1.zip -d ~/wintun
popd

- name: Build warp-plus
run: |
go build -v -o build_assets/ -trimpath -ldflags "-s -w -buildid= -X main.version=${{ github.ref }}" .
go build -v -o warp-plus_${{ env.ASSET_NAME }}/ -trimpath -ldflags "-s -w -buildid= -X main.version=${{ github.ref }}" ./cmd/warp-plus
go build -v -o warp-scan_${{ env.ASSET_NAME }}/ -trimpath -ldflags "-s -w -buildid= -X main.version=${{ github.ref }}" ./cmd/warp-scan

- name: Copy README.md & LICENSE
run: |
cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md
cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE
cp ${GITHUB_WORKSPACE}/README.md ./warp-plus_${{ env.ASSET_NAME }}/README.md
cp ${GITHUB_WORKSPACE}/LICENSE ./warp-plus_${{ env.ASSET_NAME }}/LICENSE

- name: Redistribute wintun.dll
if: matrix.goos == 'windows'
run: |
if [ "$GOARCH" = "amd64" ]; then
mv ~/wintun/wintun/bin/amd64/wintun.dll ./warp-plus_${{ env.ASSET_NAME }}/
elif [ "$GOARCH" = "arm64" ]; then
mv ~/wintun/wintun/bin/arm64/wintun.dll ./warp-plus_${{ env.ASSET_NAME }}/
elif [ "$GOARCH" = "386" ]; then
mv ~/wintun/wintun/bin/x86/wintun.dll ./warp-plus_${{ env.ASSET_NAME }}/
fi

- name: Create ZIP archive
shell: bash
run: |
pushd ./build_assets || exit 1
pushd ./warp-plus_${{ env.ASSET_NAME }} || exit 1
touch -mt $(date +%Y01010000) *
zip -9vr ../warp-plus_${{ env.ASSET_NAME }}.zip .
popd || exit 1
Expand All @@ -91,17 +129,20 @@ jobs:
openssl dgst -$METHOD $FILE | sed 's/([^)]*)//g' >>$DGST
done

- name: Change the name
run: |
mv ./build_assets ./warp-plus_${{ env.ASSET_NAME }}

- name: Upload files to Artifacts
- name: Upload warp-plus files to Artifacts
uses: actions/upload-artifact@v4
with:
name: warp-plus_${{ env.ASSET_NAME }}_${{ env.REF }}
path: |
./warp-plus_${{ env.ASSET_NAME }}/*

- name: Upload warp-scan files to Artifacts
uses: actions/upload-artifact@v4
with:
name: warp-scan_${{ env.ASSET_NAME }}_${{ env.REF }}
path: |
./warp-scan_${{ env.ASSET_NAME }}/*

- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
if: github.event_name == 'release'
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
warp-plus
warp-plus.exe
/warp-plus
/warp-plus.exe
.idea
stuff/
wintun.dll
123 changes: 100 additions & 23 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app

import (
"context"
"encoding/base64"
"errors"
"fmt"
"log/slog"
Expand All @@ -10,8 +11,8 @@ import (

"github.com/bepass-org/warp-plus/iputils"
"github.com/bepass-org/warp-plus/psiphon"
"github.com/bepass-org/warp-plus/warp"
"github.com/bepass-org/warp-plus/wiresocks"
"github.com/go-ini/ini"
)

const singleMTU = 1330
Expand All @@ -30,6 +31,7 @@ type WarpOptions struct {
Tun bool
FwMark uint32
WireguardConfig string
Reserved string
}

type PsiphonOptions struct {
Expand Down Expand Up @@ -61,16 +63,18 @@ func RunWarp(ctx context.Context, l *slog.Logger, opts WarpOptions) error {
endpoints := []string{opts.Endpoint, opts.Endpoint}

if opts.Scan != nil {
cfg, err := ini.Load(path.Join(opts.CacheDir, "primary", "wgcf-profile.ini"))
// make primary identity
ident, err := warp.LoadOrCreateIdentity(l, path.Join(opts.CacheDir, "primary"), opts.License)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
l.Error("couldn't load primary warp identity")
return err
}

// Reading the private key from the 'Interface' section
opts.Scan.PrivateKey = cfg.Section("Interface").Key("PrivateKey").String()
opts.Scan.PrivateKey = ident.PrivateKey

// Reading the public key from the 'Peer' section
opts.Scan.PublicKey = cfg.Section("Peer").Key("PublicKey").String()
opts.Scan.PublicKey = ident.Config.Peers[0].PublicKey

res, err := wiresocks.RunScan(ctx, l, *opts.Scan)
if err != nil {
Expand Down Expand Up @@ -173,12 +177,15 @@ func runWireguard(ctx context.Context, l *slog.Logger, opts WarpOptions) error {
}

func runWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoint string) error {
// Set up primary/outer warp config
conf, err := wiresocks.ParseConfig(path.Join(opts.CacheDir, "primary", "wgcf-profile.ini"))
// make primary identity
ident, err := warp.LoadOrCreateIdentity(l, path.Join(opts.CacheDir, "primary"), opts.License)
if err != nil {
l.Error("couldn't load primary warp identity")
return err
}

conf := generateWireguardConfig(ident)

// Set up MTU
conf.Interface.MTU = singleMTU
// Set up DNS Address
Expand All @@ -189,6 +196,15 @@ func runWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoint str
peer.Endpoint = endpoint
peer.Trick = true
peer.KeepAlive = 3

if opts.Reserved != "" {
r, err := wiresocks.ParseReserved(opts.Reserved)
if err != nil {
return err
}
peer.Reserved = r
}

conf.Peers[i] = peer
}

Expand All @@ -200,21 +216,21 @@ func runWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoint str
}

// Establish wireguard tunnel on tun interface
if err := establishWireguard(l, conf, tunDev, true, opts.FwMark); err != nil {
if err := establishWireguard(l, &conf, tunDev, true, opts.FwMark); err != nil {
return err
}
l.Info("serving tun", "interface", "warp0")
return nil
}

// Create userspace tun network stack
tunDev, tnet, err := newUsermodeTun(conf)
tunDev, tnet, err := newUsermodeTun(&conf)
if err != nil {
return err
}

// Establish wireguard on userspace stack
if err := establishWireguard(l, conf, tunDev, false, opts.FwMark); err != nil {
if err := establishWireguard(l, &conf, tunDev, false, opts.FwMark); err != nil {
return err
}

Expand All @@ -234,12 +250,15 @@ func runWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoint str
}

func runWarpInWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoints []string) error {
// Set up primary/outer warp config
conf, err := wiresocks.ParseConfig(path.Join(opts.CacheDir, "primary", "wgcf-profile.ini"))
// make primary identity
ident1, err := warp.LoadOrCreateIdentity(l, path.Join(opts.CacheDir, "primary"), opts.License)
if err != nil {
l.Error("couldn't load primary warp identity")
return err
}

conf := generateWireguardConfig(ident1)

// Set up MTU
conf.Interface.MTU = singleMTU
// Set up DNS Address
Expand All @@ -250,17 +269,26 @@ func runWarpInWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoi
peer.Endpoint = endpoints[0]
peer.Trick = true
peer.KeepAlive = 3

if opts.Reserved != "" {
r, err := wiresocks.ParseReserved(opts.Reserved)
if err != nil {
return err
}
peer.Reserved = r
}

conf.Peers[i] = peer
}

// Create userspace tun network stack
tunDev, tnet, err := newUsermodeTun(conf)
tunDev, tnet, err := newUsermodeTun(&conf)
if err != nil {
return err
}

// Establish wireguard on userspace stack and bind the wireguard sockets to the default interface and apply
if err := establishWireguard(l.With("gool", "outer"), conf, tunDev, opts.Tun, opts.FwMark); err != nil {
if err := establishWireguard(l.With("gool", "outer"), &conf, tunDev, opts.Tun, opts.FwMark); err != nil {
return err
}

Expand All @@ -275,12 +303,15 @@ func runWarpInWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoi
return err
}

// Set up secondary/inner warp config
conf, err = wiresocks.ParseConfig(path.Join(opts.CacheDir, "secondary", "wgcf-profile.ini"))
// make secondary
ident2, err := warp.LoadOrCreateIdentity(l, path.Join(opts.CacheDir, "secondary"), opts.License)
if err != nil {
l.Error("couldn't load secondary warp identity")
return err
}

conf = generateWireguardConfig(ident2)

// Set up MTU
conf.Interface.MTU = doubleMTU
// Set up DNS Address
Expand All @@ -290,6 +321,15 @@ func runWarpInWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoi
for i, peer := range conf.Peers {
peer.Endpoint = addr.String()
peer.KeepAlive = 10

if opts.Reserved != "" {
r, err := wiresocks.ParseReserved(opts.Reserved)
if err != nil {
return err
}
peer.Reserved = r
}

conf.Peers[i] = peer
}

Expand All @@ -302,21 +342,21 @@ func runWarpInWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoi

// Establish wireguard tunnel on tun interface but don't bind
// wireguard sockets to default interface and don't apply fwmark.
if err := establishWireguard(l.With("gool", "inner"), conf, tunDev, false, opts.FwMark); err != nil {
if err := establishWireguard(l.With("gool", "inner"), &conf, tunDev, false, opts.FwMark); err != nil {
return err
}
l.Info("serving tun", "interface", "warp0")
return nil
}

// Create userspace tun network stack
tunDev, tnet, err = newUsermodeTun(conf)
tunDev, tnet, err = newUsermodeTun(&conf)
if err != nil {
return err
}

// Establish wireguard on userspace stack
if err := establishWireguard(l.With("gool", "inner"), conf, tunDev, false, opts.FwMark); err != nil {
if err := establishWireguard(l.With("gool", "inner"), &conf, tunDev, false, opts.FwMark); err != nil {
return err
}

Expand All @@ -335,12 +375,15 @@ func runWarpInWarp(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoi
}

func runWarpWithPsiphon(ctx context.Context, l *slog.Logger, opts WarpOptions, endpoint string) error {
// Set up primary/outer warp config
conf, err := wiresocks.ParseConfig(path.Join(opts.CacheDir, "primary", "wgcf-profile.ini"))
// make primary identity
ident, err := warp.LoadOrCreateIdentity(l, path.Join(opts.CacheDir, "primary"), opts.License)
if err != nil {
l.Error("couldn't load primary warp identity")
return err
}

conf := generateWireguardConfig(ident)

// Set up MTU
conf.Interface.MTU = singleMTU
// Set up DNS Address
Expand All @@ -351,17 +394,26 @@ func runWarpWithPsiphon(ctx context.Context, l *slog.Logger, opts WarpOptions, e
peer.Endpoint = endpoint
peer.Trick = true
peer.KeepAlive = 3

if opts.Reserved != "" {
r, err := wiresocks.ParseReserved(opts.Reserved)
if err != nil {
return err
}
peer.Reserved = r
}

conf.Peers[i] = peer
}

// Create userspace tun network stack
tunDev, tnet, err := newUsermodeTun(conf)
tunDev, tnet, err := newUsermodeTun(&conf)
if err != nil {
return err
}

// Establish wireguard on userspace stack
if err := establishWireguard(l, conf, tunDev, false, opts.FwMark); err != nil {
if err := establishWireguard(l, &conf, tunDev, false, opts.FwMark); err != nil {
return err
}

Expand All @@ -385,3 +437,28 @@ func runWarpWithPsiphon(ctx context.Context, l *slog.Logger, opts WarpOptions, e
l.Info("serving proxy", "address", opts.Bind)
return nil
}

func generateWireguardConfig(i *warp.Identity) wiresocks.Configuration {
priv, _ := wiresocks.EncodeBase64ToHex(i.PrivateKey)
pub, _ := wiresocks.EncodeBase64ToHex(i.Config.Peers[0].PublicKey)
clientID, _ := base64.StdEncoding.DecodeString(i.Config.ClientID)
return wiresocks.Configuration{
Interface: &wiresocks.InterfaceConfig{
PrivateKey: priv,
Addresses: []netip.Addr{
netip.MustParseAddr(i.Config.Interface.Addresses.V4),
netip.MustParseAddr(i.Config.Interface.Addresses.V6),
},
},
Peers: []wiresocks.PeerConfig{{
PublicKey: pub,
PreSharedKey: "0000000000000000000000000000000000000000000000000000000000000000",
AllowedIPs: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
},
Endpoint: i.Config.Peers[0].Endpoint.Host,
Reserved: [3]byte{clientID[0], clientID[1], clientID[2]},
}},
}
}
Loading