skip to Main Content

I’m trying trying to redirect a tcp connection to a transparent proxy without iptables. iptables is definitely not an option. Is it possible set original destination on a socket? Here is the code I wrote in 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: %sn", 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: %sn", 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: %sn", err.Error())
        return
    }
    defer syscall.Close(sock)

}

I use IPv6Mreq because it is the only struct type with 16 bytes and also it is the only option when getting SO_ORIGINAL_DST (source). The above code returns

Error while setting original destination: protocol not available

Is only iptables allowed to set original destination or am I doing something wrong?

Edit: I’m using debian.

2

Answers


  1. SO_ORIGINAL_DST is only used to get the original destination IP address of a redirected socket. The redirection itself must be done with iptables.

    Login or Signup to reply.
  2. Nope, it is only use to get original address. e.g.

    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
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search