安全矩阵

 找回密码
 立即注册
搜索
查看: 2398|回复: 0

浅谈反向代理技术

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2021-11-2 20:01:15 | 显示全部楼层 |阅读模式
原文链接:浅谈反向代理技术

在如今越来越复杂的网络环境中,对于渗透测试工作者的要求也逐渐提高。从最开始的纯IP网站裸奔(好吧,如今依然有大量企业、政府网站这么做),到后来高防、CDN、防CC概念提出、再到如今各大厂商云防护竞争愈演愈烈,如何最大程度适应大形势下的安全运维习惯,这是对于渗透测试工程师最为迫切的要求。
本篇侧重点为反向代理技术,从攻击者视角洞察安全运维习惯,当然,在此之前,我们得先来再完整熟悉下代理技术。
目前大家提到的代理技术无外乎三种:正向代理、透明代理和反向代理,以下我们以B/S架构为例简单介绍其中的区别。
正向代理(forward proxy)
客户端将请求转发给代理服务器,代理服务器再负责转发给目标网站,响应时服务端先响应给代理服务器,代理服务器再转发给对应的客户端。

当然,正向代理可以但不限于为局域网内客户端做代理,同样可以选择公网服务器作为代理,它扮演的角色类似于NAT。

透明代理(transparent proxy)
透明代理也叫做内网代理(inline proxy)、拦截代理(intercepting proxy)以及强制代理(force proxy),所谓透明,即代理对客户端具有无感知性,即不需要客户端进行额外配置。

透明代理和正向代理基本相似,甚至是透明代理可以作为正向代理的一种。
透明代理技术经常作为一种备选模式存在,如在防火墙中作为策略,对部分流量进行过滤拦截;一般公司内的上网行为管理系统也是透明代理的应用。
另外如果有喜欢玩路由器的表哥应该接触过梅林、潘多拉系统,其中的代理模式对于网络使用者亦是透明代理的应用。
总的来说,只要是网关或主链路上的网络设备均可以实现透明代理模式,或者配合路由转发等技术搭配使用效果更佳。

反向代理(Reverse proxy)
反向代理是为服务端转发请求,客户端将请求发送至反向代理服务器,反向代理服务器再将请求转发给真正的服务器以处理请求,响应时后端真正的服务器将处理结果发送给反向代理,再由反向代理构建响应并响应给客户端。

当然,反向代理服务器并非一定要和目标网站相同内网,我们有时候会在网上发现http/https跳板,我们访问的目标也并不是目标内网内容,但这依然是一项反向代理技术的应用。

至于反向代理的优点,众说纷纭,毕竟优点是跟着需求走的,但无外乎以下几点:减少公网IP的使用、防止外网对内网服务器的恶性攻击、缓存以减少服务器的压力和访问安全控制、负载均衡将用户请求分配给多个服务器、加上一些特殊的东西做特殊的事情(如IPS—入侵防御系统、web应用防火墙等)。
接下来,我们便来探究反向代理技术的具体实现,这些实现方式将为我们的生产系统内网横向(区别于办公内网)提供大量辅助信息。
反向代理技术 - nginx篇我们在本机1988端口开放一个web站点,并绑定域名 test.rabbitmask.com。
主站域名为 www.rabbitmask.com,如果没有配置dns服务器可以借助hosts文件修改代替。
我们自然可以直接修改/etc/nginx/nginx.conf,然而在真正运维的习惯中,他们是不会接受一个又臭又长的单文件的,我们更多的会使用单文件实现,习惯上可能会使用域名作为文件名,这里我们使用test.conf。
  1. # test.conf
  2. server {
  3.         listen       80;
  4.         server_name  test.rabbitmask.com;

  5.         location / {
  6.             proxy_pass http://127.0.0.1:1988;
  7.             index  index.html;
  8.         }
  9.     }
复制代码

  1. # nginx.conf
  2.         ... ...
  3.   include /etc/nginx/conf.d/*.conf;
  4.   include /etc/nginx/sites-enabled/*;
  5.         ... ...
复制代码


在nginx.conf中我们可以看到conf.d中的*.conf文件和sites-enabled中的全部文件,均会自动加载,所以我们本次将test.conf丢到sites-enabled中,这些主观性较强运维习惯也是我们作为攻击者需要去关注的点。

sudo nginx -s reload热重载即可刷新配置。

如上,即可实现最基础的nginx反向代理设置。
反向代理技术 - Apache篇与nginx类似,我们在/etc/apache2/apache2.conf可以看到如下配置:
  1. #apache2.conf
  2.         ... ...
  3. # Include generic snippets of statements
  4. IncludeOptional conf-enabled/*.conf

  5. # Include the virtual host configurations:
  6. IncludeOptional sites-enabled/*.conf
  7.         ... ...
复制代码


同样,在这里我们在sites-enabled下创建我们的test.conf:
  1. ServerName www.rabbitmask.com
  2. ProxyRequests off

  3. <Proxy *>
  4.     Order allow,deny
  5.     Allow from all
  6. </Proxy>

  7. ProxyPass /test http://127.0.0.1:1988
  8. ProxyPassReverse /test http://127.0.0.1:1988
复制代码


需要开启相关模块
  1. # 查看当前开启模块
  2. apachectl -M
  3. # 开启反向代理所需模块
  4. a2enmod proxy
  5. a2enmod proxy_http
复制代码


重启服务
  1. /etc/init.d/apache2 restart
  2. or
  3. systemctl restart apache2
复制代码


我们可以看到,和nginx的反代还是存在差异的,apache的反代是基于路由的,如果我们在渗透过程中发现,相同域名下对应的中间件存在差异,大家可以往这边考虑一下。

另外,在实际场景之中,nginx + apache的组合也是很常见的,其实就是Nginx做前端,Apache做后端。因为Nginx对于高并发性能出众,Proxy功能强效率高,占用系统资源少,而Apache在高并发时对队列的处理比FastCGI(Nginx需要通过fastcgi等方式运行php)更好,并且在处理动态php页面时,mod_php也比php-cgi更稳定更高效。
反向代理技术 - FRP篇我一直都晓得frp可以做域名反代,但是在一次渗透活动中,拿到反代服务器后,没有找到nginx,却看到了frp的那一刻,我还是有些懵的。

这个没啥好说的,不懂的翻我之前的教程,直接上配置:
  1. # frps.ini
  2. [common]
  3. bind_port = 7000
  4. vhost_http_port = 8080
复制代码

  1. [common]
  2. server_addr = 127.0.0.1
  3. server_port = 7000

  4. [web_www]
  5. type = http
  6. local_ip = 192.168.124.21
  7. local_port = 80
  8. custom_domains = www.rabbitmask.com

  9. [web_test]
  10. type = http
  11. local_ip = 192.168.124.30
  12. local_port = 1988
  13. custom_domains = test.rabbitmask.com
复制代码



反向代理技术 - Java篇我们这里我们以Springboot为例,借助HTTP Proxy Servlet 代理服务实现。
  1. # pom.xml
  2.         <!-- https://mvnrepository.com/artifact/org.mitre.dsmiley.httpproxy/smiley-http-proxy-servlet -->
  3.         <dependency>
  4.             <groupId>org.mitre.dsmiley.httpproxy</groupId>
  5.             <artifactId>smiley-http-proxy-servlet</artifactId>
  6.             <version>1.12</version>
  7.         </dependency>
  8.         <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
  9.         <dependency>
  10.             <groupId>com.google.guava</groupId>
  11.             <artifactId>guava</artifactId>
  12.             <version>30.0-jre</version>
  13.         </dependency>
复制代码
  1. # application.properties
  2. proxy.servlet_url: /test
  3. proxy.target_url: http://test.rabbitmask.com
复制代码

  1. # Controller.Hello
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;

  4. @RestController
  5. public class Hello {
  6.     @RequestMapping("/")
  7.     public String sayHello(){
  8.         return "Hello.It's a reverse proxy server";
  9.     }
  10. }
复制代码

# Configuration.RabbitConfiguration
  1. import com.google.common.collect.ImmutableMap;
  2. import org.mitre.dsmiley.httpproxy.ProxyServlet;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;


  7. import javax.servlet.Servlet;
  8. import java.util.Map;


  9. @Configuration
  10. public class RabbitConfiguration {


  11.     @Value("${proxy.servlet_url}")
  12.     private String servlet_url;
  13.     @Value("${proxy.target_url}")
  14.     private String target_url;



  15.     @Bean
  16.     public Servlet createProxyServlet(){
  17.         return new ProxyServlet();
  18.     }
  19.     @Bean
  20.     public ServletRegistrationBean<Servlet> proxyServletRegistration(){
  21.         ServletRegistrationBean<Servlet> registrationBean = new ServletRegistrationBean<>(createProxyServlet(), servlet_url);
  22.         //设置网址以及参数
  23.         Map<String, String> params = ImmutableMap.of(
  24.                 "targetUrl", target_url,
  25.                 "log", "true");
  26.         registrationBean.setInitParameters(params);
  27.         return registrationBean;
  28.     }
  29. }
复制代码

显然,java HTTP Proxy Servlet的反向代理技术也是基于路由的。

总结
本文从中间件层(nginx篇、apache篇)、工具层(frp篇)、开发语言层(java篇)浅谈了下反向代理技术在当今互联网中的应用,本文的切入点更倾向于web渗透中面对比较多的HTTP反向代理技术,其中nginx和frp实现的反向代理是基于域名的,而apache和java实现的反向代理是基于路由的,在apache篇结尾我们也提到过了,我们可以借助这些特性和各自的优势组合使用。

在丰富的中间件、工具、语言大环境下,反向代理技术绝对不仅仅文中提到的这几项而已,关于反向代理技术我们更多想提及的是一种思想,希望借本文抛砖引玉,能让各位小伙伴在来自运维侧和开发侧的迷魂阵中拨云见日。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-22 23:04 , Processed in 0.013815 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表