为了账号安全,请及时绑定邮箱和手机立即绑定

如何查找服务器真实IP

如何查找服务器真实IP

Go
aluckdog 2022-09-26 15:12:21
如何查找运行程序的计算机或服务器的公共 IP 地址?就像程序执行时一样,它检测服务器的公共并打印例如running at 123.45.67.89
查看完整描述

2 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

简短的回答是,没有办法保证返回您的“公共”IP地址。


第一个问题是,您的公共IP地址是什么?计算机的地址(由要连接到的系统显示)可能会有所不同,具体取决于本地 Internet 服务的配置方式以及要连接到的服务:

  • 正如我在评论中提到的,在典型的家庭环境中,您的计算机没有公共IP地址。公共地址由路由器托管。

  • 如果您通过代理或VPN访问服务,则计算机的地址可能与直接连接到服务时完全不同。

  • 在具有多个接口的系统上,选择的源地址可能取决于您要连接到的地址:不同的地址可能具有不同的路由。

您可以尝试使用 http://icanhazip.com/ 等服务来尝试确定您的公共 IP。这在许多情况下是正确的,但不是所有情况下。


查看完整回答
反对 回复 2022-09-26
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

公共IP地址是一个模糊的概念,在实践中,它可能是也可能不是静态地址。你对此了解多少?它只是一个在一定时间内有效的终结点,这取决于许多因素,例如使用哪个接口发出查询。

我们可以使用主线位托伦特 dht 给我们一些指示。

Go 语言提供了由阿纳克罗利克斯编写的很酷的 dht 包

当使用谓词查询节点时,我们会收到一个数据包,其中包含对等方与我们的查询关联的远程IP地址。这在 bep10 中进行了描述。find_peers

如果UDP连接不是一个好的选择,您可以选择查询比特跟踪器,bep24中所述

考虑到对等方可能是恶意的,因此结果越多越好。

下面的程序输出与从查询的节点队列的 POV 启动查询的计算机关联的外部网络地址列表。

地址按响应数评分。

另读 https://www.bittorrent.org/beps/bep_0005.html

found 9 bootstrap peers

found 6 peers

4    [2001:861:51c5:xxx:40d1:8061:1fe0:xxx]:9090

2    81.96.42.191:9090

4同行告诉我们我们正在使用,我们可以推断这是ipv6。[2001:861:51c5:xxx:40d1:8061:1fe0:xxx]:9090

2他们告诉我们正在使用,ipv4接口。81.96.42.191:9090

package main


import (

    "encoding/json"

    "errors"

    "fmt"

    "io/ioutil"

    "log"

    "net"

    "os"

    "sort"

    "sync"

    "time"


    "github.com/anacrolix/dht"

    "github.com/anacrolix/dht/krpc"

    "github.com/anacrolix/torrent/bencode"

)


var maxTimeout = time.Second * 5


func main() {

    b, _ := ioutil.ReadFile("db.json")

    var rawAddrs []string

    json.Unmarshal(b, &rawAddrs)

    defer func() {

        if len(rawAddrs) < 1 {

            return

        }

        if len(rawAddrs) > 30 {

            rawAddrs = rawAddrs[:30]

        }

        buf, err := json.Marshal(rawAddrs)

        if err != nil {

            panic(err)

        }

        err = ioutil.WriteFile("db.json", buf, os.ModePerm)

        if err != nil {

            panic(err)

        }

        fmt.Fprintf(os.Stderr, "%v peers recorded\n", len(rawAddrs))

    }()

    bootstrap, err := parseAddrs(rawAddrs)

    if err != nil {

        bootstrap, err = globalBootstrapAddrs()

        if err != nil {

            panic(err)

        }

    }


    findPeers := []byte(`d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe`)


    local, err := net.ResolveUDPAddr("udp", "0.0.0.0:9090")

    if err != nil {

        panic(err)

    }

    ln, err := net.ListenUDP("udp", local)

    if err != nil {

        panic(err)

    }


    addrscores := map[string]int{}


    var drain drain

    defer drain.Wait()

    fmt.Fprintf(os.Stderr, "found %v bootstrap peers\n", len(bootstrap))

    res, errs := readResponses(ln, len(bootstrap), sendQuery(ln, bootstrap, findPeers))

    drain.Errors(errs)


    peers := []net.Addr{}

    for d := range res {

        if isValidAddr(d.IP.UDP()) {

            addrscores[d.IP.String()]++

            d.R.ForAllNodes(func(arg1 krpc.NodeInfo) {

                peers = append(peers, arg1.Addr.UDP())

            })

        }

    }


    if len(peers) > 0 {

        fmt.Fprintf(os.Stderr, "found %v peers\n", len(peers))

        res, errs = readResponses(ln, len(peers), sendQuery(ln, peers, findPeers))

        drain.Errors(errs)

        for d := range res {

            if isValidAddr(d.IP.UDP()) {

                addrscores[d.IP.String()]++

            }

        }

    }


    for _, peer := range peers {

        if isValidAddr(peer) {

            rawAddrs = append(rawAddrs, peer.String())

        }

    }


    addrs := make([]string, 0, len(addrscores))

    for addr := range addrscores {

        addrs = append(addrs, addr)

    }

    sort.Slice(addrs, func(i int, j int) bool {

        return addrscores[addrs[i]] > addrscores[addrs[j]]

    })


    for _, addr := range addrs {

        fmt.Printf("%-4v %v\n", addrscores[addr], addr)

    }

}


type drain struct{ sync.WaitGroup }


func (d *drain) Errors(errs <-chan error) {

    d.Add(1)

    go func() {

        defer d.Done()

        for err := range errs {

            fmt.Fprintln(os.Stderr, err)

        }

    }()

}


func parseAddrs(rawAddrs []string) (addrs []net.Addr, err error) {

    for _, s := range rawAddrs {

        host, port, err := net.SplitHostPort(s)

        if err != nil {

            panic(err)

        }

        ua, err := net.ResolveUDPAddr("udp", net.JoinHostPort(host, port))

        if err != nil {

            log.Printf("error resolving %q: %v", host, err)

            continue

        }

        addrs = append(addrs, ua)

    }

    if len(addrs) == 0 {

        err = errors.New("nothing resolved")

    }

    return

}


func globalBootstrapAddrs() (addrs []net.Addr, err error) {

    bootstrap, err := dht.GlobalBootstrapAddrs("udp")

    if err != nil {

        return nil, err

    }

    for _, b := range bootstrap {

        addrs = append(addrs, b.Raw())

    }

    return

}


func isValidAddr(addr net.Addr) bool { // so weird guys.

    return addr.String() != "<nil>" && addr.String() != ":0"

}


func sendQuery(ln *net.UDPConn, peers []net.Addr, query []byte) chan error {

    errs := make(chan error)


    for _, addr := range peers {

        go func(addr net.Addr) {

            _, err := ln.WriteTo(query, addr)

            if err != nil {

                errs <- addressedError{Op: "send", error: err, Addr: addr}

            }

        }(addr)

    }


    return errs

}


func readResponses(ln *net.UDPConn, count int, errs chan error) (<-chan krpc.Msg, <-chan error) {


    data := make(chan krpc.Msg)

    var wg sync.WaitGroup

    for i := 0; i < count; i++ {

        wg.Add(1)

        go func() {

            defer wg.Done()

            buf := make([]byte, 1000)

            ln.SetReadDeadline(time.Now().Add(maxTimeout))

            n, remoteAddr, err := ln.ReadFromUDP(buf)

            if err != nil {

                errs <- addressedError{Op: "rcv", error: err, Addr: remoteAddr}

                return

            }

            var m krpc.Msg

            err = bencode.Unmarshal(buf[:n], &m)

            if err != nil {

                errs <- addressedError{Op: "rcv", error: err, Addr: remoteAddr}

                return

            }

            data <- m

        }()

    }

    go func() {

        wg.Wait()

        close(errs)

        close(data)

    }()


    return data, errs

}


type addressedError struct {

    error

    Op   string

    Addr net.Addr

}


func (a addressedError) Error() string {

    if !isValidAddr(a.Addr) {

        return fmt.Sprintf("%-5v %v", a.Op, a.error.Error())

    }

    return fmt.Sprintf("%-5v %v: %v", a.Op, a.Addr.String(), a.error.Error())

}


查看完整回答
反对 回复 2022-09-26
  • 2 回答
  • 0 关注
  • 89 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信