curl --resolve参数的作用

之所以会有这样的操作,是因为域名一般对应的都是一个反向代理,直接请求域名,反向代理会将流量随机选一台机器打过去,而无法确保所有的机器都可用。所以直接用ip。

curl 命令中,--resolve 参数用于指定自定义的主机名解析规则。通过使用 --resolve 参数,你可以将指定的主机名解析为指定的 IP 地址,并将该解析结果应用于 curl 请求中。

具体来说,--resolve 参数的语法如下:

css 复制代码
curl --resolve <host:port:address> <URL>

其中:

  • <host:port> 是你希望自定义解析的主机名和端口号的组合。
  • <address> 是你希望将该主机名解析为的自定义 IP 地址。

通过指定 --resolve 参数,curl 将绕过标准的 DNS 解析过程,直接使用你提供的自定义 IP 地址来发送请求。这对于模拟特定的网络环境或测试特定服务器配置非常有用。

以下是一个示例:

arduino 复制代码
curl --resolve example.com:80:127.0.0.1 http://example.com

上述命令将主机名 example.com 解析为 IP 地址 127.0.0.1,然后发送 HTTP 请求到 http://example.com。在这个示例中,--resolve 参数将请求定向到本地主机,绕过了标准的 DNS 解析过程。

请注意,--resolve 参数只影响当前 curl 命令的执行,不会修改系统的实际 DNS 解析规则。它仅用于在特定情况下进行临时的主机名解析定制。

之前在网易,经常用到这个命令

curl --resolve 'brain-prd-jd.netease.im:443:xxx.xxx.xxx.xx' https://brain-prd-jd.netease.im/v1/whois/brain

即绕过DNS解析,直接将*brain-prd-jd.netease.im/v1/whois/br...

其实用--resolve参数, 和绑定host一样的效果:

因为可能是m个域名,对应n个ip(n台机器),无论是挨个curl --resolve,还是修改host,都会很麻烦,写过一个检查绑定关系的工具:

go 复制代码
package main

import (
	"context"
	"errors"
	"flag"
	"fmt"
	"net"
	"net/http"
	"strings"
	"time"
)

var (
	domain = flag.String("domain", "", "请输入域名列表,中间用英文逗号分隔")
	ip     = flag.String("ip", "", "请输入ip列表,中间用英文逗号分隔")
	whois  = flag.String("whois", "", "请输入whois地址,形如 /v1/whois/brain")
	method = flag.String("method", "GET", "HTTP 请求的方法,默认 GET")
	body   = flag.String("body", "", "HTTP 请求的 body,默认空")
)

const (
	ErrorColor = "\033[1;31m%s\033[0m" // red
	InfoColor  = "\033[1;32m%s\033[0m" // green
)

func main() {

	flag.Parse()

	domainStr := *domain
	ipStr := *ip

	checkPath := *whois

	if len(domainStr) == 0 || len(ipStr) == 0 || len(checkPath) == 0 {
		fmt.Printf(ErrorColor, "请输入域名,ip和检验地址\n")
		return
	}

	domainSli := strings.Split(domainStr, ",")

	ipSli := strings.Split(ipStr, ",")

	if len(domainSli) == 0 || len(ipSli) == 0 {
		fmt.Printf(ErrorColor, "请输入正确格式的域名和ip\n")
		return
	}

	//校验ip格式 (未校验域名格式)
	for _, v := range ipSli {
		ipItem := net.ParseIP(v)
		if ipItem == nil {
			fmt.Printf(ErrorColor, "ip格式错误\n")
			return
		}
	}

	for _, i := range domainSli {
		for _, j := range ipSli {

			if err := check(i, j, checkPath); err != nil {
				errmsg := fmt.Sprintf("域名:%s,ip:%s 错误:%#v\n", i, j, err)
				fmt.Printf(ErrorColor, errmsg)
				//return
			}
		}
	}

	fmt.Printf(InfoColor, "全部校验成功\n")

}

func check(domain, ip, checkPath string) error {

	dialer := &net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	}

	http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {

		if addr == domain+":443" {
			addr = ip + ":443"
		}
		return dialer.DialContext(ctx, network, addr)
	}

	client := http.Client{Timeout: 5 * time.Second}
	req, err := http.NewRequest(*method, domain+checkPath, strings.NewReader(*body))
	if err != nil {
		return fmt.Errorf("NewRequest error: %w", err)
	}
	resp, err := client.Do(req)

	if err != nil || resp == nil {
		return errors.New("发生错误")
	}

	if resp.StatusCode != http.StatusOK {
		return errors.New("错误码非200")
	}

	msg := fmt.Sprintf("域名:%s,ip:%s,whois:%s 请求成功\n", domain, ip, checkPath)
	fmt.Printf(InfoColor, msg)

	return nil

}

可以直接通过

go run checkbind.go -domain https://域名1,https://域名2 -ip 119.147.xxx.xx,120.147.xxx.xx -whois /v1/whois/health_check来检测

使用 CURL 的"--resolve"选项将请求固定到 IP 地址

Golang将HTTP请求发往指定的IP

Golang force http request to specific ip (similar to curl --resolve)

相关推荐
想打游戏的程序猿3 小时前
核心概念层——深入理解 Agent 是什么
后端·ai编程
woniu_maggie4 小时前
SAP Web Service日志监控:如何用SRT_UTIL快速定位接口问题
后端
一线大码4 小时前
Java 使用国密算法实现数据加密传输
java·spring boot·后端
Rust语言中文社区4 小时前
【Rust日报】用 Rust 重写的 Turso 是一个更好的 SQLite 吗?
开发语言·数据库·后端·rust·sqlite
F1FJJ5 小时前
只是想查个数据,不想装 phpMyAdmin
数据库·网络协议·容器·开源软件
在屏幕前出油6 小时前
06. FastAPI——中间件
后端·python·中间件·pycharm·fastapi
wuqingshun3141596 小时前
说一下spring的bean的作用域
java·后端·spring
F1FJJ7 小时前
Shield CLI:MySQL 插件 vs phpMyAdmin:轻量 Web 数据库管理工具对比
前端·网络·数据库·网络协议·mysql·容器
钟智强7 小时前
从2.7GB到481MB:我的Docker Compose优化实战,以及为什么不能全信AI
后端·docker
华科易迅7 小时前
Spring JDBC
java·后端·spring