mosers
/
eaas-vde-proxy
Archiviert
1
0
Fork 0

Documentation improved

main
Simon Moser vor 3 Jahren
Ursprung 6d29070fe6
Commit eb7a31446a
Signiert von: mosers
GPG-Schlüssel-ID: 96B3365A234B500C

@ -4,6 +4,9 @@
![overview](README.assets/overview.png)
## Documentation
See [[Wiki|Home]]
## Problematic protocols
Important and implemented:

@ -10,19 +10,19 @@ import (
// Cmd Overloads the exec.Cmd class to save the full command
// and adds custom input/output pipes
type Cmd struct {
fullCommand string
fullCommand string
*exec.Cmd
inReader io.Reader
InWriter io.Writer
OutReader io.Reader
outWriter io.Writer
inReader io.Reader
InWriter io.Writer
OutReader io.Reader
outWriter io.Writer
}
// Start creates a new cmd object with given arguments, runs and then returns it
func Start(args string) (*Cmd, io.Reader, io.Writer) {
ir, iw := io.Pipe()
or, ow := io.Pipe()
c := Cmd {
c := Cmd{
"vde_plug " + args,
exec.Command("vde_plug", args),
ir,
@ -47,8 +47,3 @@ func (c *Cmd) WaitH() {
log.Printf("%s failed with %s\n", c.fullCommand, err)
}
}
const (
Out = ">> " // Prefix for traffic from VM
In = "<< " // Prefix for traffic to VM
)

@ -21,22 +21,33 @@ var OldMAC net.HardwareAddr
var NewMAC net.HardwareAddr
var OldIP net.IP
var NewIP net.IP
// In-/Output to VM and network
var VmReader io.Reader
var VmWriter io.Writer
var NetReader io.Reader
var NetWriter io.Writer
var Passthrough bool
var XId []byte
// DHCP variables
var DHCPXId []byte
var DHCPIP net.IP
var RouterIP net.IP
var DNSIP net.IP
var DHCPRouterIP net.IP
var DHCPDNSIP net.IP
var DHCPMAC net.HardwareAddr
var DHCPMask []byte
var DHCPState dhcp4.MessageType
var DHCPCandidate net.IP
var UId string
var Wireshark bool
// User-provided variables
var Hostname string
var Passthrough bool
var Wireshark bool
// UId used as host name
var UId string
// Start the two plugs and run two concurrent forward methods
func main() {
@ -82,8 +93,8 @@ func main() {
NetWriter = os.Stdin
}
c2, VmReader, VmWriter = cmd.Start(*sockProxy)
go pipeForward(cmd.In)
go pipeForward(cmd.Out)
go pipeForward(In)
go pipeForward(Out)
if NewIP == nil && !Passthrough {
sendDHCPRequest(dhcp4.Discover, net.IPv4zero)
}
@ -95,11 +106,12 @@ func main() {
// Reads from an input and writes to and output,
// do things to the content in between.
// Is meant to be run concurrently with "go pipeForward(...)"
// Is meant to be run concurrently with "go pipeForward(...)".
// This is the main loop of the proxy.
func pipeForward(prefix string) {
var reader io.Reader
var writer io.Writer
if prefix == cmd.In {
if prefix == In {
reader = NetReader
writer = VmWriter
} else {
@ -139,8 +151,8 @@ func pipeForward(prefix string) {
packet := gopacket.NewPacket(frameBytes, layers.LayerTypeEthernet, gopacket.Default)
// Handle Ethernet frame
frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
log.Debug("Start packet")
frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
filterMAC(prefix, &frame.DstMAC, &frame.SrcMAC, frame.LayerType())
// Handle IPv4 packet
@ -222,6 +234,7 @@ func pipeForward(prefix string) {
}
}
// filterPayloads filters binary payloads to be able to process unsupported protocols
func filterPayload(prefix string, payload *[]byte) {
// Populate slices with values to on vm and network side
vmVals := [][]byte{OldMAC}
@ -238,7 +251,7 @@ func filterPayload(prefix string, payload *[]byte) {
// Choose for which slice to search for and which to replace it with
searchVals := vmVals
replaceVals := netVals
if prefix == cmd.In {
if prefix == In {
searchVals = netVals
replaceVals = vmVals
}
@ -255,12 +268,12 @@ func filterIP(prefix string, dst interface{}, src interface{}, context gopacket.
var condVal net.IP
var newVal net.IP
var which string
if prefix == cmd.In {
if prefix == In {
target = dst
which = "dst"
condVal = NewIP
newVal = OldIP
} else if prefix == cmd.Out {
} else if prefix == Out {
target = src
which = "src"
condVal = OldIP
@ -271,9 +284,9 @@ func filterIP(prefix string, dst interface{}, src interface{}, context gopacket.
// If no OldIP is set yet, get it from outgoing src field
if OldIP == nil {
if prefix == cmd.In {
if prefix == In {
return
} else if prefix == cmd.Out {
} else if prefix == Out {
if isIp {
if !ip.IsGlobalUnicast() {
return
@ -302,9 +315,9 @@ func filterMAC(prefix string, dst interface{}, src interface{}, context gopacket
// If no OldMAC is set yet, get it from outgoing src field
// Has to be HardwareAddr because this is used for ethernet frames which call this method first
if OldMAC == nil {
if prefix == cmd.In {
if prefix == In {
return
} else if prefix == cmd.Out {
} else if prefix == Out {
OldMAC = *src.(*net.HardwareAddr)
log.Info("OldMAC set to ", OldMAC)
}
@ -314,12 +327,12 @@ func filterMAC(prefix string, dst interface{}, src interface{}, context gopacket
var condVal net.HardwareAddr
var newVal net.HardwareAddr
var which string
if prefix == cmd.In {
if prefix == In {
target = dst
which = "dst"
condVal = NewMAC
newVal = OldMAC
} else if prefix == cmd.Out {
} else if prefix == Out {
target = src
which = "src"
condVal = OldMAC
@ -337,6 +350,8 @@ func filterMAC(prefix string, dst interface{}, src interface{}, context gopacket
}
}
// handleDHCP provides the main DHCP functionality to request an IP from a server on the one hand
// and provide an IP to the VM on the other hand
func handleDHCP(content []byte, dstMAC net.HardwareAddr, srcMAC net.HardwareAddr, prefix string) {
req := dhcp4.Packet(content)
if req.HLen() > 16 { // Invalid size
@ -356,7 +371,7 @@ func handleDHCP(content []byte, dstMAC net.HardwareAddr, srcMAC net.HardwareAddr
}
}
log.Debug(prefix, "DHCP message registered: ", reqType)
if prefix == cmd.Out {
if prefix == Out {
switch reqType {
case dhcp4.Discover:
if OldIP == nil {
@ -399,10 +414,10 @@ func handleDHCP(content []byte, dstMAC net.HardwareAddr, srcMAC net.HardwareAddr
DHCPMask = mask
}
if dns := options[dhcp4.OptionDomainNameServer]; dns != nil {
DNSIP = dns
DHCPDNSIP = dns
}
if router := options[dhcp4.OptionRouter]; router != nil {
RouterIP = router
DHCPRouterIP = router
}
DHCPCandidate = offIP
sendDHCPRequest(dhcp4.Request, offIP)
@ -422,7 +437,7 @@ func handleDHCP(content []byte, dstMAC net.HardwareAddr, srcMAC net.HardwareAddr
}
}
// sendDHCPReply creates a response DHCP packet and sends it
// sendDHCPReply creates a response DHCP packet for the VM and sends it
func sendDHCPReply(req dhcp4.Packet, mt dhcp4.MessageType, lease net.IP, reqOpt dhcp4.Options, dstMAC net.HardwareAddr) {
if DHCPIP == nil || DHCPMAC == nil {
log.Info("DHCP server is not known, discover request from VM discarded")
@ -435,8 +450,8 @@ func sendDHCPReply(req dhcp4.Packet, mt dhcp4.MessageType, lease net.IP, reqOpt
// Getting the options
opt := dhcp4.Options{
dhcp4.OptionSubnetMask: DHCPMask,
dhcp4.OptionRouter: RouterIP,
dhcp4.OptionDomainNameServer: DNSIP,
dhcp4.OptionRouter: DHCPRouterIP,
dhcp4.OptionDomainNameServer: DHCPDNSIP,
}.SelectOrderOrAll(reqOpt[dhcp4.OptionParameterRequestList])
// Creating the full packet layer by layer
@ -482,10 +497,11 @@ func sendDHCPReply(req dhcp4.Packet, mt dhcp4.MessageType, lease net.IP, reqOpt
}
}
// sendDHCPRequest creates a request DHCP packet for the server and sends it
func sendDHCPRequest(mt dhcp4.MessageType, reqIP net.IP) {
log.Info("Sending DHCP request: ", mt)
if mt == dhcp4.Discover {
XId = GenerateXID()
DHCPXId = GenerateXID()
}
DHCPState = mt
@ -527,7 +543,7 @@ func sendDHCPRequest(mt dhcp4.MessageType, reqIP net.IP) {
Value: reqIP.To4(),
})
}
dhcp := dhcp4.RequestPacket(mt, NewMAC, reqIP, XId, false, dhcpOpts)
dhcp := dhcp4.RequestPacket(mt, NewMAC, reqIP, DHCPXId, false, dhcpOpts)
if err := udp.SetNetworkLayerForChecksum(&ipv4); err != nil {
log.Error("Error building DHCP request: ", err)
}

@ -40,13 +40,7 @@ func WritePcap(file string, data []byte) {
err = r.WritePacket(ci, data)
}
// WriteBinary writes the provided data to a given binary file
func WriteBinary(file string, data []byte) {
if err := ioutil.WriteFile(file, data, 0644); err != nil {
log.Errorf("Error writing binary file %s", file)
}
}
// WritePIDFile writes the processes PID to a given file
func WritePIDFile(filename string) {
if filename == "" {
return
@ -56,6 +50,7 @@ func WritePIDFile(filename string) {
}
}
// GenerateMac generates a random MAC address
func GenerateMac(customMAC string) net.HardwareAddr {
if customMAC != "" {
ret, _ := net.ParseMAC(customMAC)
@ -74,6 +69,7 @@ func GenerateMac(customMAC string) net.HardwareAddr {
return mac
}
// GenerateXID generates a random XID for DHCP
func GenerateXID() []byte {
buf := make([]byte, 4)
if _, err := rand.Read(buf); err != nil {
@ -84,6 +80,7 @@ func GenerateXID() []byte {
return buf
}
// GenerateUId generates a random UId string as hostname
func GenerateUId(path string) string {
adl := adler32.Checksum([]byte(path))
byt := make([]byte, 4)
@ -126,8 +123,9 @@ func (c If) IP(a, b net.IP) net.IP {
return b
}
// Source: https://github.com/aler9/landiscover/blob/main/utils.go
// <size>part<size>part
// Source: https://github.com/aler9/landiscover/blob/main/utils.go, MIT LICENSE
// DnsQueryDecode takes encoded hostnames from Microsoft and decodes it
func DnsQueryDecode(data []byte, start int) (string, int) {
var read []byte
toread := uint8(0)
@ -170,6 +168,7 @@ func DnsQueryDecode(data []byte, start int) (string, int) {
return string(read), pos + 1 - start
}
// DnsQueryEncode takes string hostnames and encodes it to Microsoft format
func DnsQueryEncode(in string) []byte {
tmp := strings.Split(in, ".")
@ -196,3 +195,9 @@ func DnsQueryEncode(in string) []byte {
return ret
}
// Prefixes for traffic from (out) or to (in) VM
const (
Out = ">> "
In = "<< "
)