crossGFW玩具档案

这是一个玩具脚本,能在windows和linux上面跑。当时有一个网站提供免费的ss账号,但是账号、密码会定时变更,所以写了这个脚本来爬取免费vpn账号,然后配置好参数,最后双击启动shadowsocks。 好傻吊的玩具,被我校招时一直写简历上面,哈哈。放在 repo 里面,感觉不值得,以文章的形式留个纪念吧!

项目树状结构图:

.
├── Shadowsocks.exe
├── crossGFW.jar
├── gui-config.json
├── src
│   ├── GetData2Json.java
│   ├── Main.java
│   ├── Server.java
│   └── StartProxy.java
├── sss.bat
└── statistics-config.json

1 directory, 9 files

入口

入口很简单,双击 sss.bat 脚本,代理就自己挂上了。但是貌似在jar包里面也启动了ss代理,搞不懂啊。

java -jar crossGFW.jar
type gui-config.json
pause

抓取免费账号

现在的疑问为什么当时不用Python写,非得用Java。

此处的入口是一个Main方法,它主要抓取免费账号、填充vpn配置和启动ss。

/**
 * Created by fcy on 2017/3/6.
 */
public class Main {
    public static void main(String[] args) {
        GetData2Json.getJson();
        StartProxy.start();
    }
}

抓取免费账号与填充配置

主要逻辑:

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by fcy on 2017/3/6.
 */
public class GetData2Json {
    private static List<String> urlList ;
    private static List<Server> serverList = new ArrayList<Server>();
    static{
        urlList = new ArrayList<String>();
        urlList.add("http://www.ishadowsocks.net");
        urlList.add("https://freessr.xyz");
    }
    public static String getHTML(String url){
        StringBuffer sb = new StringBuffer();
        BufferedReader br;
        String line = null;
        try{
            URL url1 = new URL(url);
            URLConnection conn = url1.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
            conn.connect();
            br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            while ((line = br.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            return sb.toString();
        }

    }
    private static void initData(){
        String re = "                    <h4>[ABC]服务器地址:([^<]*)</h4>\n" +
                        "                    <h4>端口:([^<]*)</h4>\n" +
                        "<h4>[ABC]密码:([^<]*)</h4>\n" +
                        "                    <h4>加密方式:([^<]*)</h4>\n";
        String HTML;
        HTML = getHTML(urlList.get(0));
        Pattern p = Pattern.compile(re);
        Matcher m = p.matcher(HTML);
        while(m.find()){
            serverList.add(new Server(m.group(1),m.group(2),m.group(3),m.group(4)));
        }
        re = "\\s*<h4>[A-Z]*服务器地址:([^<]*)</h4>\n" +
                "\\s*<h4>端口:([^<]*)</h4>\n" +
                "\\s*<h4>密码:([^<]*)</h4>\n" +
                "\\s*<h4>加密方式:([^<]*)</h4>";

        HTML = getHTML(urlList.get(1));
        Pattern p2 = Pattern.compile(re);
        Matcher m2 = p2.matcher(HTML);
        while(m2.find()){
            serverList.add(new Server(m2.group(1),m2.group(2),m2.group(3),m2.group(4)));
        }
    }
    public static void getJson() {
        String os = System.getProperty("os.name").toLowerCase();
        initData();
        StringBuffer sb = new StringBuffer();
        for (int i = 0;i<serverList.size();i++){
            sb.append(serverList.get(i));
            if(i<serverList.size()-1){
                sb.append(",\n");
            }else{
                sb.append("\n");
            }
        }
        if(os.contains("windows")){
            StringBuffer sb1 = new StringBuffer();
            sb1.append("{\n" +
                    "\"configs\" : [\n");
            sb1.append(sb.toString());
            sb1.append("],\n" +
                    "  \"strategy\": null,\n" +
                    "  \"index\": 0,\n" +
                    "  \"global\": true,\n" +
                    "  \"enabled\": true,\n" +
                    "  \"shareOverLan\": false,\n" +
                    "  \"isDefault\": false,\n" +
                    "  \"localPort\": 1080,\n" +
                    "  \"pacUrl\": null,\n" +
                    "  \"useOnlinePac\": false,\n" +
                    "  \"availabilityStatistics\": false,\n" +
                    "  \"autoCheckUpdate\": true,\n" +
                    "  \"isVerboseLogging\": false,\n" +
                    "  \"logViewer\": {\n" +
                    "    \"fontName\": \"Consolas\",\n" +
                    "    \"fontSize\": 8.0,\n" +
                    "    \"bgColor\": \"black\",\n" +
                    "    \"textColor\": \"white\",\n" +
                    "    \"topMost\": false,\n" +
                    "    \"wrapText\": false,\n" +
                    "    \"toolbarShown\": false,\n" +
                    "    \"width\": 600,\n" +
                    "    \"height\": 400,\n" +
                    "    \"top\": 328,\n" +
                    "    \"left\": 766,\n" +
                    "    \"maximized\": true\n" +
                    "  },\n" +
                    "  \"proxy\": {\n" +
                    "    \"useProxy\": false,\n" +
                    "    \"proxyType\": 0,\n" +
                    "    \"proxyServer\": \"\",\n" +
                    "    \"proxyPort\": 0,\n" +
                    "    \"proxyTimeout\": 3\n" +
                    "  },\n" +
                    "  \"hotkey\": {\n" +
                    "    \"SwitchSystemProxy\": \"\",\n" +
                    "    \"ChangeToPac\": \"\",\n" +
                    "    \"ChangeToGlobal\": \"\",\n" +
                    "    \"SwitchAllowLan\": \"\",\n" +
                    "    \"ShowLogs\": \"\",\n" +
                    "    \"ServerMoveUp\": \"\",\n" +
                    "    \"ServerMoveDown\": \"\"\n" +
                    "  }\n" +
                    "}");
            try {
                FileWriter fw = new FileWriter("gui-config.json");
                fw.write(sb1.toString());
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(os.contains("linux")){
            try {
                FileWriter fw = new FileWriter(".config.json");
                fw.write(serverList.get(4).toString());
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("there is no solution yet!");
        }

    }
}

没搞明白当时的想法,我为啥还定义了一个 Server POJO类,代码里面并没见到调用呀。

/**
 * Created by fcy on 2017/3/6.
 */
public class Server {
    String server,server_port,password,method,remarks,auth,timeout;
    String local_port;

    @Override
    public String toString() {
        return "{" +
                "\"server\": \"" + server + "\",\n" +
                "\"server_port\": " + server_port + ",\n" +
                "\"password\": \"" + password + "\",\n" +
                "\"method\": \"" + method + "\",\n" +
                "\"remarks\": \"" + remarks + "\",\n" +
                "\"auth\": " + auth + ",\n" +
                "\"timeout\": " + timeout + ",\n" +
                "\"local_port\": "+local_port+"\n"+
                '}';
    }

    public Server(String server, String server_port, String password, String method) {
        this.server = server;
        this.server_port = server_port;
        this.password = password;
        this.method = method;
        this.remarks = "";
        this.auth = "false";
        this.timeout = "10";
        this.local_port = "5555";
    }
}

启动ss

最魔幻的事情还是发生了,与sss.bat里面的代码貌似有点冲突。

import java.io.IOException;

/**
 * Created by fcy on 2017/3/6.
 */
public class StartProxy {
    public static void winStart(){
        Runtime rt = Runtime.getRuntime();
        Process p = null;
        try {
        	p = rt.exec("cmd");
            p = rt.exec("shadowsocks.exe");
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(p.toString());
    }
    public static void linuxStart(){
        Runtime rt = Runtime.getRuntime();
        Process p = null;

        try {
            p=rt.exec("(nohup sslocal -c .config.json > .iss.log &)");
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(p.toString());
    }
    public static void start(){
        String os = System.getProperty("os.name").toLowerCase();
        if(os.contains("windows")){
            winStart();
        }else if(os.contains("linux")){
            linuxStart();
        }else{
            System.out.println("there is no solution yet!");
        }
    }
}

也许是后面加的Java代码,但是 who cares,反正它也没有什么实际价值与维护的意义,当做纪念吧~

Read more

Volcano 与 Kubernetes GPU 调度学习笔记

本笔记系统整理 Volcano 调度器、Kubernetes 调度框架、GPU Device Plugin、HAMi 等云原生 AI 调度领域的核心知识,适合用于学习、复习和工程实践参考。 目录 * 第一部分:Volcano 入门 * 1. Volcano 是什么 * 2. 安装与快速使用 * 3. 核心特性一览 * 第二部分:Volcano 整体架构 * 4. Volcano 解决的核心问题 * 5. 整体架构与数据流 * 6. 三层抽象模型 * 第三部分:Volcano 核心实现原理 * 7. Session 机制 * 8. Gang Scheduling 实现 * 9. Queue 与 DRF 公平调度

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd