是否可以设置套接字的 SO_ORIGINAL_DST 值?
Is it possible to set SO_ORIGINAL_DST value of a socket?
我正在尝试将 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) 时的唯一选项。上面的代码returns
Error while setting original destination: protocol not available
是否只允许 iptables 设置原始目的地,还是我做错了什么?
编辑:我正在使用 debian。
SO_ORIGINAL_DST 仅用于获取重定向套接字的原始目标 IP 地址。重定向本身必须使用 iptables 完成。
不,它仅用于获取原始地址。例如
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
}
我正在尝试将 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) 时的唯一选项。上面的代码returns
Error while setting original destination: protocol not available
是否只允许 iptables 设置原始目的地,还是我做错了什么?
编辑:我正在使用 debian。
SO_ORIGINAL_DST 仅用于获取重定向套接字的原始目标 IP 地址。重定向本身必须使用 iptables 完成。
不,它仅用于获取原始地址。例如
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
}