From 2ed9cf258be5ce0a26b5ab7f028f64652628c40e Mon Sep 17 00:00:00 2001 From: Michael Cambria Date: Wed, 17 Apr 2019 13:28:30 -0400 Subject: [PATCH] Added unix socket --- api/api.proto | 23 +++++++++++------ api/handler.go | 1 + cert/le-unix.txt | 13 ++++++++++ cert/unixServer.crt | 18 +++++++++++++ cert/unixServer.key | 28 ++++++++++++++++++++ client/main.go | 53 ++++++++++++++++++++++++++++++++++++++ server/main.go | 62 ++++++++++++++++++++++++++++++++++++++++----- 7 files changed, 183 insertions(+), 15 deletions(-) create mode 100644 cert/le-unix.txt create mode 100644 cert/unixServer.crt create mode 100644 cert/unixServer.key diff --git a/api/api.proto b/api/api.proto index f925f2a..d9ac730 100644 --- a/api/api.proto +++ b/api/api.proto @@ -20,7 +20,13 @@ enum CmdType { DEL = 3; } -message CNIargs { +// "portMappings": [ +// { "hostPort": 9090, "containerPort": 90, "protocol": "sctp" }, +// { "hostPort": 9090, "containerPort": 90, "protocol": "tcp" } +// ] + + +message CNIcapArgs { string name = 1; string value = 2; } @@ -32,13 +38,14 @@ message ConfPath { message CNImsg { ConfPath configPath = 1; - string binPath = 8; - CmdType cmd = 2; - string containerID = 3; - string netNS = 4; - string ifName = 5; - repeated CNIargs args = 6; - string stdIn = 7; + string binPath = 2; + CmdType cmd = 3; + string containerID = 4; + string netNS = 5; + string ifName = 6; + string cniArgs = 7; + string stdIn = 8; + repeated CNIcapArgs capArgs = 9; } message CNIresult { diff --git a/api/handler.go b/api/handler.go index 0a62665..7a838e2 100644 --- a/api/handler.go +++ b/api/handler.go @@ -22,6 +22,7 @@ func (s *CNIServer) CNIop(ctx context.Context, in *CNImsg) (*CNIresult, error) { log.Printf("Receive message NetNS: %s", in.NetNS) log.Printf("Receive message IfName: %s", in.IfName) log.Printf("Receive message StdIn: %s", in.StdIn) + log.Printf("Receive message CniArgs: %s", in.CniArgs) cniResult := CNIresult{ Cmd: in.Cmd, diff --git a/cert/le-unix.txt b/cert/le-unix.txt new file mode 100644 index 0000000..e860292 --- /dev/null +++ b/cert/le-unix.txt @@ -0,0 +1,13 @@ + +openssl req -x509 -out localhost.crt -keyout localhost.key \ + -newkey rsa:2048 -nodes -sha256 \ + -subj '/CN=localhost' -extensions EXT -config <( \ + printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") + + +openssl req -x509 -out unixServer.crt -keyout unixServer.key \ + -newkey rsa:2048 -nodes -sha256 \ + -subj '/CN=unix' -extensions EXT -config <( \ + printf "[dn]\nCN=unix\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:unix\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") + + diff --git a/cert/unixServer.crt b/cert/unixServer.crt new file mode 100644 index 0000000..fff9e99 --- /dev/null +++ b/cert/unixServer.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1jCCAb6gAwIBAgIJANibMV3mxLngMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV +BAMMBHVuaXgwHhcNMTkwNDE3MTYwMzMwWhcNMTkwNTE3MTYwMzMwWjAPMQ0wCwYD +VQQDDAR1bml4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA147pAWo7 +9XuZRrtaMMLonlpWvPF4yt8umr5BeQC8UgcLPON0TNB2i5C7kEP1kfR9OsG215Rj +wyg4QHscu0Zc97pmwcINTjyTK15pOAWD5sjcEFCjO4t4MEq1LLLOQxTxNcLPyyrS +ahdJJqtK7ygf1aGHZFBZGXr55hXP1NOwSLhb+4Kf8ycPMQ3fVbaLQmZir4RfAqxm +P63EDuW/FPxVt9MnBd5K64G2vKkKqMu7ioKqXu/DicKthIoE9NiarIcA9oAC+Kni +C/4DlxMqg2Ba8WUIJC9VEcjKdVMrY6cAlMNDM1EQbo22ab0SGUhEkpjw/lcDxMup +rka++qG/9BnrkQIDAQABozUwMzAPBgNVHREECDAGggR1bml4MAsGA1UdDwQEAwIH +gDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAvBQz5yVz +zP5OzViSZWoB8njP5mKAeEyy8J1lEAyM0GdTfBLU+0NhsFx6q45VcdGjtuPPP3Zz +pi0ULGVutnk+++SrtGqqXfhBJGSV5bDxHgX3Wx0wbu5qeoKeiUFyB5y+Qv2vGeTs +R2Rj6cgyqWirMjgIFQCAsH571WPju6fsfDTncZH9ieiQYFcr+c+kYyHiqUjFpZDX +SMdKS87TCQByn5kRsUCgxWYv1XYlrfJl8NPw3k5Ag+dh6mboX00wS59tVAn5VNR2 +Jx2H+50wAYUbWH4T/QWMWP+nHSxMJaJcRBSso+968xWJwbVr1mor/aHbyTdKEGJ5 +fF5iau25fhAJ6g== +-----END CERTIFICATE----- diff --git a/cert/unixServer.key b/cert/unixServer.key new file mode 100644 index 0000000..c8da4c1 --- /dev/null +++ b/cert/unixServer.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDXjukBajv1e5lG +u1owwuieWla88XjK3y6avkF5ALxSBws843RM0HaLkLuQQ/WR9H06wbbXlGPDKDhA +exy7Rlz3umbBwg1OPJMrXmk4BYPmyNwQUKM7i3gwSrUsss5DFPE1ws/LKtJqF0km +q0rvKB/VoYdkUFkZevnmFc/U07BIuFv7gp/zJw8xDd9VtotCZmKvhF8CrGY/rcQO +5b8U/FW30ycF3krrgba8qQqoy7uKgqpe78OJwq2EigT02JqshwD2gAL4qeIL/gOX +EyqDYFrxZQgkL1URyMp1UytjpwCUw0MzURBujbZpvRIZSESSmPD+VwPEy6muRr76 +ob/0GeuRAgMBAAECggEAE9Yr7RxoniOcrFyrZRdars/jcYnLMugs8sKVZdxCeE37 +o8POvQ7mCdvs1s7aN29HYvPWrqoSMDBwVMa/kyBbh9SYhjYkYVHDvVb32dbwF3ne +foXdL6qbCd6mI5Hk11mDBQ6Dbs/nAypXaf6Ta8TGgTNXMU0Plf+yJZFWSeCdNWPO +f4gEkJMNl47CFNdly7LMm8LI/BRxy8w6tgzjstFq2Eem2+1Eomy9r/8Q87ZkZaCd +eFu1lN2a/sS1kaIzcdnNoJvrCGAiz7SbxtmpLiHiOrNGFVx89TjakoPacM28MZYD +2H2C3MAEhGwrDhkCU/eHTFiM1tam7ZEVycEsOeCuwQKBgQD9QotLxIc1lcUKXtc8 +cNqITyIHFHmd5tMHt3Rkr00RjiE85aAuABdDyNgRxUedhWkcWQZmLurDgYbnwX1w +6YQMeP9os/aB4jgViFpb6DP7f2Hms3gv9dIgroWutEffk9eB9mRbQ/86HJrlrnDm +WcK/20t8tILpj4VDSHxDi8CNmQKBgQDZ4/GCbLLcAAonCDaCmakLNapYUXbqduf1 +Kq2C/UJcVAlOyVj1VEmMLWKnW1SSUyj1gsi5p0h9ivvMfl7Pbn0DagnOw2YdD4Xb +O94IN0q/8iOyadtshJqwQV9hZ+zcWkOEhE5SVnPGWm7QKv9rmA1cvFQwihZVOnku +JsA/9d9YuQKBgE8XoA76gkteyZlygv9yMx1MsVDKuSxx8MfBKE1lXck0vPaas8qJ +5roZmDj8hmAQUQI0X0Y8Mr75zZrFF5rSopWOmB0nzr1DW8aFvcpkGw/Y+UcmF0vL +FmN0fXVRAf0126DPxQmnk6afVlSShNm7gJGQN+PrL9MnKjQYCA7EL09JAoGAEd+g +8BH6mhFmw8zoq83vD/xW/Oex2YnnfTUDBru/tdMu8EeUBIvlfJo8fX4AcgBgW8Ne +s9wFFkdQYHX9UQa/Ooh4RX3B4qBjWpiOnh3rA9PZGcmVNlGqXsr+B/9+bpT49OXl +htuQo7THYkwkp67RacoJHfI14sfpKOAE5TpGGAECgYADV5rxn2BbEWhD9+G5GR6x +4DKhstNPmP0RMZsnuJ9i889STA0ltRvCKD0RdywyhhayqQZydX8lrZ7GzVa2MO4U +OaChcAT2m8Li7FcnJz50yLq9pjwpMhw1y9RkSdNKARv9gkCHGAwZDNI/P8rIyJSY +l6jI1bVxIuIX+iChhJx+OQ== +-----END PRIVATE KEY----- diff --git a/client/main.go b/client/main.go index 522d167..9097f31 100644 --- a/client/main.go +++ b/client/main.go @@ -71,10 +71,63 @@ func main() { NetNS: "mcc-test-0", IfName: "ensX", StdIn: "stdInStringHere", + CniArgs: "IgnoreUnknown=1;IP=10.1.0.20", + } result, err := cni.CNIop(context.Background(), &cniMsg) if err != nil { log.Fatalf("error when calling CNIop: %s", err) } log.Printf("Response from server: %s", result.StdOut) + + // Create the unix socket client TLS credentials + creds2, err := credentials.NewClientTLSFromFile("cert/unixServer.crt", "") + if err != nil { + log.Fatalf("could not load tls cert: %s", err) + } + + // Setup the login/pass + auth2 := Authentication{ + Login: "john", + Password: "doe", + } + + var conn2 *grpc.ClientConn + + // Initiate a connection with the server + conn2, err = grpc.Dial("unix:///tmp/grpc.sock", grpc.WithTransportCredentials(creds2), grpc.WithPerRPCCredentials(&auth2)) + if err != nil { + log.Fatalf("did not connect: %s", err) + } + defer conn2.Close() + + // CNI Test + cni2 := api.NewCNIserverClient(conn2) + + /// + cniPath2 := api.ConfPath { + NetDir: "/home/mcambria/go/src/github.com/containernetworking", + NetConf: "firewall-mcc1-range-chain", + } + // + + cniMsg2 := api.CNImsg{ + //ConfigPath: { + //NetDir: "/home/mcambria/go/src/github.com/containernetworking", + //NetConf: "firewall-mcc1-range-chain", + //}, + ConfigPath: &cniPath2, + Cmd: api.CmdType_ADD, + ContainerID: "containerOne", + NetNS: "mcc-test-0", + IfName: "ensX", + StdIn: "stdInStringHere", + CniArgs: "IgnoreUnknown=1;IP=10.1.0.20", + + } + result2, err := cni2.CNIop(context.Background(), &cniMsg2) + if err != nil { + log.Fatalf("error when calling CNIop: %s", err) + } + log.Printf("Response from server: %s", result2.StdOut) } diff --git a/server/main.go b/server/main.go index ffdb8ad..bc71aac 100644 --- a/server/main.go +++ b/server/main.go @@ -6,6 +6,7 @@ import ( "net" "net/http" "strings" + "syscall" "github.com/grpc-ecosystem/grpc-gateway/runtime" @@ -22,6 +23,7 @@ type contextKey int const ( clientIDKey contextKey = iota + unixSocketPath = "/tmp/grpc.sock" ) func credMatcher(headerName string) (mdName string, ok bool) { @@ -67,7 +69,43 @@ func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServ return handler(ctx, req) } -func startGRPCServer(address, certFile, keyFile string) error { +func startGRPCunixServer(address, certFile, keyFile string) error { + // create a listener on unix socket + syscall.Unlink(unixSocketPath) + lis, err := net.Listen("unix", unixSocketPath) + if err != nil { + return fmt.Errorf("failed to listen: %v", err) + } + + // create a CNI server instance + cni := api.CNIServer{} + + // Create the TLS credentials + creds, err := credentials.NewServerTLSFromFile(certFile, keyFile) + if err != nil { + return fmt.Errorf("could not load TLS keys: %s", err) + } + + // Create an array of gRPC options with the credentials + opts := []grpc.ServerOption{grpc.Creds(creds), + grpc.UnaryInterceptor(unaryInterceptor)} + + // create a gRPC server object + grpcCNIServer := grpc.NewServer(opts...) + + // attach the CNI service to the server + api.RegisterCNIserverServer(grpcCNIServer, &cni) + + // start the server + log.Printf("starting CNI unix socket gRPC server on %s", unixSocketPath) + if err := grpcCNIServer.Serve(lis); err != nil { + return fmt.Errorf("failed to serve: %s", err) + } + + return nil +} + +func startGRPCtcpServer(address, certFile, keyFile string) error { // create a listener on TCP port lis, err := net.Listen("tcp", address) if err != nil { @@ -133,20 +171,30 @@ func startRESTServer(address, grpcAddress, certFile string) error { func main() { grpcAddress := fmt.Sprintf("%s:%d", "localhost", 7777) restAddress := fmt.Sprintf("%s:%d", "localhost", 7778) - certFile := "cert/server.crt" - keyFile := "cert/server.key" + tcpcertFile := "cert/server.crt" + tcpkeyFile := "cert/server.key" + unixcertFile := "cert/unixServer.crt" + unixkeyFile := "cert/unixServer.key" - // fire the gRPC server in a goroutine + // fire the gRPC unix socket server in a goroutine go func() { - err := startGRPCServer(grpcAddress, certFile, keyFile) + err := startGRPCunixServer(grpcAddress, unixcertFile, unixkeyFile) if err != nil { - log.Fatalf("failed to start gRPC server: %s", err) + log.Fatalf("failed to start unix socket gRPC server: %s", err) + } + }() + + // fire the gRPC tcp server in a goroutine + go func() { + err := startGRPCtcpServer(grpcAddress, tcpcertFile, tcpkeyFile) + if err != nil { + log.Fatalf("failed to start tcp gRPC server: %s", err) } }() // fire the REST server in a goroutine go func() { - err := startRESTServer(restAddress, grpcAddress, certFile) + err := startRESTServer(restAddress, grpcAddress, tcpcertFile) if err != nil { log.Fatalf("failed to start gRPC server: %s", err) } -- 2.44.0