Compare commits

...

14 Commits

Author SHA1 Message Date
Vladislav Yarmak
30295224ee bump snap version 2021-07-15 23:11:09 +03:00
Vladislav Yarmak
4d4348686c holaapi: update reported client version 2021-07-15 23:10:29 +03:00
Vladislav Yarmak
86b7fece9b bump snap version 2021-07-02 23:41:28 +03:00
Vladislav Yarmak
608da0baa9 remove mentions of unknown proxy types 2021-07-02 23:38:40 +03:00
Vladislav Yarmak
0c36dee0b7 remove dockerhub hooks 2021-06-09 21:46:34 +03:00
Vladislav Yarmak
f2fdeea039 ci: docker 2021-06-09 19:39:22 +03:00
Snawoot
f5da736ca1 Update README.md 2021-05-02 13:04:36 +03:00
Vladislav Yarmak
dd0eaa7611 bump snap version 2021-05-01 17:58:42 +03:00
Snawoot
882bca34bc Merge pull request #45 from Snawoot/fix_http
Fixed plain HTTP request
2021-05-01 17:57:30 +03:00
Vladislav Yarmak
70faaec848 fixed plain HTTP request 2021-05-01 17:55:12 +03:00
Snawoot
4728548594 Merge pull request #43 from aarivex/patch-2
Update README.md
2021-04-01 02:10:13 +03:00
Vladislav Yarmak
2c555adb35 amend chmod notice 2021-04-01 02:09:06 +03:00
Canathan
9fee5905bb Update README.md
Add chmod command section for the linux binary.
2021-03-30 04:57:44 +02:00
Vladislav Yarmak
19fd0c9d52 add android build target 2021-03-28 18:44:12 +03:00
9 changed files with 175 additions and 14 deletions

58
.github/workflows/docker-ci.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: docker-ci
on:
push:
branches:
- 'master'
release:
types: [published]
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Find Git Tag
id: tagger
uses: jimschubert/query-tag-action@v2
with:
include: 'v*'
exclude: '*-rc*'
commit-ish: 'HEAD'
skip-unshallow: 'true'
abbrev: 7
-
name: Determine image tag type
uses: haya14busa/action-cond@v1
id: imgtag
with:
cond: ${{ github.event_name == 'release' }}
if_true: ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ github.event.release.tag_name }},${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:latest
if_false: ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:latest
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: ${{ steps.imgtag.outputs.value }}
build-args: 'GIT_DESC=${{steps.tagger.outputs.tag}}'

View File

@@ -5,6 +5,9 @@ BUILDOPTS = -a -tags netgo
LDFLAGS = -ldflags '-s -w -extldflags "-static" -X main.version=$(VERSION)'
LDFLAGS_NATIVE = -ldflags '-s -w -X main.version=$(VERSION)'
NDK_CC_ARM = $(abspath ../../ndk-toolchain-arm/bin/arm-linux-androideabi-gcc)
NDK_CC_ARM64 = $(abspath ../../ndk-toolchain-arm64/bin/aarch64-linux-android21-clang)
GO := go
src = $(wildcard *.go)
@@ -17,6 +20,9 @@ all: bin-linux-amd64 bin-linux-386 bin-linux-arm \
bin-darwin-amd64 bin-darwin-arm64 \
bin-windows-amd64 bin-windows-386 bin-windows-arm
allplus: all \
bin-android-arm bin-android-arm64
bin-native: $(OUTSUFFIX)
bin-linux-amd64: $(OUTSUFFIX).linux-amd64
bin-linux-386: $(OUTSUFFIX).linux-386
@@ -33,6 +39,8 @@ bin-darwin-arm64: $(OUTSUFFIX).darwin-arm64
bin-windows-amd64: $(OUTSUFFIX).windows-amd64.exe
bin-windows-386: $(OUTSUFFIX).windows-386.exe
bin-windows-arm: $(OUTSUFFIX).windows-arm.exe
bin-android-arm: $(OUTSUFFIX).android-arm
bin-android-arm64: $(OUTSUFFIX).android-arm64
$(OUTSUFFIX): $(src)
$(GO) build $(LDFLAGS_NATIVE) -o $@
@@ -82,6 +90,12 @@ $(OUTSUFFIX).windows-386.exe: $(src)
$(OUTSUFFIX).windows-arm.exe: $(src)
CGO_ENABLED=0 GOOS=windows GOARCH=arm GOARM=7 $(GO) build $(BUILDOPTS) $(LDFLAGS) -o $@
$(OUTSUFFIX).android-arm: $(src)
CC=$(NDK_CC_ARM) CGO_ENABLED=1 GOOS=android GOARCH=arm GOARM=7 $(GO) build $(LDFLAGS_NATIVE) -o $@
$(OUTSUFFIX).android-arm64: $(src)
CC=$(NDK_CC_ARM64) CGO_ENABLED=1 GOOS=android GOARCH=arm64 $(GO) build $(LDFLAGS_NATIVE) -o $@
clean:
rm -f bin/*
@@ -102,6 +116,13 @@ install:
bin-freebsd-amd64 \
bin-freebsd-386 \
bin-freebsd-arm \
bin-netbsd-amd64 \
bin-netbsd-386 \
bin-openbsd-amd64 \
bin-openbsd-386 \
bin-darwin-amd64 \
bin-windows-amd64 \
bin-windows-386
bin-windows-386 \
bin-windows-arm \
bin-android-arm \
bin-android-arm64

View File

@@ -5,7 +5,7 @@
Standalone Hola proxy client. Just run it and it'll start a plain HTTP proxy server forwarding traffic through Hola proxies of your choice.
By default the application listens on 127.0.0.1:8080.
Application is capable to forward traffic via proxies in datacenters (flag `-proxy-type direct`, default) or via peer proxies on residental IPs (consumer ISP) in that country (flag `-proxy-type pool` or `-proxy-type lum`).
Application is capable to forward traffic via proxies in datacenters (flag `-proxy-type direct`, default) or via peer proxies on residental IPs (consumer ISP) in that country (flag `-proxy-type lum`).
---
@@ -41,6 +41,12 @@ git clone https://ipfs.io/ipns/k51qzi5uqu5dkrgx0hozpy1tlggw5o0whtquyrjlc6pprhvbm
Pre-built binaries are available [here](https://github.com/Snawoot/hola-proxy/releases/latest).
Don't forget to make file executable on Unix-like systems (Linux, MacOS, \*BSD, Android). For your convenience rename downloaded file to `hola-proxy` and run within directory where you placed it:
```sh
chmod +x hola-proxy
```
#### Build from source
Alternatively, you may install hola-proxy from source. Run the following within the source directory:
@@ -158,8 +164,12 @@ zagent248.hola.org,165.22.65.3,22222,22223,22224,22225,22226,digitalocean
| list-countries | String | list available countries and exit |
| list-proxies | - | output proxy list and exit |
| proxy | String | sets base proxy to use for all dial-outs. Format: `<http\|https\|socks5\|socks5h>://[login:password@]host[:port]` Examples: `http://user:password@192.168.1.1:3128`, `socks5://10.0.0.1:1080` |
| proxy-type | String | proxy type (Datacenter: direct, virt) (Residential: peer, lum, pool) (default "direct") |
| proxy-type | String | proxy type (Datacenter: direct) (Residential: lum) (default "direct") |
| resolver | String | DNS/DoH/DoT resolver to workaround Hola blocked hosts. See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format. (default "https://cloudflare-dns.com/dns-query") |
| rotate | Duration | rotate user ID once per given period (default 1h0m0s) |
| timeout | Duration | timeout for network operations (default 10s) |
| verbosity | Number | logging verbosity (10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical) (default 20) |
## See also
* [Project wiki](https://github.com/Snawoot/hola-proxy/wiki)

View File

@@ -3,6 +3,7 @@ package main
import (
"fmt"
"net/http"
"net/url"
"strings"
"time"
)
@@ -15,20 +16,28 @@ type ProxyHandler struct {
logger *CondLogger
dialer ContextDialer
httptransport http.RoundTripper
auth AuthProvider
}
func NewProxyHandler(dialer ContextDialer, resolver *Resolver, logger *CondLogger) *ProxyHandler {
func NewProxyHandler(dialer, requestDialer ContextDialer, auth AuthProvider, resolver *Resolver, logger *CondLogger) *ProxyHandler {
dialer = NewRetryDialer(dialer, resolver, logger)
httptransport := &http.Transport{
Proxy: func(_ *http.Request) (*url.URL, error) {
return &url.URL{
Scheme: "http",
Host: "void",
}, nil
},
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DialContext: dialer.DialContext,
DialContext: requestDialer.DialContext,
}
return &ProxyHandler{
logger: logger,
dialer: dialer,
auth: auth,
httptransport: httptransport,
}
}
@@ -74,6 +83,8 @@ func (s *ProxyHandler) HandleRequest(wr http.ResponseWriter, req *http.Request)
req.URL.Scheme = "http" // We can't access :scheme pseudo-header, so assume http
req.URL.Host = req.Host
}
delHopHeaders(req.Header)
req.Header.Add("Proxy-Authorization", s.auth())
resp, err := s.httptransport.RoundTrip(req)
if err != nil {
s.logger.Error("HTTP fetch error: %v", err)

View File

@@ -21,8 +21,8 @@ import (
"github.com/google/uuid"
)
const USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36"
const EXT_VER = "1.181.350"
const USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
const EXT_VER = "1.186.562"
const EXT_BROWSER = "chrome"
const PRODUCT = "cws"
const CCGI_URL = "https://client.hola.org/client_cgi/"

View File

@@ -1,2 +0,0 @@
#!/bin/bash
docker build --build-arg GIT_DESC="$(git describe)" -f "$DOCKERFILE_PATH" -t "$IMAGE_NAME" .

View File

@@ -64,15 +64,15 @@ func parse_args() CLIArgs {
"(10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical)")
flag.DurationVar(&args.timeout, "timeout", 10*time.Second, "timeout for network operations")
flag.DurationVar(&args.rotate, "rotate", 1*time.Hour, "rotate user ID once per given period")
flag.StringVar(&args.proxy_type, "proxy-type", "direct", "proxy type: direct or peer or lum or virt or pool") // or skip but not mentioned
flag.StringVar(&args.proxy_type, "proxy-type", "direct", "proxy type: direct or lum") // or skip but not mentioned
// skip would be used something like this: `./bin/hola-proxy -proxy-type skip -force-port-field 24232 -country ua.peer` for debugging
flag.StringVar(&args.resolver, "resolver", "https://cloudflare-dns.com/dns-query",
"DNS/DoH/DoT resolver to workaround Hola blocked hosts. "+
"See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format.")
flag.BoolVar(&args.use_trial, "dont-use-trial", false, "use regular ports instead of trial ports") // would be nice to not show in help page
flag.BoolVar(&args.showVersion, "version", false, "show program version and exit")
flag.StringVar(&args.proxy, "proxy", "", "sets base proxy to use for all dial-outs. " +
"Format: <http|https|socks5|socks5h>://[login:password@]host[:port] " +
flag.StringVar(&args.proxy, "proxy", "", "sets base proxy to use for all dial-outs. "+
"Format: <http|https|socks5|socks5h>://[login:password@]host[:port] "+
"Examples: http://user:password@192.168.1.1:3128, socks5://10.0.0.1:1080")
flag.Parse()
if args.country == "" {
@@ -164,9 +164,10 @@ func run() int {
return 5
}
handlerDialer := NewProxyDialer(endpoint.NetAddr(), endpoint.TLSName, auth, dialer)
requestDialer := NewPlaintextDialer(endpoint.NetAddr(), endpoint.TLSName, dialer)
mainLogger.Info("Endpoint: %s", endpoint.URL().String())
mainLogger.Info("Starting proxy server...")
handler := NewProxyHandler(handlerDialer, resolver, proxyLogger)
handler := NewProxyHandler(handlerDialer, requestDialer, auth, resolver, proxyLogger)
mainLogger.Info("Init complete.")
err = http.ListenAndServe(args.bind_address, handler)
mainLogger.Critical("Server terminated with a reason: %v", err)

62
plaintext.go Normal file
View File

@@ -0,0 +1,62 @@
package main
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"net"
)
type PlaintextDialer struct {
fixedAddress string
tlsServerName string
next ContextDialer
}
func NewPlaintextDialer(address, tlsServerName string, next ContextDialer) *PlaintextDialer {
return &PlaintextDialer{
fixedAddress: address,
tlsServerName: tlsServerName,
next: next,
}
}
func (d *PlaintextDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
switch network {
case "tcp", "tcp4", "tcp6":
default:
return nil, errors.New("bad network specified for DialContext: only tcp is supported")
}
conn, err := d.next.DialContext(ctx, "tcp", d.fixedAddress)
if err != nil {
return nil, err
}
if d.tlsServerName != "" {
// Custom cert verification logic:
// DO NOT send SNI extension of TLS ClientHello
// DO peer certificate verification against specified servername
conn = tls.Client(conn, &tls.Config{
ServerName: "",
InsecureSkipVerify: true,
VerifyConnection: func(cs tls.ConnectionState) error {
opts := x509.VerifyOptions{
DNSName: d.tlsServerName,
Intermediates: x509.NewCertPool(),
}
for _, cert := range cs.PeerCertificates[1:] {
opts.Intermediates.AddCert(cert)
}
_, err := cs.PeerCertificates[0].Verify(opts)
return err
},
})
}
return conn, nil
}
func (d *PlaintextDialer) Dial(network, address string) (net.Conn, error) {
return d.DialContext(context.Background(), network, address)
}

View File

@@ -1,5 +1,5 @@
name: hola-proxy
version: '1.5.0'
version: '1.5.3'
summary: Standalone Hola proxy client.
description: |
Standalone Hola proxy client. Just run it and it'll start plain HTTP proxy server forwarding traffic via Hola proxies of your choice.