FAQ
Hi,

I'm looking for a way to log outgoing connections (using iptables) straight into my Go program.


iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

The iptables man page says that it'll use a default netlink group of 1, which sounds ok, and Golang appears to have some supporting netlink functions (including parsing) in the syscall pkg. However, I'm having problems getting started, as I don't really know what I'm doing. Thus, unsurprisingly, capturing is not working.

func NetLinkListener() {
     fmt.Println("***** Starting NetLink")
     s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last parameter is netlink group???
     if e != nil {
         fmt.Println("****** NetLink Error 1:", e)
         return
     }
     defer syscall.Close(s)
     buffer := make([]byte, 2000)
     for {
         n, err := syscall.Read(s, buffer)
         if err != nil {
             fmt.Println("***** NetLink Error 2:", err)
             break
         }
         fmt.Println("NetLink:", buffer[:n]) // Output captured packet
     }
}


The socket opens, I presume as no errors are generated, but nothing is printed.


If anyone could point me in the right direction, it would be greatly appreciated.


Many thanks.

--

Search Discussions

  • Scott Lawrence at Dec 24, 2012 at 3:37 am

    On Sun, 23 Dec 2012, krolaw wrote:

    Hi,

    I'm looking for a way to log outgoing connections (using iptables) straight into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1, which sounds ok, and Golang appears to have some supporting netlink functions (including parsing) in the syscall pkg. However, I'm having problems getting started, as I don't really know what I'm doing. Thus, unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last parameter is netlink group???
    if e != nil {
    fmt.Println("****** NetLink Error 1:", e)
    return
    }
    defer syscall.Close(s)
    buffer := make([]byte, 2000)
    for {
    n, err := syscall.Read(s, buffer)
    if err != nil {
    fmt.Println("***** NetLink Error 2:", err)
    break
    }
    fmt.Println("NetLink:", buffer[:n]) // Output captured packet
    }
    }


    The socket opens, I presume as no errors are generated, but nothing is printed.


    If anyone could point me in the right direction, it would be greatly appreciated.
    I'm not sure I know what I'm doing any better than you, but my guess would be
    that it's the iptables config, not the go program, causing the trouble. Do
    other programs listening for ulog stuff get results? (ulogd, maybe?) I'm
    thinking `-t mangle` might be the wrong place for this. Try using the OUTPUT
    chain of the filter table (default).

    (Maybe. My luck with iptables recently has been poor.)

    --
    Scott Lawrence

    go version go1.0.3
    Linux baidar 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012 x86_64 GNU/Linux

    --
  • Scott Lawrence at Dec 24, 2012 at 3:40 am

    On Sun, 23 Dec 2012, Scott Lawrence wrote:
    On Sun, 23 Dec 2012, krolaw wrote:



    Hi,

    I'm looking for a way to log outgoing connections (using iptables) straight
    into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1,
    which sounds ok, and Golang appears to have some supporting netlink
    functions (including parsing) in the syscall pkg. However, I'm having
    problems getting started, as I don't really know what I'm doing. Thus,
    unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last
    parameter is netlink group???
    if e != nil {
    fmt.Println("****** NetLink Error 1:", e)
    return
    }
    defer syscall.Close(s)
    buffer := make([]byte, 2000)
    for {
    n, err := syscall.Read(s, buffer)
    if err != nil {
    fmt.Println("***** NetLink Error 2:", err)
    break
    }
    fmt.Println("NetLink:", buffer[:n]) // Output captured packet
    }
    }


    The socket opens, I presume as no errors are generated, but nothing is
    printed.


    If anyone could point me in the right direction, it would be greatly
    appreciated.
    I'm not sure I know what I'm doing any better than you, but my guess would be
    that it's the iptables config, not the go program, causing the trouble. Do
    other programs listening for ulog stuff get results? (ulogd, maybe?) I'm
    thinking `-t mangle` might be the wrong place for this. Try using the OUTPUT
    chain of the filter table (default).
    Ah. That should be INPUT, I guess. You get the point.
    (Maybe. My luck with iptables recently has been poor.)

    --
    Scott Lawrence

    go version go1.0.3
    Linux baidar 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012 x86_64
    GNU/Linux
    --
    Scott Lawrence

    go version go1.0.3
    Linux baidar 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012 x86_64 GNU/Linux

    --
  • Krolaw at Dec 24, 2012 at 9:57 am
    Found that someone had written a golang Netlink library:
    https://github.com/abneptis/GoNetlink/

    Which I will be reading through. Looks like I need to change:
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1)
    to
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, 1)

    It's still possible, there's an error in the firewall. I'll post back once
    I have it working if I needed to make any other changes.

    Cheers.
    On Monday, 24 December 2012 16:40:42 UTC+13, Scott Lawrence wrote:
    On Sun, 23 Dec 2012, Scott Lawrence wrote:
    On Sun, 23 Dec 2012, krolaw wrote:



    Hi,

    I'm looking for a way to log outgoing connections (using iptables)
    straight
    into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1,
    which sounds ok, and Golang appears to have some supporting netlink
    functions (including parsing) in the syscall pkg. However, I'm having
    problems getting started, as I don't really know what I'm doing. Thus,
    unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) //
    Last
    parameter is netlink group???
    if e != nil {
    fmt.Println("****** NetLink Error 1:", e)
    return
    }
    defer syscall.Close(s)
    buffer := make([]byte, 2000)
    for {
    n, err := syscall.Read(s, buffer)
    if err != nil {
    fmt.Println("***** NetLink Error 2:", err)
    break
    }
    fmt.Println("NetLink:", buffer[:n]) // Output captured packet
    }
    }


    The socket opens, I presume as no errors are generated, but nothing is
    printed.


    If anyone could point me in the right direction, it would be greatly
    appreciated.
    I'm not sure I know what I'm doing any better than you, but my guess would be
    that it's the iptables config, not the go program, causing the trouble. Do
    other programs listening for ulog stuff get results? (ulogd, maybe?) I'm
    thinking `-t mangle` might be the wrong place for this. Try using the OUTPUT
    chain of the filter table (default).
    Ah. That should be INPUT, I guess. You get the point.
    (Maybe. My luck with iptables recently has been poor.)

    --
    Scott Lawrence

    go version go1.0.3
    Linux baidar 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012 x86_64
    GNU/Linux
    --
    Scott Lawrence

    go version go1.0.3
    Linux baidar 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012
    x86_64 GNU/Linux
    --
  • Krolaw at Dec 24, 2012 at 9:47 am
    Thanks Scott, but this is for a Internet management appliance, which I am
    rewriting in Go, from what I created in Lua 18 months ago on OpenWRT. I
    believe the mangle PREROUTING table is the best place for the ULOG rule as
    I want the source and destination details before the DNAT, SNAT and
    REDIRECTs get involved. Plus, it worked fine in Lua that way using LOG and
    logread. Admittedly, I haven't played with ulogd (yet) as I was trying to
    bypass it altogether.

    In any case, the code I put together compiles, but I don't know what I'm
    doing. It's missing some key information; such as how do I specify the
    NetLink group that I'm trying to connect to? I'm pretty sure the code is
    hanging on the Syscall.Read as wherever it has connected, there's no data
    coming in.

    Cheers.
    On Monday, 24 December 2012 16:37:47 UTC+13, Scott Lawrence wrote:
    On Sun, 23 Dec 2012, krolaw wrote:



    Hi,

    I'm looking for a way to log outgoing connections (using iptables)
    straight into my Go program.

    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1,
    which sounds ok, and Golang appears to have some supporting netlink
    functions (including parsing) in the syscall pkg. However, I'm having
    problems getting started, as I don't really know what I'm doing. Thus,
    unsurprisingly, capturing is not working.
    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) //
    Last parameter is netlink group???
    if e != nil {
    fmt.Println("****** NetLink Error 1:", e)
    return
    }
    defer syscall.Close(s)
    buffer := make([]byte, 2000)
    for {
    n, err := syscall.Read(s, buffer)
    if err != nil {
    fmt.Println("***** NetLink Error 2:", err)
    break
    }
    fmt.Println("NetLink:", buffer[:n]) // Output captured packet
    }
    }


    The socket opens, I presume as no errors are generated, but nothing is printed.

    If anyone could point me in the right direction, it would be greatly
    appreciated.

    I'm not sure I know what I'm doing any better than you, but my guess would
    be
    that it's the iptables config, not the go program, causing the trouble. Do
    other programs listening for ulog stuff get results? (ulogd, maybe?) I'm
    thinking `-t mangle` might be the wrong place for this. Try using the
    OUTPUT
    chain of the filter table (default).

    (Maybe. My luck with iptables recently has been poor.)

    --
    Scott Lawrence

    go version go1.0.3
    Linux baidar 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012
    x86_64 GNU/Linux
    --
  • Minux at Dec 24, 2012 at 10:10 am

    On Mon, Dec 24, 2012 at 11:23 AM, krolaw wrote:

    Hi,

    I'm looking for a way to log outgoing connections (using iptables) straight into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1, which sounds ok, and Golang appears to have some supporting netlink functions (including parsing) in the syscall pkg. However, I'm having problems getting started, as I don't really know what I'm doing. Thus, unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last parameter is netlink group???

    i believe the 3rd parameter should be NETLINK_NETFILTER (12 according to
    <linux/netlink.h>, and
    unfortunately, 1 is NETLINK_UNUSED).
    the netlink group is not related to the protocol parameter.

    I suggest you read socket(2) and netlink(7) and perhaps source code of
    libmnl and ulogd.

    --
  • Krolaw at Dec 24, 2012 at 10:31 am
    Thanks minux,

    Turns out I am probably doing it all wrong. I don't want to dial (at least
    I think I don't), I want to bind a netlink socket to receive the multicast
    messages. Have also discovered that syscall.SOCK_RAW
    and syscall.SOCK_DGRAM are interchangeable as netlink does not distinguish
    the two.

    I'll do some more reading and I'll hopefully post a solution sometime after
    Christmas.

    Cheers.
    On Monday, 24 December 2012 23:10:11 UTC+13, minux wrote:


    On Mon, Dec 24, 2012 at 11:23 AM, krolaw <kro...@gmail.com <javascript:>>wrote:
    Hi,

    I'm looking for a way to log outgoing connections (using iptables) straight into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1, which sounds ok, and Golang appears to have some supporting netlink functions (including parsing) in the syscall pkg. However, I'm having problems getting started, as I don't really know what I'm doing. Thus, unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last parameter is netlink group???

    i believe the 3rd parameter should be NETLINK_NETFILTER (12 according to
    <linux/netlink.h>, and
    unfortunately, 1 is NETLINK_UNUSED).
    the netlink group is not related to the protocol parameter.

    I suggest you read socket(2) and netlink(7) and perhaps source code of
    libmnl and ulogd.
    --
  • Dmitry Fedorov at Jan 10, 2015 at 12:00 pm
    Hi,

    there are a few mistakes in your code:
    1)

    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1)

    your belief was right, the last parameter is a netlink group

    checkout linux/netlink.h for valid group number.

    probably your looking for NETLINK_NFLOG or NETLINK_NETFILTER


    2) you cant just start listening netlink socket to get messages.

    first you will need to send a request to kernel.


    here is an example of how to receive chain list from netfilter


         fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
         if err != nil {
             fmt.Println(err)
         }
         var lsa syscall.SockaddrNetlink
         lsa.Family = syscall.AF_NETLINK

         if err := syscall.Bind(fd, &lsa); err != nil {
             syscall.Close(fd)
             fmt.Println(err)
         }

         defer syscall.Close(fd)
         b := make([]byte, 20)
         native.PutUint32(b[0:4], uint32(20)) // length
         native.PutUint16(b[4:6], uint16(NFT_MSG_GETCHAIN)) // type

         native.PutUint16(b[6:8], syscall.NLM_F_REQUEST|syscall.NLM_F_DUMP) //flags
         native.PutUint32(b[8:12], uint32(1)) // seq
         native.PutUint32(b[12:16], uint32(0)) // pid
         b[16] = NFPROTO_IPV4 // nft family
         b[17] = NFNETLINK_V0 // nft version
         native.PutUint16(b[18:20], uint16(0)) // res_id

         _, err = syscall.Getsockname(fd)
         if err != nil {
             fmt.Println(err)
         }

         if err := syscall.Sendto(fd, b, 0, &lsa); err != nil {
             fmt.Println(err)
         }


      понедельник, 24 декабря 2012 г., 13:31:43 UTC+3 пользователь krolaw
    написал:
    Thanks minux,

    Turns out I am probably doing it all wrong. I don't want to dial (at
    least I think I don't), I want to bind a netlink socket to receive the
    multicast messages. Have also discovered that syscall.SOCK_RAW
    and syscall.SOCK_DGRAM are interchangeable as netlink does not distinguish
    the two.

    I'll do some more reading and I'll hopefully post a solution sometime
    after Christmas.

    Cheers.
    On Monday, 24 December 2012 23:10:11 UTC+13, minux wrote:

    On Mon, Dec 24, 2012 at 11:23 AM, krolaw wrote:

    Hi,

    I'm looking for a way to log outgoing connections (using iptables) straight into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1, which sounds ok, and Golang appears to have some supporting netlink functions (including parsing) in the syscall pkg. However, I'm having problems getting started, as I don't really know what I'm doing. Thus, unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last parameter is netlink group???

    i believe the 3rd parameter should be NETLINK_NETFILTER (12 according to
    <linux/netlink.h>, and
    unfortunately, 1 is NETLINK_UNUSED).
    the netlink group is not related to the protocol parameter.

    I suggest you read socket(2) and netlink(7) and perhaps source code of
    libmnl and ulogd.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Richard Warburton at Jan 10, 2015 at 8:39 pm
    Hi Dmitry,

    This is what has been working for me, guess I should have posted a solution:

    s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW,
    syscall.NETLINK_NFLOG)
    // NFLOG = iptables ULOG
    if err != nil {
    fmt.Println("****** NetLink Error 1:", err)
    }
    if err := syscall.Bind(s, &syscall.SockaddrNetlink{Pid: 0, Groups: 1}); err
    != nil { // If Pid==0, Kernel chooses
    fmt.Println("****** NetLink Error 2:", err)
    }

    I then use:
    n, err := syscall.Read(s, buffer)
    to load in the message and a derivative of syscall.ParseNetlinkMessage to
    decode it.

    Thanks.
    On 11 January 2015 at 01:00, Dmitry Fedorov wrote:

    Hi,

    there are a few mistakes in your code:
    1)

    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1)

    your belief was right, the last parameter is a netlink group

    checkout linux/netlink.h for valid group number.

    probably your looking for NETLINK_NFLOG or NETLINK_NETFILTER


    2) you cant just start listening netlink socket to get messages.

    first you will need to send a request to kernel.


    here is an example of how to receive chain list from netfilter


    fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
    if err != nil {
    fmt.Println(err)
    }
    var lsa syscall.SockaddrNetlink
    lsa.Family = syscall.AF_NETLINK

    if err := syscall.Bind(fd, &lsa); err != nil {
    syscall.Close(fd)
    fmt.Println(err)
    }

    defer syscall.Close(fd)
    b := make([]byte, 20)
    native.PutUint32(b[0:4], uint32(20)) // length
    native.PutUint16(b[4:6], uint16(NFT_MSG_GETCHAIN)) // type

    native.PutUint16(b[6:8], syscall.NLM_F_REQUEST|syscall.NLM_F_DUMP) //flags
    native.PutUint32(b[8:12], uint32(1)) // seq
    native.PutUint32(b[12:16], uint32(0)) // pid
    b[16] = NFPROTO_IPV4 // nft family
    b[17] = NFNETLINK_V0 // nft version
    native.PutUint16(b[18:20], uint16(0)) // res_id

    _, err = syscall.Getsockname(fd)
    if err != nil {
    fmt.Println(err)
    }

    if err := syscall.Sendto(fd, b, 0, &lsa); err != nil {
    fmt.Println(err)
    }


    понедельник, 24 декабря 2012 г., 13:31:43 UTC+3 пользователь krolaw
    написал:
    Thanks minux,

    Turns out I am probably doing it all wrong. I don't want to dial (at
    least I think I don't), I want to bind a netlink socket to receive the
    multicast messages. Have also discovered that syscall.SOCK_RAW
    and syscall.SOCK_DGRAM are interchangeable as netlink does not distinguish
    the two.

    I'll do some more reading and I'll hopefully post a solution sometime
    after Christmas.

    Cheers.
    On Monday, 24 December 2012 23:10:11 UTC+13, minux wrote:

    On Mon, Dec 24, 2012 at 11:23 AM, krolaw wrote:

    Hi,

    I'm looking for a way to log outgoing connections (using iptables) straight into my Go program.


    iptables -t mangle -A PREROUTING -i br-lan -m state --state NEW -j ULOG

    The iptables man page says that it'll use a default netlink group of 1, which sounds ok, and Golang appears to have some supporting netlink functions (including parsing) in the syscall pkg. However, I'm having problems getting started, as I don't really know what I'm doing. Thus, unsurprisingly, capturing is not working.

    func NetLinkListener() {
    fmt.Println("***** Starting NetLink")
    s, e := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, 1) // Last parameter is netlink group???

    i believe the 3rd parameter should be NETLINK_NETFILTER (12 according
    to <linux/netlink.h>, and
    unfortunately, 1 is NETLINK_UNUSED).
    the netlink group is not related to the protocol parameter.

    I suggest you read socket(2) and netlink(7) and perhaps source code of
    libmnl and ulogd.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 24, '12 at 3:23a
activeJan 10, '15 at 8:39p
posts9
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase