前言
作为一种常见的服务器防御网络攻击或探测手段,封 IP 可以有效地保护服务器免受恶意攻击。在进行安全测试时,安全人员需要使用代理来隐藏真实 IP 地址,并依靠代理池获取可用的代理地址。同时,为了更方便地在某些工具中使用代理,可以借助隧道代理直接将请求转发给不同的代理服务器,从而避免 IP 被封锁。
本文介绍了一种利用 Docker 搭建代理池和隧道代理的方法,并通过对 httpbin.org 的访问和红队工具 dirsearch 的使用进行了测试。这种方法能够快速搭建一个免费、高效、稳定且易于管理的代理环境,在进行网络渗透测试等任务时非常有帮助。
下图为搭建过程的流程图:
Docker 的准备
我这里都是使用的 Docker 搭建。
Docker 可能用到的命令如下:
# 查看当前运行的 docker 容器 ID 和运行状况
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c09ae6b9c554 tunnel_proxy:0.02 "/usr/local/openrest…" 2 hours ago Up 2 hours tunnel_proxy
17bc67d0f892 germey/proxypool:master "supervisord -c supe…" 2 hours ago Up 2 hours 0.0.0.0:5555->5555/tcp, :::5555->5555/tcp proxypool
b659295a7927 redis:alpine "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp redis4proxypool
[root@localhost ~]# docker exec -it 17 /bin/sh
/app # ls
Dockerfile README.md docker-compose.yml kubernetes release.sh run.py supervisord.log
LICENSE build.yaml examples proxypool requirements.txt supervisord.conf
exit 退出
命令:docker exec -it <id> /bin/bash
在指定 id 的 Docker 容器中执行指令,id 通过docker ps
命令来获取。如果执行的是 shell 程序比如 /bin/bash 或者 /bin/sh 就能进入到容器的 shell 里,可以执行一些 linux 指令,id 可以使用前几位可以区分不同容器的字符就行,我这里用的前两位。
如果在接下来的配置中有问题,可以使用这种方式进入容器里查看日志,或者按照我的配置将日志文件映射到本地。
启动 Docker 用的程序是 docker-compose。如果你输入 docker-compose 提示找不到这个程序,有可能是没有安装或者是 /bin 目录下没有。
使用docker info
命令查看 docker-compose 程序的位置
[root@localhost ~]# docker info
Client: Docker Engine - Community
Version: 24.0.2
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.10.5
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.18.1
Path: /usr/libexec/docker/cli-plugins/docker-compose
检查一下 docker-compose 有无执行权限,如果没有,就要sudo chmod +x /usr/local/bin/docker-compose
赋予执行权限
[root@localhost proxy_pool]# cd /usr/libexec/docker/cli-plugins/
[root@localhost cli-plugins]# ll
总用量 108356
-rwxr-xr-x 1 root root 56327368 5月 26 05:56 docker-buildx
-rwxr-xr-x 1 root root 54627904 5月 20 02:09 docker-compose
如果无法直接运行 docker-compose,可能需要创建软链接
[root@localhost cli-plugins]# ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose
[root@localhost work]# docker-compose --version
Docker Compose version v2.18.1
代理池 ProxyPool
我这里用的是开源的代理池,自动从免费代理网站上爬取 http 代理。Python3WebSpider/ProxyPool
这个项目有四个模块:获取IP模块,存储模块,检测模块,接口模块。它包含两个 Docker 容器:redis4proxypool 和 proxypool,对于容器的设置都在 ProxyPool 根目录的 docker-compose.yml 文件里。对于容器的配置留到下部分再详细描述,先跑起来再说。
首先 gitclone
git clone https://github.com/Python3WebSpider/ProxyPool.git
cd ProxyPool
然后启动 docker 环境
docker-compose up
这时候如果防火前的 5555 端口是开放的,访问 http://<当前 ip>:5555/random 即可随机获取一个可用代理,不需要做任何的修改。效果图如下:
random 接口返回的是随机的高分 IP,也就是已验证能访问测试 URL 的 IP。高分,指的是在 redis 数据库中,获取 IP 模块获取的每一条 IP 的分数,如果检测模块用 IP 访问测试链接,能成功访问则设置这个分数为 100,单次测试访问失败则将分数减 1。
ProxyPool 的配置
在 ProxyPool 目录下使用命令docker-compose down
可以关闭 docker。接下来,我们修改 ProxyPool 的配置。它包含两个容器,一个是 redis4proxypool,也就是 redis 数据库的部分,下文用 redis 来代替,另一个容器是 proxypool,也就是负责代理池逻辑的部分。
redis
为了查看或者 redis 里的这些数据,首先要设置 docker-compose.yml,设置 6374 的端口映射
version: "3"
services:
redis4proxypool:
image: redis:alpine
container_name: redis4proxypool
# 把容器内部的 6379 端口映射到宿主机(host)的 6374 端口,这样就可以通过宿主机的 6374 端口来访问容器内部的 Redis 数据库
ports:
- "6374:6379"
proxypool:
image: "germey/proxypool:master"
container_name: proxypool
ports:
- "5555:5555"
restart: always
# volumes:
# - proxypool/crawlers/private:/app/proxypool/crawlers/private
environment:
PROXYPOOL_REDIS_HOST: redis4proxypool
开启容器之后,要查看 redis 用到的命令如下:
[root@localhost ProxyPool]# redis-cli -h 127.0.0.1 -p 6374
keys * 获取 redis 中所有的 key
127.0.0.1:6374> keys *
- "proxies:universal"
type <key> 获取 key 的类型
127.0.0.1:6374> type proxies:universal
zset
因为是 zset 有序类型,所以用 zrange 获取所有数据,后面两个参数是开始位置和结束位置
127.0.0.1:6374> zrange proxies:universal 0 -1
...
18156) "72.44.101.173:8080"
18157) "95.56.254.139:3128"
获取分数为 100 的,用 zrangebyscore,后面两个参数是最小值和最大值
127.0.0.1:6374> zrangebyscore proxies:universal 99 100
"103.189.96.98:8085"
"186.121.235.66:8080"
"200.4.217.203:999"
"103.74.121.88:3128"
"117.251.103.186:8080"
...exit 退出
proxypool
针对 proxypool 也有不少设置可以自定义,在使用 Docker 的情况下,在 docker-compose.yml 文件中,设置 environment 参数即可。
这里修改了 volumes 参数,把容器里的指定文件夹映射到宿主机的指定位置。proxypool 在容器里工作的根目录是 /app,所以这里是把 /app/proxypool/logs 文件夹映射到主机的 ProxyPool/logs/proxypool 目录下。
设置了以下环境变量:
CYCLE_TESTER, Tester 运行周期,即间隔多久运行一次测试,默认 20 秒,这里修改为 5 秒。
PROXYPOOL_REDIS_PORT,容器内部的 6379 连接 redis4proxypool。
TEST_URL, 测试 URL,默认百度,指定要爬取的 URL。
REDIS_KEY,redis 储存代理使用字典的名称,其中 PROXYPOOL_REDIS_KEY 会覆盖 REDIS_KEY 的值。
LOG_DIR: "proxypool/logs" ,这个参数不知道为啥设置了并没有什么用,尝试了 n 遍,本来按照源码,没有上面这个参数也应该写到 logs 相对目录下,但是程序并没有写入,所以保存日志文件只能用下面这种相对路径的写法。
LOG_RUNTIME_FILE,运行日志文件名称。
LOG_ERROR_FILE,错误日志文件名称。
加了 depends_on 参数,意思是先启动 redis4proxypool 在启动 proxypool,这样确保在启动 proxypool 之前先启动了 redis4proxypool,以避免可能的连接问题。
version: "3"
services:
redis4proxypool:
image: redis:alpine
container_name: redis4proxypool
ports:
- "6374:6379"
proxypool:
image: "germey/proxypool:master"
container_name: proxypool
ports: - "5555:5555"
restart: always
volumes:
./logs/proxypool:/app/proxypool/logsvolumes:
- proxypool/crawlers/private:/app/proxypool/crawlers/private
environment:
CYCLE_TESTER: 5
PROXYPOOL_REDIS_HOST: redis4proxypool
PROXYPOOL_REDIS_PORT: 6379
TEST_URL: https://httpbin.org/ip
REDIS_KEY: proxies:httpbin
LOG_RUNTIME_FILE: "./proxypool/logs/proxypool_runtime.log"
LOG_ERROR_FILE: "./proxypool/logs/proxypool_error.log"
depends_on:
redis4proxypool
隧道代理
我们使用一些扫描或者爆破工具的时候,大部分情况下,配置选项中只能选择一条代理,被封 IP 的可能性仍然很大,有没有什么方法能在请求的时候自动切换代理服务器呢?这就是隧道代理。
隧道代理服务器,能将接收到的请求随机或者按规则转发给不同的代理,这样,相当于在工具中只需要设置代理为隧道代理服务器,自动切换 IP 的任务交给隧道代理。
我这里使用的 OpenResty 搭建的隧道代理,也是用的 Docker,并把配置整合到了 docker-compose.yml 文件中。
参考链接:openresty实现隧道代理