func (m *Muxy) LoadPlugins() { // Load Configuration var err error var confLoader *plugo.ConfigLoader c := &PluginConfig{} if m.config.ConfigFile != "" { confLoader = &plugo.ConfigLoader{} err = confLoader.LoadFromFile(m.config.ConfigFile, &c) if err != nil { log.Fatalf("Unable to read configuration file: %s", err.Error()) } } else { log.Fatal("No config file provided") } log.SetLevel(log.LogLevel(c.LogLevel)) // Load all plugins m.middlewares = make([]Middleware, len(c.Middleware)) plugins := plugo.LoadPluginsWithConfig(confLoader, c.Middleware) for i, p := range plugins { log.Info("Loading plugin \t" + log.Colorize(log.YELLOW, c.Middleware[i].Name)) m.middlewares[i] = p.(Middleware) } m.proxies = make([]Proxy, len(c.Proxy)) plugins = plugo.LoadPluginsWithConfig(confLoader, c.Proxy) for i, p := range plugins { log.Info("Loading proxy \t" + log.Colorize(log.YELLOW, c.Proxy[i].Name)) m.proxies[i] = p.(Proxy) m.proxies[i].Setup(m.middlewares) } }
func (l *LoggerMiddleware) HandleEvent(e muxy.ProxyEvent, ctx *muxy.Context) { switch e { case muxy.EVENT_PRE_DISPATCH: if ctx.Request == nil { if len(ctx.Bytes) > 0 { log.Info("Handle TCP event " + log.Colorize(log.GREY, "PRE_DISPATCH") + fmt.Sprintf(" Received %d%s", len(ctx.Bytes), " bytes")) data := fmt.Sprintf(l.format, ctx.Bytes) log.Debug("Handle TCP event " + log.Colorize(log.GREY, "PRE_DISPATCH") + " Received request: " + bytesTab + log.Colorize(log.BLUE, data)) } } else { log.Info("Handle HTTP event " + log.Colorize(log.GREY, "PRE_DISPATCH") + " Proxying request " + log.Colorize(log.LIGHTMAGENTA, ctx.Request.Method) + log.Colorize(log.BLUE, " \""+ctx.Request.URL.String()+"\"")) } case muxy.EVENT_POST_DISPATCH: if ctx.Request == nil { if len(ctx.Bytes) > 0 { log.Info("Handle TCP event " + log.Colorize(log.GREY, "POST_DISPATCH") + fmt.Sprintf(" Sent %d%s", len(ctx.Bytes), " bytes")) data := fmt.Sprintf(l.format, ctx.Bytes) log.Debug("Handle TCP event " + log.Colorize(log.GREY, "POST_DISPATCH") + " Sent response: " + bytesTab + log.Colorize(log.BLUE, data)) } } else { log.Info("Handle HTTP event " + log.Colorize(log.GREY, "POST_DISPATCH") + " Returning " + log.Colorize(log.GREY, fmt.Sprintf("%s", ctx.Response.Status))) } } }
func (p *proxy) start() { log.Trace("Starting TCP Proxy") defer p.lconn.Close() //connect to remote rconn, err := net.DialTCP("tcp", nil, p.raddr) if err != nil { p.err("Remote connection failed: %s", err) return } p.rconn = rconn defer p.rconn.Close() //nagles? if p.nagles { p.lconn.SetNoDelay(true) p.rconn.SetNoDelay(true) } //display both ends log.Info("Opened %s >>> %s", p.lconn.RemoteAddr().String(), p.rconn.RemoteAddr().String()) //bidirectional copy go p.pipe(p.lconn, p.rconn) go p.pipe(p.rconn, p.lconn) //wait for close... <-p.errsig log.Info("Closed (%d bytes sent, %d bytes received)", p.sentBytes, p.receivedBytes) }
func (m *Muxy) Run() { m.LoadPlugins() // Setup all plugins... for _, m := range m.middlewares { m.Setup() } // Interrupt handler sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, os.Kill) // Start proxy for _, proxy := range m.proxies { go proxy.Proxy() } // Block until a signal is received. <-sigChan log.Info("Shutting down Muxy...") for _, m := range m.middlewares { m.Teardown() } }
func (p *HttpProxy) Proxy() { log.Info("HTTP proxy listening on %s", log.Colorize(log.BLUE, fmt.Sprintf("%s://%s:%d", p.Protocol, p.Host, p.Port))) pkiMgr, err := pki.New() checkHttpServerError(err) config, err := pkiMgr.GetClientTLSConfig() checkHttpServerError(err) config.InsecureSkipVerify = false mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { director := func(req *http.Request) { req = r req.URL.Scheme = p.ProxyProtocol req.URL.Host = fmt.Sprintf("%s:%d", p.ProxyHost, p.ProxyPort) } proxy := &ReverseProxy{Director: director, Middleware: p.middleware} proxy.Transport = &http.Transport{ Proxy: http.ProxyFromEnvironment, TLSClientConfig: config, TLSHandshakeTimeout: 10 * time.Second, } proxy.ServeHTTP(w, r) }) if p.Protocol == "https" { checkHttpServerError(err) checkHttpServerError(http.ListenAndServeTLS(fmt.Sprintf("%s:%d", p.Host, p.Port), pkiMgr.Config.ClientCertPath, pkiMgr.Config.ClientKeyPath, mux)) } else { checkHttpServerError(http.ListenAndServe(fmt.Sprintf("%s:%d", p.Host, p.Port), mux)) } }
func (p *HttpProxy) Proxy() { log.Info("HTTP proxy listening on %s", log.Colorize(log.BLUE, fmt.Sprintf("http://%s:%d", p.Host, p.Port))) mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { director := func(req *http.Request) { req = r req.URL.Scheme = p.ProxyProtocol req.URL.Host = fmt.Sprintf("%s:%d", p.ProxyHost, p.ProxyPort) } proxy := &ReverseProxy{Director: director, Middleware: p.middleware} proxy.ServeHTTP(w, r) }) err := http.ListenAndServe(fmt.Sprintf("%s:%d", p.Host, p.Port), mux) if err != nil { log.Info("ListenAndServe error: ", err.Error()) } }
func (p *TcpProxy) Proxy() { log.Trace("Checking connection: %s:%d", p.Host, p.Port) laddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", p.Host, p.Port)) check(err) log.Trace("Checking connection: %s:%d", p.ProxyHost, p.ProxyPort) raddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", p.ProxyHost, p.ProxyPort)) check(err) listener, err := net.ListenTCP("tcp", laddr) check(err) for { log.Info("TCP proxy listening on %s", log.Colorize(log.BLUE, fmt.Sprintf("tcp://%s:%d", p.Host, p.Port))) conn, err := listener.AcceptTCP() if err != nil { fmt.Printf("Failed to accept connection '%s'\n", err) continue } p.connId++ p := &proxy{ lconn: conn, laddr: laddr, raddr: raddr, packetsize: p.PacketSize, erred: false, errsig: make(chan bool), prefix: fmt.Sprintf("Connection #%03d ", p.connId), hex: p.HexOutput, nagles: p.NaglesAlgorithm, middleware: p.middleware, // matcher: matcher, // replacer: replacer, } go p.start() } }