monkeyWie / proxyee

HTTP proxy server,support HTTPS&websocket.MITM impl,intercept and tamper HTTPS traffic.
MIT License
1.53k stars 573 forks source link

这个框架能否修改请求URL #65

Open wayddmldbzz opened 5 years ago

wayddmldbzz commented 5 years ago

需求是这样,比如app链接这个代理去访问A网站,但是我想改一下,在咱们这个代理收到转发请求时转发到B网站,https和http是否支持? 我试着改了一下改了之后不好使,也没有日志,请指教。

monkeyWie commented 5 years ago

可以的,把你的代码贴出来看看

wayddmldbzz commented 5 years ago

在你的例子上改了改 好使了,但是因为证书的关系被替换的url跟原先url前三级域名必须一致,可以改第四级,不知道怎么解,我把代码发出来您给看看改的对不

还有一个问题;您里面HttpProxyIntercept这个类里面对应四个方法是能拿到请求和响应的所有数据, 但是我想一次性把某个请求的所有请求头、请求体、响应头、响应体都收集完整后在返回给别的地方, 所以我想问这个这个类下面的方法是被串行调用的吗?

package com.github.monkeywie.proxyee;

import com.github.monkeywie.proxyee.exception.HttpProxyExceptionHandle;
import com.github.monkeywie.proxyee.intercept.HttpProxyIntercept;
import com.github.monkeywie.proxyee.intercept.HttpProxyInterceptInitializer;
import com.github.monkeywie.proxyee.intercept.HttpProxyInterceptPipeline;
import com.github.monkeywie.proxyee.server.HttpProxyServer;
import com.github.monkeywie.proxyee.server.HttpProxyServerConfig;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.*;

/**
 * @Author: LiWei
 * @Description 匹配到百度首页时重定向到指定url
 * @Date: 2019/3/4 16:23
 */
public class InterceptRedirectHttpProxyServer {
  public static void main(String[] args) {
    HttpProxyServerConfig config = new HttpProxyServerConfig();
    config.setHandleSsl(true);
    new HttpProxyServer()
            .serverConfig(config)
            .proxyInterceptInitializer(new HttpProxyInterceptInitializer() {
              @Override
              public void init(HttpProxyInterceptPipeline pipeline) {
                pipeline.addLast(new HttpProxyIntercept() {

                  /**
                   * 拦截代理服务器到目标服务器的请求头
                   */
                  public void beforeRequest(Channel clientChannel, HttpRequest httpRequest,
                                            HttpProxyInterceptPipeline pipeline) throws Exception {
                    String oldHost = null;
                    if (httpRequest.headers().get("HOST").equals("1-aaa.bbbb.cccc.com")) {
                      oldHost = httpRequest.headers().get("HOST");
                      httpRequest.headers().set("HOST", "2-aaa.bbbb.cccc.com");
                    }
                    System.out.println("OLD:" + oldHost + httpRequest.uri() + "       NEW:" + httpRequest.headers().get("HOST") + httpRequest.uri());
                    pipeline.beforeRequest(clientChannel, httpRequest);
                  }
                });
              }
            })
            .httpProxyExceptionHandle(new HttpProxyExceptionHandle() {
              @Override
              public void beforeCatch(Channel clientChannel, Throwable cause) throws Exception {
                cause.printStackTrace();
              }

              @Override
              public void afterCatch(Channel clientChannel, Channel proxyChannel, Throwable cause)
                      throws Exception {
                cause.printStackTrace();
              }
            })
            .start(9999);
  }
}
monkeyWie commented 5 years ago

是串行调用的,另外那个证书的三四级域名不会有影响的啊,客户端实际访问的还是A网站,代理服务器返回的也是A网站对应生成的中间人证书。

wayddmldbzz commented 5 years ago

这个我试过比如过来的请求本身想请求“a.stage.bbb.com”,我给改成“a.dev.bbb.com” 这时候转发是不成功的,服务也没有日志

monkeyWie commented 5 years ago

@wayddmldbzz 不好意思啊,测试了一下之前的代码确实不支持,现在重新修改过了代理的逻辑。 你这个功能可以参考下 :https://github.com/monkeyWie/proxyee/blob/master/src/test/java/com/github/monkeywie/proxyee/InterceptForwardHttpProxyServer.java

wayddmldbzz commented 5 years ago

@monkeyWie 哥们还有个问题,在我配上代理后有些软件(其实就是请求)是可以正常转发的,但是有些就转发不了不能用了,日志会提示一个异常,后来我想了下像这些不能抓包的软件(请求)能否过滤下不进行抓包(应该就是证书验证)直接转发,比如charles那样抓不了包的也可以转发 错误日志:(比如美拍,配上代理后加上证书后不能用) io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:475) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:283) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1421) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:697) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:632) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:549) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:511) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:830) Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:311) at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:285) at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:184) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164) at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:729) at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:684) at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:499) at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:475) at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:634) at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:282) at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1329) at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1224) at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1271) at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:505) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:444) ... 17 more

liming1985 commented 4 years ago

InterceptForwardHttpProxyServer.java 这个例子运行不成功呢, 而且我发现 beforeRequest 是在HttpProxyServerHandle的channelRead处理connect请求后执行的, 这样貌似没法处理https的请求吧

liming1985 commented 4 years ago

就是想实现一个域名转发的功能, https的, 类似charles的map remote功能;不仅仅是www.baidu.com重定向到www.taobao.com,而是相同的请求内容,包括header和body,由原来的A域名转发到B域名,给指点一下呗

monkeyWie commented 4 years ago

@liming1985 参考下这个:https://github.com/monkeyWie/proxyee/blob/master/src/test/java/com/github/monkeywie/proxyee/InterceptForwardHttpProxyServer.java https的要安装根证书

hanjiangxuehua commented 4 years ago

这种其实是将它分成客户端和服务端(C/S),两端分别存储转存原来域名以达到规避公司拦截的目的,是可以实现的,其实主要代码大神monkeywie已经做完,仔细阅读大神代码就可以做到

luyuanwan commented 4 years ago

https://github.com/monkeyWie/proxyee/issues/65#issuecomment-557368158 我也想弄一个类似charles的,不仅仅是修改响应内容,数据由原来的发往A域名实际转发到B域名

hanjiangxuehua commented 4 years ago

感觉作为服务端中转效率有点低下,可能我用法不对吧

---原始邮件--- 发件人: "大雁小鱼"<notifications@github.com> 发送时间: 2020年8月22日(周六) 下午4:11 收件人: "monkeyWie/proxyee"<proxyee@noreply.github.com>; 抄送: "Comment"<comment@noreply.github.com>;"hanjiangxuehua"<844308604@qq.com>; 主题: Re: [monkeyWie/proxyee] 这个框架能否修改请求URL (#65)

65 (comment)

我也想弄一个类似charles的,不仅仅是修改响应内容,数据由原来的发往A域名实际转发到B域名

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.