From b27179fbc7df5d484c384e3d0d391de599ed7ef1 Mon Sep 17 00:00:00 2001 From: Simon Moser Date: Sat, 16 Oct 2021 00:31:21 +0200 Subject: [PATCH] Start script rewritten, proxy changes macs (not fully functional) [#7] --- proxy/cmd/cmd.go | 4 +- proxy/go.mod | 5 +- proxy/go.sum | 7 ++ proxy/main.go | 132 +++++++++++++++++++++++++++++------ test-env/qemu-environment.sh | 40 ----------- 5 files changed, 123 insertions(+), 65 deletions(-) delete mode 100755 test-env/qemu-environment.sh diff --git a/proxy/cmd/cmd.go b/proxy/cmd/cmd.go index 82f420d..b7f166c 100644 --- a/proxy/cmd/cmd.go +++ b/proxy/cmd/cmd.go @@ -53,6 +53,6 @@ func (c *cmd) WaitH() { } const ( - Out = "\u001b[31m>> " // Prefix for traffic from VM - In = "\u001b[32m<< " // Prefix for traffic to VM + Out = ">> " // Prefix for traffic from VM + In = "<< " // Prefix for traffic to VM ) \ No newline at end of file diff --git a/proxy/go.mod b/proxy/go.mod index 7fc308e..aa6984a 100644 --- a/proxy/go.mod +++ b/proxy/go.mod @@ -2,4 +2,7 @@ module proxy go 1.13 -require github.com/google/gopacket v1.1.19 // indirect +require ( + github.com/google/gopacket v1.1.19 + github.com/sirupsen/logrus v1.8.1 +) diff --git a/proxy/go.sum b/proxy/go.sum index fc169e8..48f926c 100644 --- a/proxy/go.sum +++ b/proxy/go.sum @@ -1,3 +1,4 @@ +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -12,6 +13,10 @@ github.com/mdlayher/raw v0.0.0-20190313224157-43dbcdd7739d h1:rjAS0af7FIYCScTtEU github.com/mdlayher/raw v0.0.0-20190313224157-43dbcdd7739d/go.mod h1:r1fbeITl2xL/zLbVnNHFyOzQJTgr/3fpf1lJX/cjzR8= github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18 h1:zwOa3e/13D6veNIz6zzuqrd3eZEMF0dzD0AQWKcYSs4= github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -31,6 +36,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4 h1:3i7qG/aA9NUAzdnJHfhgxSKSmxbAebomYR5IZgFbC5Y= golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/proxy/main.go b/proxy/main.go index 1b7e717..52eb11a 100644 --- a/proxy/main.go +++ b/proxy/main.go @@ -2,22 +2,47 @@ package main import ( "encoding/binary" - "fmt" + "flag" "github.com/google/gopacket" "github.com/google/gopacket/layers" - _ "github.com/google/gopacket/layers" + log "github.com/sirupsen/logrus" "io" + "net" "proxy/cmd" + "strconv" ) +var OldMac net.HardwareAddr +var NewMac net.HardwareAddr +var OldIP net.IP +var NewIP net.IP + + // Start the two plugs and run two concurrent forward methods func main() { + // Get command line arguments + logLvl := flag.Int("log", 4, "allowed: 5 (debug), 4 (info), 3 (warning), 2 (error), 1 (fatal)") + oldip := flag.String("oldip", "10.0.0.11", "IP before change") + newip := flag.String("newip", "10.0.0.15", "IP after change") + oldmac := flag.String("oldmac", "52:54:00:12:34:56", "MAC before change") + newmac := flag.String("newmac", "52:54:00:12:34:aa", "MAC after change") + passthrough := flag.Bool("passthrough", false, "Whether to pass every traffic through") + proxy := flag.String("proxy", "1", "Number of the proxy switch") + flag.Parse() + log.SetLevel(log.Level(*logLvl)) + OldMac, _ = net.ParseMAC(*oldmac) + NewMac, _ = net.ParseMAC(*newmac) + OldIP = net.ParseIP(*oldip) + NewIP = net.ParseIP(*newip) + log.SetFormatter(&log.TextFormatter{ + DisableTimestamp: true, + }) c1 := cmd.New("vde_plug", "/run/vde/sw_main.sock") - c2 := cmd.New("vde_plug", "/run/vde/sw_proxy.sock") + c2 := cmd.New("vde_plug", "/run/vde/sw_proxy" + *proxy + ".sock") c1.Execute() c2.Execute() - go pipeForward(c1.OutReader, c2.InWriter, cmd.In) - go pipeForward(c2.OutReader, c1.InWriter, cmd.Out) + go pipeForward(c1.OutReader, c2.InWriter, cmd.In, *passthrough) + go pipeForward(c2.OutReader, c1.InWriter, cmd.Out, *passthrough) c1.WaitH() c2.WaitH() } @@ -26,22 +51,18 @@ func main() { // do things to the content in between. // For now only output the packet's information // Is meant to be run concurrently with "go pipeForward(...)" -func pipeForward(reader io.Reader, writer io.Writer, prefix string) { +func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough bool) { for { - // Read frame length and print it + // Read frame length frameLength := make([]byte, 2) - _, err := reader.Read(frameLength) - if err == io.EOF { - break + if _, err := reader.Read(frameLength); err == io.EOF { + log.Fatal(prefix, "Error reading frame length") } - frameLengthInt := int(binary.BigEndian.Uint16(frameLength)) - fmt.Printf("%s Frame length: %d\n", prefix, frameLengthInt) // Read actual frame - frameBytes := make([]byte, frameLengthInt) - _, err = reader.Read(frameBytes) - if err == io.EOF { - break + frameBytes := make([]byte, int(binary.BigEndian.Uint16(frameLength))) + if _, err := reader.Read(frameBytes); err == io.EOF { + log.Fatal(prefix, "Error reading frame data") } // Convert frame to full stack packet @@ -49,22 +70,89 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string) { // Handle Ethernet frame frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet) - fmt.Printf("src: %s\ndst: %s\ntyp: %s\n", frame.SrcMAC, frame.DstMAC, frame.EthernetType) + if !passthrough && prefix == cmd.In { + log.Debug(prefix, "Incoming MAC rewritten ", frame.DstMAC, OldMac) + frame.DstMAC = OldMac + } else if !passthrough && prefix == cmd.Out { + log.Debug(prefix, "Outgoing MAC rewritten ", frame.SrcMAC, NewMac) + frame.SrcMAC = NewMac + } + + // Handle IP packet + if ipv4layer := packet.Layer(layers.LayerTypeIPv4); ipv4layer != nil { + ipv4Packet, _ := ipv4layer.(*layers.IPv4) + if !passthrough && prefix == cmd.In { + log.Debug(prefix, "Incoming IP rewritten ", ipv4Packet.DstIP, OldIP) + ipv4Packet.DstIP = OldIP + } else if !passthrough && prefix == cmd.Out { + log.Debug(prefix, "Outgoing IP rewritten ", ipv4Packet.SrcIP, NewMac) + ipv4Packet.SrcIP = NewIP + } + } // Handle ARP packet if frame.EthernetType == layers.EthernetTypeARP { arpPacket := packet.Layer(layers.LayerTypeARP).(*layers.ARP) - fmt.Printf("%sARP Packet:\n%#v\n", prefix, arpPacket) + log.Infof( + "%sARP before modification\nAddrType:\t%s\nProtocol:\t%s\nOperation:\t%s\n" + + "SrcHwAddress:\t%s\nSrcProtAddress:\t%s\nDstHwAddress:\t%s\nDstProAddress:\t%s\n", + prefix, + arpPacket.AddrType, + arpPacket.Protocol, + strconv.Itoa(int(arpPacket.Operation)), + net.HardwareAddr(arpPacket.SourceHwAddress), + net.IP(arpPacket.SourceProtAddress), + net.HardwareAddr(arpPacket.DstHwAddress), + net.IP(arpPacket.DstProtAddress), + ) + + if !passthrough && prefix == cmd.In { + log.Debug(prefix,"Incoming MAC rewritten (ARP) ", net.HardwareAddr(arpPacket.DstHwAddress), OldMac) + arpPacket.DstProtAddress = OldIP + log.Infof( + "%sARP after modification\nDstProtAddress:\t%s\n", + prefix, + net.IP(arpPacket.DstProtAddress), + ) + if arpPacket.Operation == layers.ARPReply { + arpPacket.DstHwAddress = OldMac + log.Infof( + "%sDstHwAddress:\t%s\n", + prefix, + net.HardwareAddr(arpPacket.DstHwAddress), + ) + } + } else if !passthrough && prefix == cmd.Out { + log.Debug(prefix,"Outgoing MAC rewritten (ARP) ", net.HardwareAddr(arpPacket.SourceHwAddress), NewMac) + arpPacket.SourceHwAddress = NewMac + arpPacket.SourceProtAddress = NewIP + log.Infof( + "%sARP after modification\nSrcHwAddress:\t%s\nSrcProtAddress:\t%s\n", + prefix, + net.HardwareAddr(arpPacket.SourceHwAddress), + net.IP(arpPacket.SourceProtAddress), + ) + } } // Handle DHCP packet if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil { - dhcpPacket, _ := dhcpLayer.(*layers.DHCPv4) - fmt.Printf("%sDHCP Packet:\n%#v\n", prefix, dhcpPacket) + //dhcpPacket, _ := dhcpLayer.(*layers.DHCPv4) + log.Info(prefix, "DHCP packet dropped") + continue + } + + buf := gopacket.NewSerializeBuffer() + if err := gopacket.SerializePacket(buf, gopacket.SerializeOptions{}, packet); err != nil { + log.Error(prefix, "Error serializing packet to send") + continue } + newFrameBytes := buf.Bytes() + newFrameLength := make([]byte, 2) + binary.BigEndian.PutUint16(newFrameLength, uint16(len(newFrameBytes))) // Forward original frame to other plug - writer.Write(frameLength) - writer.Write(frameBytes) + writer.Write(newFrameLength) + writer.Write(newFrameBytes) } } \ No newline at end of file diff --git a/test-env/qemu-environment.sh b/test-env/qemu-environment.sh deleted file mode 100755 index c845876..0000000 --- a/test-env/qemu-environment.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -# QEMU/VDE network environment preparation script -RUN='/run/vde' -qemu=/opt/qemu/build/qemu-system-x86_64 - -case "$1" in - start) - echo "Starting VDE network for QEMU: " - # Create run dir - sudo mkdir -p $RUN && sudo chown `id -un`:`id -gn` $RUN - # Main switch - vde_switch -daemon -s $RUN/sw_main.sock -p $RUN/sw_main.pid - # Proxy switch -.- - vde_switch -daemon -s $RUN/sw_proxy.sock -p $RUN/sw_proxy.pid - # Slirp NAT + Port forwarding SSH - slirpvde -D -H 10.0.0.2 --daemon -s $RUN/sw_main.sock -p $RUN/slirp.pid - #echo "Run:\nqemu -m 512 -nic vde,mac='52:54:00:12:34:56',sock=$RUN/sw_proxy.sock -hda alpine1.qcow2 -nographic" - $qemu -m 512 -nic vde,mac='52:54:00:12:34:56',sock=$RUN/sw_proxy.sock -hda alpine1.qcow2 -daemonize -vnc :1 -pidfile $RUN/vm_1.pid - $qemu -m 512 -nic vde,mac='52:54:00:12:34:66',sock=$RUN/sw_main.sock -hda alpine2.qcow2 -daemonize -vnc :2 -pidfile $RUN/vm_2.pid - ;; - stop) - echo "Stopping VDE network for QEMU: " - kill `cat $RUN/*.pid | xargs` - ;; - restart|reload) - $0 stop - sleep 1 - $0 start - ;; - status) - ps -fq `cat $RUN/*.pid | xargs | sed 's/ /,/g'` - ;; - ssh) - ssh -p 2222 root@localhost - ;; - *) - echo "Usage: $0 {start|stop|restart|reload}" - exit 1 -esac -exit 0