Skip to content

Commit

Permalink
feat: add port security to pod port
Browse files Browse the repository at this point in the history
Prevent MAC or IP spoofing
  • Loading branch information
oilbeater committed Aug 23, 2019
1 parent 325cc1b commit 80de8e5
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 80 deletions.
75 changes: 38 additions & 37 deletions pkg/controller/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func (c *Controller) handleAddNode(key string) error {
nic, err := c.ovnClient.CreatePort(
c.config.NodeSwitch, fmt.Sprintf("node-%s", key),
node.Annotations[util.IpAddressAnnotation],
node.Annotations[util.CidrAnnotation],
node.Annotations[util.MacAddressAnnotation])
if err != nil {
return err
Expand Down Expand Up @@ -176,44 +177,23 @@ func (c *Controller) handleAddNode(key string) error {
}

ipCr, err := c.config.KubeOvnClient.KubeovnV1().IPs().Get(key, metav1.GetOptions{})
if err != nil && k8serrors.IsNotFound(err) {
_, err := c.config.KubeOvnClient.KubeovnV1().IPs().Create(&kubeovnv1.IP{
ObjectMeta: metav1.ObjectMeta{
Name: key,
Labels: map[string]string{
util.SubnetNameLabel: c.config.NodeSwitch,
if err != nil {
if k8serrors.IsNotFound(err) {
_, err := c.config.KubeOvnClient.KubeovnV1().IPs().Create(&kubeovnv1.IP{
ObjectMeta: metav1.ObjectMeta{
Name: key,
Labels: map[string]string{
util.SubnetNameLabel: c.config.NodeSwitch,
},
},
},
Spec: kubeovnv1.IPSpec{
PodName: key,
Subnet: c.config.NodeSwitch,
NodeName: key,
IPAddress: nic.IpAddress,
MacAddress: nic.MacAddress,
},
})
if err != nil {
errMsg := fmt.Errorf("failed to create ip crd for %s, %v", nic.IpAddress, err)
klog.Error(errMsg)
return errMsg
}
} else {
if err != nil {
if ipCr.Labels != nil {
ipCr.Labels[util.SubnetNameLabel] = c.config.NodeSwitch
} else {
ipCr.Labels = map[string]string{
util.SubnetNameLabel: c.config.NodeSwitch,
}
}
ipCr.Spec.PodName = key
ipCr.Spec.Namespace = ""
ipCr.Spec.Subnet = c.config.NodeSwitch
ipCr.Spec.NodeName = key
ipCr.Spec.IPAddress = nic.IpAddress
ipCr.Spec.MacAddress = nic.MacAddress
ipCr.Spec.ContainerID = ""
_, err := c.config.KubeOvnClient.KubeovnV1().IPs().Update(ipCr)
Spec: kubeovnv1.IPSpec{
PodName: key,
Subnet: c.config.NodeSwitch,
NodeName: key,
IPAddress: nic.IpAddress,
MacAddress: nic.MacAddress,
},
})
if err != nil {
errMsg := fmt.Errorf("failed to create ip crd for %s, %v", nic.IpAddress, err)
klog.Error(errMsg)
Expand All @@ -224,6 +204,27 @@ func (c *Controller) handleAddNode(key string) error {
klog.Error(errMsg)
return errMsg
}
} else {
if ipCr.Labels != nil {
ipCr.Labels[util.SubnetNameLabel] = c.config.NodeSwitch
} else {
ipCr.Labels = map[string]string{
util.SubnetNameLabel: c.config.NodeSwitch,
}
}
ipCr.Spec.PodName = key
ipCr.Spec.Namespace = ""
ipCr.Spec.Subnet = c.config.NodeSwitch
ipCr.Spec.NodeName = key
ipCr.Spec.IPAddress = nic.IpAddress
ipCr.Spec.MacAddress = nic.MacAddress
ipCr.Spec.ContainerID = ""
_, err := c.config.KubeOvnClient.KubeovnV1().IPs().Update(ipCr)
if err != nil {
errMsg := fmt.Errorf("failed to create ip crd for %s, %v", nic.IpAddress, err)
klog.Error(errMsg)
return errMsg
}
}

return err
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func (c *Controller) handleAddPod(key string) error {
ip := pod.Annotations[util.IpAddressAnnotation]
mac := pod.Annotations[util.MacAddressAnnotation]

nic, err := c.ovnClient.CreatePort(subnet.Name, ovs.PodNameToPortName(name, namespace), ip, mac)
nic, err := c.ovnClient.CreatePort(subnet.Name, ovs.PodNameToPortName(name, namespace), ip, subnet.Spec.CIDRBlock, mac)
if err != nil {
return err
}
Expand Down Expand Up @@ -552,7 +552,7 @@ func (c *Controller) handleAddIpPoolPod(key string) error {
// pod address info may already exist in ovn
ip := pod.Annotations[util.IpAddressAnnotation]
mac := pod.Annotations[util.MacAddressAnnotation]
nic, err := c.ovnClient.CreatePort(subnet.Name, ovs.PodNameToPortName(name, namespace), ip, mac)
nic, err := c.ovnClient.CreatePort(subnet.Name, ovs.PodNameToPortName(name, namespace), ip, subnet.Spec.CIDRBlock, mac)
if err != nil {
return err
}
Expand Down
80 changes: 40 additions & 40 deletions pkg/daemon/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,47 +73,25 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon
}

ipCrd, err := csh.KubeOvnClient.KubeovnV1().IPs().Get(fmt.Sprintf("%s.%s", podRequest.PodName, podRequest.PodNamespace), metav1.GetOptions{})
if err != nil && k8serrors.IsNotFound(err) {
_, err := csh.KubeOvnClient.KubeovnV1().IPs().Create(&kubeovnv1.IP{
ObjectMeta: v1.ObjectMeta{
Name: fmt.Sprintf("%s.%s", podRequest.PodName, podRequest.PodNamespace),
Labels: map[string]string{
util.SubnetNameLabel: subnet,
if err != nil {
if k8serrors.IsNotFound(err) {
_, err := csh.KubeOvnClient.KubeovnV1().IPs().Create(&kubeovnv1.IP{
ObjectMeta: v1.ObjectMeta{
Name: fmt.Sprintf("%s.%s", podRequest.PodName, podRequest.PodNamespace),
Labels: map[string]string{
util.SubnetNameLabel: subnet,
},
},
},
Spec: kubeovnv1.IPSpec{
PodName: podRequest.PodName,
Namespace: podRequest.PodNamespace,
Subnet: subnet,
NodeName: csh.Config.NodeName,
IPAddress: ip,
MacAddress: macAddr,
ContainerID: podRequest.ContainerID,
},
})
if err != nil {
errMsg := fmt.Errorf("failed to create ip crd for %s, %v", ip, err)
klog.Error(errMsg)
resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.PodResponse{Err: errMsg.Error()})
return
}
} else {
if err != nil {
if ipCrd.Labels != nil {
ipCrd.Labels[util.SubnetNameLabel] = subnet
} else {
ipCrd.Labels = map[string]string{
util.SubnetNameLabel: subnet,
}
}
ipCrd.Spec.PodName = podRequest.PodName
ipCrd.Spec.Namespace = podRequest.PodNamespace
ipCrd.Spec.Subnet = subnet
ipCrd.Spec.NodeName = csh.Config.NodeName
ipCrd.Spec.IPAddress = ip
ipCrd.Spec.MacAddress = macAddr
ipCrd.Spec.ContainerID = podRequest.ContainerID
_, err := csh.KubeOvnClient.KubeovnV1().IPs().Update(ipCrd)
Spec: kubeovnv1.IPSpec{
PodName: podRequest.PodName,
Namespace: podRequest.PodNamespace,
Subnet: subnet,
NodeName: csh.Config.NodeName,
IPAddress: ip,
MacAddress: macAddr,
ContainerID: podRequest.ContainerID,
},
})
if err != nil {
errMsg := fmt.Errorf("failed to create ip crd for %s, %v", ip, err)
klog.Error(errMsg)
Expand All @@ -126,6 +104,28 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon
resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.PodResponse{Err: errMsg.Error()})
return
}
} else {
if ipCrd.Labels != nil {
ipCrd.Labels[util.SubnetNameLabel] = subnet
} else {
ipCrd.Labels = map[string]string{
util.SubnetNameLabel: subnet,
}
}
ipCrd.Spec.PodName = podRequest.PodName
ipCrd.Spec.Namespace = podRequest.PodNamespace
ipCrd.Spec.Subnet = subnet
ipCrd.Spec.NodeName = csh.Config.NodeName
ipCrd.Spec.IPAddress = ip
ipCrd.Spec.MacAddress = macAddr
ipCrd.Spec.ContainerID = podRequest.ContainerID
_, err := csh.KubeOvnClient.KubeovnV1().IPs().Update(ipCrd)
if err != nil {
errMsg := fmt.Errorf("failed to create ip crd for %s, %v", ip, err)
klog.Error(errMsg)
resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.PodResponse{Err: errMsg.Error()})
return
}
}

ipAddr = fmt.Sprintf("%s/%s", ip, strings.Split(cidr, "/")[1])
Expand Down
11 changes: 10 additions & 1 deletion pkg/ovs/ovn-nbctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (c Client) DeletePort(port string) error {
}

// CreatePort create logical switch port in ovn
func (c Client) CreatePort(ls, port, ip, mac string) (*nic, error) {
func (c Client) CreatePort(ls, port, ip, cidr, mac string) (*nic, error) {
if ip == "" && mac == "" {
_, err := c.ovnNbCommand(WaitSb, MayExist, "lsp-add", ls, port,
"--", "set", "logical_switch_port", port, "addresses=dynamic")
Expand Down Expand Up @@ -76,6 +76,15 @@ func (c Client) CreatePort(ls, port, ip, mac string) (*nic, error) {
mac = address[0]
}
}

if ls != c.NodeSwitch {
_, err := c.ovnNbCommand("lsp-set-port-security", port, fmt.Sprintf("%s %s/%s", mac, ip, strings.Split(cidr, "/")[1]))
if err != nil {
klog.Errorf("failed to set port security for %s, %v", port, err)
return nil, err
}
}

return &nic{IpAddress: ip, MacAddress: mac}, nil
}

Expand Down

0 comments on commit 80de8e5

Please sign in to comment.