check thing

This commit is contained in:
idk
2019-10-16 21:01:56 -04:00
parent 6b993d6d62
commit db2f32877a
6 changed files with 236 additions and 18 deletions

View File

@ -45,10 +45,9 @@ Features: Done
* CONNECT support
* "New Ident" signaling interface(Unix-only for now)(I guess I might have done
for Windows too now but I haven't tried it out yet).
* Outproxy Support
Features: Planned
-----------------
* Outproxy Support
* Traffic Shaping
* Authentication

11
go.mod
View File

@ -3,8 +3,17 @@ module github.com/eyedeekay/httptunnel
go 1.12
require (
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce // indirect
github.com/d5/tengo v1.24.3 // indirect
github.com/eyedeekay/goSam v0.1.1-0.20190814204230-d4c9b8c57dd6
github.com/eyedeekay/sam-forwarder v0.0.0-20190831205522-ccc29b5e6647
github.com/eyedeekay/sam-forwarder v0.0.0-20190908210105-71ca8cd65fda
github.com/eyedeekay/sam3 v0.0.0-20190730185140-f8d54526ea25
github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a // indirect
gitlab.com/golang-commonmark/linkify v0.0.0-20180917065525-c22b7bdb1179 // indirect
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2 // indirect
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe // indirect
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
)

View File

@ -24,7 +24,7 @@ var (
samPortString = flag.String("bridge-port", "7656", ":port of the SAM bridge")
watchProfiles = flag.String("watch-profiles", "~/.mozilla/.firefox.profile.i2p.default/user.js,~/.mozilla/.firefox.profile.i2p.debug/user.js", "Monitor and control these Firefox profiles")
destfile = flag.String("dest-file", "invalid.tunkey", "Use a long-term destination key")
debugConnection = flag.Bool("conn-debug", true, "Print connection debug info")
debugConnection = flag.Bool("conn-debug", false, "Print connection debug info")
inboundTunnelLength = flag.Int("in-tun-length", 2, "Tunnel Length(default 3)")
outboundTunnelLength = flag.Int("out-tun-length", 2, "Tunnel Length(default 3)")
inboundTunnels = flag.Int("in-tunnels", 2, "Inbound Tunnel Count(default 2)")
@ -43,8 +43,10 @@ var (
reduceIdleQuantity = flag.Int("reduce-idle-tunnels", 1, "Reduce tunnels to this level")
runCommand = flag.String("run-command", "", "Execute command using the *_PROXY environment variables")
runArguments = flag.String("run-arguments", "", "Pass arguments to run-command")
suppressLifetime = flag.Bool("suppress-lifetime-output", false, "Suppress \"Tunnel lifetime\" output")
suppressLifetime = flag.Bool("suppress-lifetime-output", true, "Suppress \"Tunnel lifetime\" output")
runQuiet = flag.Bool("run-quiet", false, "Suppress all non-command output")
outproxy = flag.String("outproxy-addr", "false.i2p", "Use this address as an outproxy, either a base32 address or a local HTTP proxy")
socks = flag.Bool("outproxy-socks", true, "Use a SOCKS outproxy")
)
var addr string
@ -86,6 +88,8 @@ func proxyMain(ctx context.Context, ln net.Listener, cln net.Listener) {
SetPort(*samPortString),
SetProxyAddr(ln.Addr().String()),
SetControlAddr(cln.Addr().String()),
SetOutProxy(*outproxy),
SetOutProxySocks(*socks),
SetDebug(*debugConnection),
SetInLength(uint(*inboundTunnelLength)),
SetOutLength(uint(*outboundTunnelLength)),

View File

@ -160,6 +160,26 @@ func SetProxyHost(s string) func(*SAMHTTPProxy) error {
}
}
//SetOutProxy sets the host of the client's outproxy, it may be a base32 or a local proxy
func SetOutProxy(s string) func(*SAMHTTPProxy) error {
return func(c *SAMHTTPProxy) error {
c.UseOutProxy = s
return nil
}
}
//SetOutProxySocks tells it to use a SOCKS outproxy instead of HTTP
func SetOutProxySocks(s bool) func(*SAMHTTPProxy) error {
return func(c *SAMHTTPProxy) error {
if s {
c.outproxytype = "socks://"
return nil
}
c.outproxytype = "http://"
return nil
}
}
//SetProxyPort sets the host of the client's Proxy controller
func SetProxyPort(s string) func(*SAMHTTPProxy) error {
return func(c *SAMHTTPProxy) error {

View File

@ -3,12 +3,14 @@ package i2phttpproxy
import (
"crypto/tls"
"fmt"
"golang.org/x/net/proxy"
"golang.org/x/time/rate"
"io"
"io/ioutil"
"log"
"net"
"net/http"
"net/url"
"os"
"strconv"
"strings"
@ -23,17 +25,24 @@ import (
"github.com/eyedeekay/sam-forwarder/hashhash"
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam-forwarder/interface"
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam3/i2pkeys"
"github.com/mwitkow/go-http-dialer"
"github.com/phayes/freeport"
)
type SAMHTTPProxy struct {
goSam *goSam.Client
Hasher *hashhash.Hasher
client *http.Client
transport *http.Transport
rateLimiter *rate.Limiter
goSam *goSam.Client
Hasher *hashhash.Hasher
client *http.Client
outproxyclient *http.Client
transport *http.Transport
rateLimiter *rate.Limiter
outproxy *samforwarder.SAMClientForwarder
outproxydialer proxy.Dialer
outproxytype string
useOutProxy bool
UseOutProxy string
dialed bool
debug bool
@ -190,20 +199,21 @@ func (p *SAMHTTPProxy) samaddr() string {
func (p *SAMHTTPProxy) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
plog(req.RemoteAddr, " ", req.Method, " ", req.URL)
p.Save()
if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
/*if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
if !(req.Method == http.MethodConnect) {
msg := "Unsupported protocol scheme " + req.URL.Scheme
http.Error(wr, msg, http.StatusBadRequest)
plog(msg)
return
}
}*/
if req.URL.Host == p.Conf.ControlHost+":"+p.Conf.ControlPort {
p.reset(wr, req)
return
}
if !strings.HasSuffix(req.URL.Host, ".i2p") {
if req.URL.Host == p.Conf.ControlHost+":"+p.Conf.ControlPort {
p.reset(wr, req)
return
}
if !strings.HasSuffix(req.URL.Host, ".i2p") && p.UseOutProxy == "" {
msg := "Unsupported host " + req.URL.Host
if !Quiet {
http.Error(wr, msg, http.StatusBadRequest)
@ -216,6 +226,13 @@ func (p *SAMHTTPProxy) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
p.get(wr, req)
return
} else {
if !strings.HasSuffix(req.URL.Host, ".i2p") && p.UseOutProxy != "" {
p.outproxyget(wr, req)
return
} else {
plog("No outproxy configured ", p.UseOutProxy, p.outproxy.Target())
return
}
p.connect(wr, req)
return
}
@ -265,10 +282,35 @@ func (p *SAMHTTPProxy) reset(wr http.ResponseWriter, req *http.Request) {
}
}
func (p *SAMHTTPProxy) outproxyget(wr http.ResponseWriter, req *http.Request) {
plog("CONNECT via outproxy to", req.URL.Host)
dest_conn, err := p.outproxydialer.Dial("tcp", req.URL.String())
if err != nil {
if !Quiet {
plog(err.Error())
}
return
}
hijacker, ok := wr.(http.Hijacker)
if !ok {
return
}
client_conn, _, err := hijacker.Hijack()
if err != nil {
if !Quiet {
plog(err.Error())
}
return
}
go proxycommon.Transfer(dest_conn, client_conn)
go proxycommon.Transfer(client_conn, dest_conn)
}
func (p *SAMHTTPProxy) get(wr http.ResponseWriter, req *http.Request) {
req.RequestURI = ""
proxycommon.DelHopHeaders(req.Header)
p.client = p.freshClient()
plog("Getting i2p page")
//p.client = p.freshClient()
resp, err := p.client.Do(req)
if err != nil {
msg := "Proxy Error " + err.Error()
@ -333,6 +375,13 @@ func (p *SAMHTTPProxy) Save() string {
return ""
}
func (p *SAMHTTPProxy) GuaranteePrefix(str string) string {
if strings.HasPrefix(p.outproxytype, str) {
return str
}
return p.outproxytype + str
}
func (handler *SAMHTTPProxy) Load() (samtunnel.SAMTunnel, error) {
var err error
handler.Conf.ClientDest = handler.Save()
@ -360,6 +409,128 @@ func (handler *SAMHTTPProxy) Load() (samtunnel.SAMTunnel, error) {
}
handler.transport = handler.freshTransport()
handler.client = handler.freshClient()
if handler.UseOutProxy != "" {
if strings.HasSuffix(handler.UseOutProxy, ".i2p") {
plog("Configuring an outproxy,", handler.UseOutProxy)
config := handler.Conf
port, err := freeport.GetFreePort()
if err != nil {
return nil, err
}
config.TargetPort = strconv.Itoa(port)
config.TunName = handler.Conf.TunName + "-outproxy"
config.ClientDest = handler.UseOutProxy
handler.outproxy, err = samforwarder.NewSAMClientForwarderFromOptions(
samforwarder.SetClientSaveFile(config.SaveFile),
samforwarder.SetClientFilePath(config.SaveDirectory),
samforwarder.SetClientHost(config.TargetHost),
samforwarder.SetClientPort(config.TargetPort),
samforwarder.SetClientSAMHost(config.SamHost),
samforwarder.SetClientSAMPort(config.SamPort),
samforwarder.SetClientSigType(config.SigType),
samforwarder.SetClientName(config.TunName),
samforwarder.SetClientInLength(config.InLength),
samforwarder.SetClientOutLength(config.OutLength),
samforwarder.SetClientInVariance(config.InVariance),
samforwarder.SetClientOutVariance(config.OutVariance),
samforwarder.SetClientInQuantity(config.InQuantity),
samforwarder.SetClientOutQuantity(config.OutQuantity),
samforwarder.SetClientInBackups(config.InBackupQuantity),
samforwarder.SetClientOutBackups(config.OutBackupQuantity),
samforwarder.SetClientEncrypt(config.EncryptLeaseSet),
samforwarder.SetClientLeaseSetKey(config.LeaseSetKey),
samforwarder.SetClientLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samforwarder.SetClientLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samforwarder.SetClientAllowZeroIn(config.InAllowZeroHop),
samforwarder.SetClientAllowZeroOut(config.OutAllowZeroHop),
samforwarder.SetClientFastRecieve(config.FastRecieve),
samforwarder.SetClientCompress(config.UseCompression),
samforwarder.SetClientReduceIdle(config.ReduceIdle),
samforwarder.SetClientReduceIdleTimeMs(config.ReduceIdleTime),
samforwarder.SetClientReduceIdleQuantity(config.ReduceIdleQuantity),
samforwarder.SetClientCloseIdle(config.CloseIdle),
samforwarder.SetClientCloseIdleTimeMs(config.CloseIdleTime),
samforwarder.SetClientAccessListType(config.AccessListType),
samforwarder.SetClientAccessList(config.AccessList),
samforwarder.SetClientMessageReliability(config.MessageReliability),
samforwarder.SetClientPassword(config.KeyFilePath),
samforwarder.SetClientDestination(config.ClientDest),
)
if err != nil {
return nil, err
}
go handler.outproxy.Serve()
if handler.outproxytype == "http://" {
proxyURL, err := url.Parse(handler.GuaranteePrefix(handler.outproxy.Target()))
if err != nil {
return nil, err
}
handler.outproxydialer = http_dialer.New(proxyURL, http_dialer.WithTls(&tls.Config{}))
if err != nil {
return nil, err
}
handler.outproxyclient = &http.Client{
Transport: &http.Transport{
Dial: handler.outproxydialer.Dial,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
TLSClientConfig: &tls.Config{},
},
Timeout: time.Second * 300,
CheckRedirect: nil,
}
} else {
handler.outproxydialer, err = proxy.SOCKS5("tcp", handler.outproxy.Target(), nil, nil)
if err != nil {
return nil, err
}
handler.outproxyclient = &http.Client{
Transport: &http.Transport{
Dial: handler.outproxydialer.Dial,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
TLSClientConfig: &tls.Config{},
},
Timeout: time.Second * 300,
CheckRedirect: nil,
}
}
plog("setup outproxy on", handler.outproxy.Target())
} else {
if handler.outproxytype == "http://" {
proxyURL, err := url.Parse(handler.GuaranteePrefix(handler.UseOutProxy))
if err != nil {
return nil, err
}
handler.outproxydialer = http_dialer.New(proxyURL, http_dialer.WithTls(&tls.Config{}))
if err != nil {
return nil, err
}
handler.outproxyclient = &http.Client{
Transport: &http.Transport{
Dial: handler.outproxydialer.Dial,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
TLSClientConfig: &tls.Config{},
},
Timeout: time.Second * 300,
CheckRedirect: nil,
}
} else {
handler.outproxydialer, err = proxy.SOCKS5("tcp", handler.UseOutProxy, nil, proxy.Direct)
if err != nil {
return nil, err
}
handler.outproxyclient = &http.Client{
Transport: &http.Transport{
Dial: handler.outproxydialer.Dial,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
TLSClientConfig: &tls.Config{},
},
Timeout: time.Second * 300,
CheckRedirect: nil,
}
}
plog("setup outproxy on", handler.GuaranteePrefix(handler.UseOutProxy))
}
}
handler.Hasher, err = hashhash.NewHasher(len(strings.Replace(handler.Base32(), ".b32.i2p", "", 1)))
if err != nil {
return nil, err
@ -375,6 +546,8 @@ func NewHttpProxy(opts ...func(*SAMHTTPProxy) error) (*SAMHTTPProxy, error) {
handler.Conf.SamPort = "7656"
handler.Conf.ControlHost = "127.0.0.1"
handler.Conf.ControlPort = "7951"
handler.UseOutProxy = ""
handler.outproxytype = "http://"
for _, o := range opts {
if err := o(&handler); err != nil {
return nil, err

View File

@ -28,3 +28,16 @@ It also has an aggressive mode, which creates a whole new tunnel pool for every
single eepSite you visit, by domain(which means that if you visit both the
base32 and readable domain, it will create *two* destinations). I advise against
using it.
Features: Done
--------------
* Self-supervising, Self-restarting on Unixes
* CONNECT support
* "New Ident" signaling interface
Features: Planned
-----------------
* Outproxy Support
* Traffic Shaping