是否可以设置套接字的SO_ORIGINAL_DST值?

问题描述 投票:0回答:2

我正在尝试将tcp连接重定向到不带iptables的透明代理。 iptables绝对不是一个选择。是否可以在套接字上设置原始目标?这是我在go中编写的代码:

package main

import (
    "fmt"
    "syscall"
)

const (
    SO_ORIGINAL_DST = 80
)

func main() {
    proto := ((syscall.IPPROTO_IP << 8) & 0xff00) | ((syscall.IPPROTO_IP >> 8) & 0xff)
    sock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, proto)
    if err != nil {
        fmt.Printf("Error while creating socket: %s\n", err.Error())
        return
    }

    mreq := syscall.IPv6Mreq{
        Multiaddr: [16]byte{2, 0, 1, 187, 104, 28, 28, 88, 0, 0, 0, 0, 0, 0, 0, 0},
        Interface: 0,
    }

    err = syscall.SetsockoptIPv6Mreq(sock, syscall.SOL_IP, SO_ORIGINAL_DST, &mreq)
    if err != nil {
        fmt.Printf("Error while setting original destination: %s\n", err.Error())
        return
    }

    sa := syscall.SockaddrInet4{
        Port: 8080,
        Addr: [4]byte{127, 0, 0, 1},
    }
    err = syscall.Connect(sock, &sa)
    if err != nil {
        fmt.Printf("Error while connecting to target: %s\n", err.Error())
        return
    }
    defer syscall.Close(sock)

}

我使用IPv6Mreq,因为它是具有16个字节的唯一结构类型,并且它也是获得SO_ORIGINAL_DST(source)时的唯一选项。上面的代码返回

Error while setting original destination: protocol not available

仅允许iptables设置原始目标,还是我做错了什么?

编辑:我正在使用debian。

sockets go networking iptables
2个回答
1
投票

SO_ORIGINAL_DST仅用于获取重定向套接字的原始目标IP地址。重定向本身必须使用iptables完成。


0
投票

不是,它仅用于获取原始地址。例如

f, err := conn.(*net.TCPConn).File()
if err != nil {
    return "", err
}
defer f.Close()
addr, err := syscall.GetsockoptIPv6Mreq(int(f.Fd()), syscall.IPPROTO_IP, SO_ORIGINAL_DST)
if err != nil {
    return "", err
}
© www.soinside.com 2019 - 2024. All rights reserved.