A8DOG

A8DOG

随便写写,记录折腾过程!
telegram

书接上回:扫描反代Cloudflare的IP 给网站或节点加速 免费制作自己的CDN加速

前言:#

看此文章前先看完:扫描反代 Cloudflare 的 IP 给网站或节点加速 免费制作自己的 CDN 加速

本文章算一个后续和常见问题的解答和解决方法,如果你是想加速节点而已 请直接看下面的视频:

如果你是想加速网站,并且遇到了一些问题导致无法加速成功,速度慢,无法访问网站等问题,请继续往下看。

可能会出现的问题 + 解决办法:#

首先你找到了一些反代 Cloudflare 的 IP,并且通过前面的文章中教程解析到了这些 IP 上,你去访问可能会提示证书错误 无法访问的情况,这个情况下忽略证书错误会访问到他人的网站中。

代表这个 IP 的 443 端口并没有反代到 Cloudflare 上,一般 443 端口正常反代证书内容域名会是:cloudflare-dns.com

IP 检测:#

那么我发现了这个问题,找 AI 写了一个 go 代码,可以筛选出正常 443 端口的节点 IP,复制下面的代码创建一个 go 文件,再创建好一个 ip.txt 和 443.txt. 在 ip.txt 写入你需要检查的 IP 节点就好了,正常的 IP 会写入到 443.txt 中。

package main

import (
	"bufio"
	"crypto/tls"
	"fmt"
	"net"
	"os"
	"strings"
	"sync"
	"time"
)

func main() {
	// 打开 ip.txt 文件
	file, err := os.Open("ip.txt")
	if err != nil {
		fmt.Println("无法打开文件:", err)
		return
	}
	defer file.Close()

	// 创建一个文件用于写入合格的 IP 地址
	outFile, err := os.OpenFile("443.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Println("无法创建文件:", err)
		return
	}
	defer outFile.Close()

	// 创建一个 bufio.Scanner 用于逐行读取文件内容
	scanner := bufio.NewScanner(file)
	tasks := make(chan string, 5) // 并发任务通道
	results := make(chan string)  // 结果通道
	var wg sync.WaitGroup         // 等待所有任务完成

	// 开启并发任务处理
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go handleTask(tasks, results, &wg)
	}

	// 逐行读取文件内容并发送到并发任务通道
	for scanner.Scan() {
		ip := scanner.Text()
		tasks <- ip
	}

	// 关闭并发任务通道,等待所有任务完成
	close(tasks)
	go func() {
		wg.Wait()
		close(results)
	}()

	// 从结果通道中读取合格的 IP 地址并写入到文件中
	for ip := range results {
		outFile.WriteString(ip + "\n")
	}

	if err := scanner.Err(); err != nil {
		fmt.Println("读取文件时发生错误:", err)
		return
	}

	fmt.Println("处理完毕,合格的 IP 已追加到 443.txt 文件中")
}

// 函数用于处理并发任务
func handleTask(tasks <-chan string, results chan<- string, wg *sync.WaitGroup) {
	defer wg.Done()
	for ip := range tasks {
		// 检查 IP 的 443 端口是否可访问,超时设置为 5 秒
		if isPortOpenWithTimeout(ip, "443", 5*time.Second) {
			// 如果 443 端口可访问,继续检查证书是否来自 cloudflare-dns.com
			if checkCertificate(ip, "cloudflare-dns.com") {
				// 如果证书来自 cloudflare-dns.com,写入到结果通道中
				fmt.Println(ip, "合格")
				results <- ip
			} else {
				fmt.Println(ip, "不合格,证书不是来自 cloudflare-dns.com")
			}
		} else {
			fmt.Println(ip, "不合格,443端口不可访问或超时")
		}
	}
}

// 函数用于检查指定 IP 和端口是否可访问,并设置超时时间
func isPortOpenWithTimeout(ip, port string, timeout time.Duration) bool {
	conn, err := net.DialTimeout("tcp", ip+":"+port, timeout)
	if err != nil {
		return false
	}
	defer conn.Close()
	return true
}

// 函数用于检查指定 IP 的证书是否来自指定的域名
func checkCertificate(ip, domain string) bool {
	config := tls.Config{ServerName: domain}
	conn, err := tls.Dial("tcp", ip+":443", &config)
	if err != nil {
		return false
	}
	defer conn.Close()

	// 获取证书
	certs := conn.ConnectionState().PeerCertificates
	if len(certs) < 1 {
		return false
	}

	// 检查证书是否匹配指定的域名
	for _, cert := range certs {
		if strings.Contains(cert.Subject.CommonName, domain) || cert.VerifyHostname(domain) == nil {
			return true
		}
	}
	return false
}

还有一个问题就是有些 IP 的 80 端口可以访问,443 端口也可以访问,但是 443 端口被防火墙给墙了,然后就是 80 无法使用 443 端口可以使用,使用这样的 IP 加速后会导致http://a8dog.com 无法访问,也不能 301 跳转到 https,这个大家需要花点功夫去找 80 和 443 都可用的。

IP 测速:#

如果你要用,那么就需要忍受速度不稳定和随时不可用的情况,因为也会有人拿来加速节点 动不动去跑一些 4k8k 视频或者下载任务。而且有些节点本身就很慢这个时候我们使用就会是反向加速。于是拿出 AI 写了一个 go 代码,分为 jpg 测速和 zip 测速。

Snipaste_2024-04-30_14-42-17

jpg 测速(请使用 Windows 电脑,或者你自己修改对应的 hosts 目录):

img.a8tool.comhttps://img.a8dog.com/i/2024/04/30/loux3b.jpg 修改成你自己的,jpg 文件建议有个 5M 或以上,到 go 程序同目录下创建一个 dns.txt 文件,写入测速节点 IP。

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"time"
)

// backupHostsFilePath 存储 hosts 文件的备份路径
var backupHostsFilePath = "C:\\Windows\\System32\\drivers\\etc\\hosts.backup"

func main() {
	// 打开 DNS 文件
	dnsFile, err := os.Open("dns.txt")
	if err != nil {
		log.Fatalf("无法打开 DNS 文件:%v", err)
	}
	defer dnsFile.Close()

	// 读取 DNS 文件中的 IP
	ips, err := ioutil.ReadAll(dnsFile)
	if err != nil {
		log.Fatalf("无法读取 DNS 文件:%v", err)
	}

	// 创建日志文件
	logFile, err := os.OpenFile("dns.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("无法创建日志文件:%v", err)
	}
	defer logFile.Close()

	// 备份原 hosts 文件
	err = backupHostsFile()
	if err != nil {
		log.Fatalf("备份 hosts 文件失败:%v", err)
	}

	// 以行为单位遍历 IP
	ipList := strings.Split(string(ips), "\n")
	for _, ip := range ipList {
		ip = strings.TrimSpace(ip)
		if ip == "" {
			continue
		}

		// 检查当前IP是否已经是目标IP
		if !checkHostIP("img.a8dog.com", ip) {
			// 修改本地 host 文件
			if err := modifyHosts("img.a8dog.com", ip); err != nil {
				log.Printf("修改 host 文件失败:%v", err)
				continue
			}

			// 刷新 DNS 缓存
			err := flushDNSCache()
			if err != nil {
				log.Printf("刷新 DNS 缓存失败:%v", err)
			}

			// 等待一段时间,确保 host 文件生效
			time.Sleep(5 * time.Second)

			// 再次检查当前IP是否已经是目标IP
			if !checkHostIP("img.a8dog.com", ip) {
				log.Printf("域名未指向目标 IP:%s", ip)
				continue
			}
		}

		// 删除旧的图片文件
		err := deleteFile("downloaded_image.jpg")
		if err != nil {
			log.Printf("删除旧的图片文件失败:%v", err)
		}

		// 下载图片
		start := time.Now()
		_, err = downloadFile("https://img.a8dog.com/i/2024/04/30/loux3b.jpg", "downloaded_image.jpg")
		if err != nil {
			log.Printf("下载图片失败:%v", err)
			continue
		}
		duration := time.Since(start)

		// 记录下载时间和下载速度
		speed := float64(fileSize("downloaded_image.jpg")) / duration.Seconds() / 1024 // KB/s

		// 打印记录信息并写入日志文件
		logMsg := fmt.Sprintf("IP: %s, 下载时间: %v, 下载速度: %.2f KB/s", ip, duration, speed)
		fmt.Println(logMsg)
		if _, err := logFile.WriteString(logMsg + "\n"); err != nil {
			log.Printf("写入日志文件失败:%v", err)
		}

		// 恢复原 hosts 文件
		err = restoreHostsFile()
		if err != nil {
			log.Fatalf("恢复 hosts 文件失败:%v", err)
		}
	}
}

// 修改本地 hosts 文件
func modifyHosts(hostname, ip string) error {
	hostsFilePath := "C:\\Windows\\System32\\drivers\\etc\\hosts"
	hostsFile, err := os.OpenFile(hostsFilePath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer hostsFile.Close()

	_, err = hostsFile.WriteString(fmt.Sprintf("%s %s\n", ip, hostname))
	if err != nil {
		return err
	}

	return nil
}

// 下载文件
func downloadFile(url, filename string) (int64, error) {
	resp, err := http.Get(url)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	file, err := os.Create(filename)
	if err != nil {
		return 0, err
	}
	defer file.Close()

	size, err := io.Copy(file, resp.Body)
	if err != nil {
		return 0, err
	}

	return size, nil
}

// 获取文件大小
func fileSize(filename string) int64 {
	info, err := os.Stat(filename)
	if err != nil {
		return 0
	}
	return info.Size()
}

// 备份 hosts 文件
func backupHostsFile() error {
	src, err := os.Open("C:\\Windows\\System32\\drivers\\etc\\hosts")
	if err != nil {
		return err
	}
	defer src.Close()

	dst, err := os.Create(backupHostsFilePath)
	if err != nil {
		return err
	}
	defer dst.Close()

	_, err = io.Copy(dst, src)
	if err != nil {
		return err
	}

	return nil
}

// 恢复 hosts 文件
func restoreHostsFile() error {
	src, err := os.Open(backupHostsFilePath)
	if err != nil {
		return err
	}
	defer src.Close()

	dst, err := os.Create("C:\\Windows\\System32\\drivers\\etc\\hosts")
	if err != nil {
		return err
	}
	defer dst.Close()

	_, err = io.Copy(dst, src)
	if err != nil {
		return err
	}

	return nil
}

// 刷新 DNS 缓存
func flushDNSCache() error {
	cmd := exec.Command("ipconfig", "/flushdns")
	err := cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

// 删除文件
func deleteFile(filename string) error {
	err := os.Remove(filename)
	if err != nil {
		return err
	}
	return nil
}

// 检查域名是否指向目标 IP
func checkHostIP(hostname, expectedIP string) bool {
	addrs, err := net.LookupIP(hostname)
	if err != nil {
		log.Printf("无法解析域名:%s", err)
		return false
	}
	for _, addr := range addrs {
		if addr.String() == expectedIP {
			return true
		}
	}
	return false
}

zip 测速(请使用 Windows 电脑,或者你自己修改对应的 hosts 目录):

img.a8tool.comhttps://img.a8dog.com/i/2024i.zip 修改成你自己的,zip 文件建议有个 10M 或以上,到 go 程序同目录下创建一个 dns.txt 文件,写入测速节点 IP。

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"time"
)

// backupHostsFilePath 存储 hosts 文件的备份路径
var backupHostsFilePath = "C:\\Windows\\System32\\drivers\\etc\\hosts.backup"

func main() {
	// 打开 DNS 文件
	dnsFile, err := os.Open("dns.txt")
	if err != nil {
		log.Fatalf("无法打开 DNS 文件:%v", err)
	}
	defer dnsFile.Close()

	// 读取 DNS 文件中的 IP
	ips, err := ioutil.ReadAll(dnsFile)
	if err != nil {
		log.Fatalf("无法读取 DNS 文件:%v", err)
	}

	// 创建日志文件
	logFile, err := os.OpenFile("dns.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("无法创建日志文件:%v", err)
	}
	defer logFile.Close()

	// 备份原 hosts 文件
	err = backupHostsFile()
	if err != nil {
		log.Fatalf("备份 hosts 文件失败:%v", err)
	}

	// 以行为单位遍历 IP
	ipList := strings.Split(string(ips), "\n")
	for _, ip := range ipList {
		ip = strings.TrimSpace(ip)
		if ip == "" {
			continue
		}

		// 检查当前IP是否已经是目标IP
		if !checkHostIP("img.a8dog.com", ip) {
			// 修改本地 host 文件
			if err := modifyHosts("img.a8dog.com", ip); err != nil {
				log.Printf("修改 host 文件失败:%v", err)
				continue
			}

			// 刷新 DNS 缓存
			err := flushDNSCache()
			if err != nil {
				log.Printf("刷新 DNS 缓存失败:%v", err)
			}

			// 等待一段时间,确保 host 文件生效
			time.Sleep(5 * time.Second)

			// 再次检查当前IP是否已经是目标IP
			if !checkHostIP("img.a8dog.com", ip) {
				log.Printf("域名未指向目标 IP:%s", ip)
				continue
			}
		}

		// 删除旧的zip文件
		err := deleteFile("downloaded_file.zip")
		if err != nil {
			log.Printf("删除旧的zip文件失败:%v", err)
		}

		// 下载zip文件
		start := time.Now()
		size, err := downloadFile("https://img.a8dog.com/i/2024i.zip", "downloaded_file.zip")
		if err != nil {
			log.Printf("下载zip文件失败:%v", err)
			continue
		}
		duration := time.Since(start)

		// 计算下载速度
		speed := float64(size) / duration.Seconds() / 1024 // KB/s

		// 打印记录信息并写入日志文件
		logMsg := fmt.Sprintf("IP: %s, 下载时间: %v, 下载速度: %.2f KB/s", ip, duration, speed)
		fmt.Println(logMsg)
		if _, err := logFile.WriteString(logMsg + "\n"); err != nil {
			log.Printf("写入日志文件失败:%v", err)
		}

		// 恢复原 hosts 文件
		err = restoreHostsFile()
		if err != nil {
			log.Fatalf("恢复 hosts 文件失败:%v", err)
		}
	}
}

// 修改本地 hosts 文件
func modifyHosts(hostname, ip string) error {
	hostsFilePath := "C:\\Windows\\System32\\drivers\\etc\\hosts"
	hostsFile, err := os.OpenFile(hostsFilePath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer hostsFile.Close()

	_, err = hostsFile.WriteString(fmt.Sprintf("%s %s\n", ip, hostname))
	if err != nil {
		return err
	}

	return nil
}

// 下载文件
func downloadFile(url, filename string) (int64, error) {
	resp, err := http.Get(url)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	file, err := os.Create(filename)
	if err != nil {
		return 0, err
	}
	defer file.Close()

	size, err := io.Copy(file, resp.Body)
	if err != nil {
		return 0, err
	}

	return size, nil
}

// 备份 hosts 文件
func backupHostsFile() error {
	src, err := os.Open("C:\\Windows\\System32\\drivers\\etc\\hosts")
	if err != nil {
		return err
	}
	defer src.Close()

	dst, err := os.Create(backupHostsFilePath)
	if err != nil {
		return err
	}
	defer dst.Close()

	_, err = io.Copy(dst, src)
	if err != nil {
		return err
	}

	return nil
}

// 恢复 hosts 文件
func restoreHostsFile() error {
	src, err := os.Open(backupHostsFilePath)
	if err != nil {
		return err
	}
	defer src.Close()

	dst, err := os.Create("C:\\Windows\\System32\\drivers\\etc\\hosts")
	if err != nil {
		return err
	}
	defer dst.Close()

	_, err = io.Copy(dst, src)
	if err != nil {
		return err
	}

	return nil
}

// 刷新 DNS 缓存
func flushDNSCache() error {
	cmd := exec.Command("ipconfig", "/flushdns")
	err := cmd.Run()
	if err != nil {
		return err
	}
	return nil
}

// 删除文件
func deleteFile(filename string) error {
	err := os.Remove(filename)
	if err != nil {
		return err
	}
	return nil
}

// 检查域名是否指向目标 IP
func checkHostIP(hostname, expectedIP string) bool {
	addrs, err := net.LookupIP(hostname)
	if err != nil {
		log.Printf("无法解析域名:%s", err)
		return false
	}
	for _, addr := range addrs {
		if addr.String() == expectedIP {
			return true
		}
	}
	return false
}

当然你不修改代码使用也是可以的,也能测试出一个基本的速度,但是还是修改成你自己的才能提现出实际的速度,建议使用国内网络不开启代理测试 毕竟你需要加速肯定是要加速大陆,并且这个样子你还能知道那些在大陆不可用。

后续我有时间,我会找 AI 或者看其他解决办法 做一个故障转移的办法 如部分节点不可用直接删除解析,最后提醒大家一个点,就是你加速的域名不要直接解析在节点 IP 上,因为你变动了解析那么你就要重新去验证主机名 你直接添加一个新的解析 这个解析只解析节点 IP,然后把加速的域名添加到这个解析上就好了。

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.