Skip to content

Instantly share code, notes, and snippets.

@covertsh
Created May 17, 2020 19:08
Show Gist options
  • Save covertsh/a627e99381d0a01bc5ba3f6226ec73f3 to your computer and use it in GitHub Desktop.
Save covertsh/a627e99381d0a01bc5ba3f6226ec73f3 to your computer and use it in GitHub Desktop.
TCP-MD5 client and server in Golang (RFC 2385). Written and tested using Go 1.14.3 on Ubuntu 18.04 x64 running kernel 4.15. See accompanying blog post: https://covert.sh/2020/05/17/golang-tcp-md5/
package main
import (
"context"
"golang.org/x/sys/unix"
"io"
"log"
"net"
"os"
"syscall"
"time"
"unsafe"
)
func main() {
key := []byte("sup3rsecretkey")
var keyArray [80]byte
copy(keyArray[0:], key)
saStorage := unix.SockaddrStorage{
Family: unix.AF_INET,
}
tcpMD5Sig := unix.TCPMD5Sig{
Addr: saStorage,
Flags: unix.TCP_MD5SIG_FLAG_PREFIX,
Prefixlen: 0,
Keylen: uint16(len(key)),
Key: keyArray,
}
var d net.Dialer
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
d.Control = func(network, address string, c syscall.RawConn) error {
var err error
c.Control(func(fdPtr uintptr) {
fd := int(fdPtr)
b := *(*[unsafe.Sizeof(tcpMD5Sig)]byte)(unsafe.Pointer(&tcpMD5Sig))
err = unix.SetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_MD5SIG_EXT, string(b[:]))
})
return err
}
conn, err := d.DialContext(ctx, "tcp", "127.0.0.1:8081")
if err != nil {
log.Fatal(err)
}
go func() {
io.Copy(os.Stdout, conn)
}()
io.Copy(conn, os.Stdin)
conn.Close()
}
package main
import (
"context"
"golang.org/x/sys/unix"
"io"
"log"
"net"
"syscall"
"time"
"unsafe"
)
func main() {
key := []byte("sup3rsecretkey")
var keyArray [80]byte
copy(keyArray[0:], key)
saStorage := unix.SockaddrStorage{
Family: unix.AF_INET,
}
tcpMD5Sig := unix.TCPMD5Sig{
Addr: saStorage,
Flags: unix.TCP_MD5SIG_FLAG_PREFIX,
Prefixlen: 0,
Keylen: uint16(len(key)),
Key: keyArray,
}
var lc net.ListenConfig
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
lc.Control = func(network, address string, c syscall.RawConn) error {
var err error
c.Control(func(fdPtr uintptr) {
fd := int(fdPtr)
b := *(*[unsafe.Sizeof(tcpMD5Sig)]byte)(unsafe.Pointer(&tcpMD5Sig))
err = unix.SetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_MD5SIG_EXT, string(b[:]))
})
return err
}
l, err := lc.Listen(ctx, "tcp", "127.0.0.1:8081")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
go func(c net.Conn) {
io.Copy(c, c)
c.Close()
}(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment