K7

K7Blog

须知少年凌云志 曾许人间第一流.
proton
telegram

前回の続き:CloudflareのIPをスキャンしてウェブサイトやノードを加速させる 自分のCDN加速を無料で作成

前言:#

この記事を読む前にこちらを確認してください:Cloudflare の IP をスキャンしてウェブサイトやノードを加速し、自分の CDN を無料で作成する

この記事は、後続の内容とよくある質問への回答および解決策をまとめたものです。ノードを加速したいだけの場合は、以下のビデオを直接ご覧ください:

もしウェブサイトを加速したいが、何らかの問題に直面して加速に成功できない、速度が遅い、ウェブサイトにアクセスできないなどの問題がある場合は、引き続きお読みください。

可能性のある問題 + 解決策:#

まず、Cloudflare の反代 IP をいくつか見つけ、前述の文章のチュートリアルを通じてこれらの IP にアクセスした場合、証明書エラーが表示されてアクセスできないことがあります。この場合、証明書エラーを無視すると他の人のウェブサイトにアクセスしてしまいます。

この IP の 443 ポートは Cloudflare に反代されていないことを示しています。通常、443 ポートが正常に反代されている証明書の内容のドメインは:cloudflare-dns.com です。

IP 検出:#

この問題を発見したので、AI に頼んで正常な 443 ポートのノード IP をフィルタリングする go コードを書いてもらいました。以下のコードをコピーして 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://k7blog.com にアクセスできなくなり、https に 301 リダイレクトできなくなります。これには、80 と 443 の両方が使用可能なものを見つけるために少し手間がかかります。

IP 速度テスト:#

使用する場合は、速度が不安定で随時使用できなくなることを我慢する必要があります。なぜなら、他の人が加速ノードを使って 4k や 8k の動画を再生したり、ダウンロードタスクを実行したりするからです。また、いくつかのノード自体が非常に遅い場合、使用すると逆に加速されることになります。そこで、AI に頼んで jpg 速度テストと zip 速度テストを行う go コードを書きました。

Snipaste_2024-04-30_14-42-17

jpg 速度テスト(Windows PC を使用するか、対応する hosts ディレクトリを自分で変更してください):

img.a8tool.comhttps://img.k7blog.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.k7blog.com", ip) {
			// ローカルhostファイルを変更
			if err := modifyHosts("img.k7blog.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.k7blog.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.k7blog.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 PC を使用するか、対応する hosts ディレクトリを自分で変更してください):

img.a8tool.comhttps://img.k7blog.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.k7blog.com", ip) {
			// ローカルhostファイルを変更
			if err := modifyHosts("img.k7blog.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.k7blog.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.k7blog.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 を解析し、その解析に加速するドメインを追加すれば大丈夫です。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。