使用V2rayN将SSR所有节点在本地开放单独Socks5链接端口

需求前因:

我们写了一个抓取Telegram社交账号群聊信息的数据爬虫,每个爬虫脚本都使用了一个Telegram账号,如果多个账号使用同一个ip进行抓取,自然会封号,就gg了,所以我们需要多个Socks5代理,但是想了想很不划算,谷歌上搜了一下,一个代理一个月竟然要80$,富人爆金币,穷人靠变异。

设想思路:

我自己经常用的Socks5节点是本地127.0.0.1:7890来自我的ssr付费节点Clash客户端订阅实现,但是他只能选择一个节点,想切换IP需要手动选择节点,依然在7890上。

所以,我的订阅有50个节点,可以让每个节点都启动在本地不同端口上吗?于是有了这个话

调研抄作业:

OK,有了思路就开干,但是咱确实没干过,谷歌搜了一下,不靠谱。但是在Youtobe上看到一个博主,实现了这个技术:

里面提到了,将订阅的内容进行转换,然后利用V2rayN的自定义配置服务器功能来实现。

实现步骤:

在Clash中点击编辑:

查看Config内容

然后复制内容,去在线转换,但是这里就不用博主用的那个转换网址了,我发现他的在线是上传的,会在他服务器保存,所以我 借鉴 了他的js代码部分,来本地写了一个(核心代码附在文末)

于是得到了一个yaml文件

把他放在V2rayN同目录,然后打开V2rayN,选择第一个 添加自定义配置服务器,然后选择这个文件,注意socks5端口随意写,但是不要跟配置文件生成的端口号冲突

然后右键设为活动服务器

到这里,V2rayN就配置完成了,但是怎么测试是否有效呢,

1.使用浏览器代理配置一些端口测试,或者使用代理端口,不过我觉得挺费劲的。所以写了个python自动脚本测试。

实现效果:

批量测试代理可用性思路

  • 脚本批量链接代理地址 socks5://127.0.0.1:{端口起-端口止}
  • 连接后请求一个接口获取本地IP,也就是说这个接口会返回请求者的IP,也就是咱们的隧道代理的节点IP,然后打印出来
  • 统计可用的端口数,和得到的内容数IP去重,得到IP数量(有些无良节点商一个IP设置两个节点)

代码实现:

设置的IP接口为 https://cloudflare-cdn.make-everything.pics/ip.php

<?php 
if ($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"])
{
  $ip = $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];
}
elseif ($HTTP_SERVER_VARS["HTTP_CLIENT_IP"])
{
  $ip = $HTTP_SERVER_VARS["HTTP_CLIENT_IP"];
}
elseif ($HTTP_SERVER_VARS["REMOTE_ADDR"])
{
  $ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];
}
elseif (getenv("HTTP_X_FORWARDED_FOR"))
{
  $ip = getenv("HTTP_X_FORWARDED_FOR");
}
elseif (getenv("HTTP_CLIENT_IP"))
{
  $ip = getenv("HTTP_CLIENT_IP");
}
elseif (getenv("REMOTE_ADDR"))
{
  $ip = getenv("REMOTE_ADDR");
}
else
{
  $ip = "Unknown";
}
echo $ip ;
?>

Python实现批量链接Socks5代理并获取IP内容

import requests
import socks

# 设置代理地址和端口范围
proxy_base_url = "socks5://127.0.0.1:"
proxy_ports = range(16000, 16051)

# 目标URL
target_url = "https://cloudflare-cdn.make-everything.pics/ip.php"

# 初始化可用端口和内容集合
available_ports = set()
unique_contents = set()

# 批量链接代理并获取内容
for port in proxy_ports:
    proxy_url = f"{proxy_base_url}{port}"

    # 设置代理
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }

    # 使用requests发送GET请求
    try:
        response = requests.get(target_url, proxies=proxies, timeout=5)
        content = response.text

        # 记录可用端口
        available_ports.add(port)

        # 记录内容,去重
        unique_contents.add(content)
        
        print(f"{proxy_url} 》》》 {content}")
    except requests.exceptions.RequestException as e:
        print(f"{proxy_url} 》》》 (该端口链接失败)")

# 打印结果
print(f"\n共 {len(available_ports)} 个可用端口")
print(f"去重后共 {len(unique_contents)} 个可用IP")

SSR节点转本地Socks5多端口的html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节点配置转换工具</title>
    <!-- 引入 jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <!-- 引入 js-yaml -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.0.0/js-yaml.min.js"></script>
    <!-- 引入 Bootstrap 4 CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>

<div class="container mt-5">
    <h1 class="mb-4">节点配置转换工具</h1>

    <div class="alert alert-info" role="alert">
        <strong>相关内容:</strong>
        <ul>
            <li><a href="https://github.com/2dust/v2rayN/releases/tag/6.23" target="_blank">v2rayN代理工具</a> - https://github.com/2dust/v2rayN/releases/tag/6.23</li>
            <li><a href="https://bulianglin.com/archives/51.html" target="_blank">本地订阅转换工具</a> - https://bulianglin.com/archives/51.html</li>
            <li><a href="https://youtu.be/01F8xUxqmkY" target="_blank">视频教程</a> - https://youtu.be/01F8xUxqmkY</li>
        </ul>
    </div>

    <div class="form-group">
        <label for="inputYAML">输入节点配置信息:</label>
        <textarea class="form-control" id="inputYAML" rows="10" placeholder="在这里输入节点配置信息"></textarea>
    </div>

    <div class="form-group">
        <label for="startPort">起始端口号:</label>
        <input type="number" class="form-control" id="startPort" value="11000" />
    </div>

    <button class="btn btn-primary" id="processButton">生成配置文件</button>

    <div class="mt-3" id="infoDiv"></div>
    <div class="mt-3" id="outputDiv">
        <h4>生成成功后的内容:</h4>
        <textarea class="form-control" id="outputYAML" rows="10" readonly></textarea>
    </div>
</div>

<!-- 引入 Bootstrap 4 JS 和 Popper.js -->
<script src="https://code.jquery.com/jquery-3.6.4.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

<script type="text/javascript">
    $(document).ready(function () {
        $('#processButton').click(function () {
            const inputYAML = $('#inputYAML').val();
            const startPort = parseInt($('#startPort').val());
            const infoDiv = $('#infoDiv');
            const outputDiv = $('#outputDiv');

            try {
                const yamlData = jsyaml.load(inputYAML);
                const numProxies = yamlData.proxies.length;
                const newYAML = {
                    'allow-lan': true,
                    dns: {
                        enable: true,
                        'enhanced-mode': 'fake-ip',
                        'fake-ip-range': '198.18.0.1/16',
                        'default-nameserver': ['114.114.114.114'],
                        nameserver: ['https://doh.pub/dns-query']
                    },
                    listeners: [],
                    proxies: yamlData.proxies
                };
                newYAML.listeners = Array.from({ length: numProxies }, (_, i) => ({
                    name: `mixed${i}`,
                    type: 'mixed',
                    port: startPort + i,
                    proxy: yamlData.proxies[i].name
                }));
                const newYAMLString = jsyaml.dump(newYAML);

                // 显示生成成功后的内容
                $('#outputYAML').val(newYAMLString);
                const blob = new Blob([newYAMLString], { type: 'text/yaml' });
                const downloadLink = document.createElement('a');
                downloadLink.href = URL.createObjectURL(blob);
                downloadLink.download = 'config.yaml';
                downloadLink.textContent = '点击此处下载生成的节点文件';

                // 清空原有内容
                infoDiv.html("");
                outputDiv.html("");

                // 将生成的内容追加到 #outputDiv
                outputDiv.append("<h4>生成成功:</h4>");
                outputDiv.append(downloadLink);
                outputDiv.append("<textarea class='form-control' id='outputYAML' rows='10' readonly>" + newYAMLString + "</textarea>");
                

                infoDiv.html(`起始端口:${startPort},结束端口:${startPort + numProxies - 1},共发现了${numProxies}个节点,生成了${numProxies}个端口`);
            } catch (error) {
                infoDiv.html('发生异常,请确认文件格式正确,或尝试刷新页面重试!');
            }
        });
    });
</script>
</body>
</html>
我很爱交朋友,欢迎联系我
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇