Skip to content

Commit 1293839

Browse files
committed
add option to send node events if enabled
1 parent d4832b9 commit 1293839

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

azure-iptables-monitor/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Follow the steps below to build and run the program:
2929
```
3030
- The `--input` flag specifies the directory containing allowed regex pattern files. Default: `/etc/config/`
3131
- The `--interval` flag specifies how often to check iptables rules in seconds. Default: `600`
32+
- The `--events` flag enables Kubernetes event creation for rule violations. Default: `false`
3233
- The program must be in a k8 environment and `NODE_NAME` must be a set environment variable with the current node.
3334

3435
5. The program will set the `user-iptables-rules` label on the current node to `true` if unexpected rules are found, or `false` if all rules match expected patterns. Proper RBAC is required for patching the node.

azure-iptables-monitor/iptables_monitor.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
goiptables "github.com/coreos/go-iptables/iptables"
14+
corev1 "k8s.io/api/core/v1"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
"k8s.io/apimachinery/pkg/types"
1617
"k8s.io/client-go/kubernetes"
@@ -26,6 +27,7 @@ var version string
2627
var (
2728
configPath = flag.String("input", "/etc/config/", "Name of the directory with the allowed regex files")
2829
checkInterval = flag.Int("interval", 600, "How often to check iptables rules (in seconds)")
30+
sendEvents = flag.Bool("events", false, "Whether to send node events if unexpected iptables rules are detected")
2931
)
3032

3133
const nodeLabel = "user-iptables-rules"
@@ -86,6 +88,49 @@ func patchNodeLabel(clientset *kubernetes.Clientset, labelValue bool, nodeName s
8688
return nil
8789
}
8890

91+
// createNodeEvent creates a Kubernetes event for the specified node
92+
func createNodeEvent(clientset *kubernetes.Clientset, nodeName, reason, message, eventType string) error {
93+
node, err := clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
94+
if err != nil {
95+
return fmt.Errorf("failed to get node %s: %w", nodeName, err)
96+
}
97+
98+
now := metav1.NewTime(time.Now())
99+
100+
event := &corev1.Event{
101+
ObjectMeta: metav1.ObjectMeta{
102+
Name: fmt.Sprintf("%s.%d", nodeName, now.Unix()),
103+
Namespace: "default",
104+
},
105+
InvolvedObject: corev1.ObjectReference{
106+
Kind: "Node",
107+
Name: nodeName,
108+
UID: node.UID, // required for event to show up in node describe
109+
APIVersion: "v1",
110+
},
111+
Reason: reason,
112+
Message: message,
113+
Type: eventType,
114+
FirstTimestamp: now,
115+
LastTimestamp: now,
116+
Count: 1,
117+
Source: corev1.EventSource{
118+
Component: "azure-iptables-monitor",
119+
},
120+
}
121+
_, err = clientset.CoreV1().Events("default").Create(
122+
context.TODO(),
123+
event,
124+
metav1.CreateOptions{},
125+
)
126+
if err != nil {
127+
return fmt.Errorf("failed to create event for node %s: %w", nodeName, err)
128+
}
129+
130+
klog.V(2).Infof("Created event for node %s: %s - %s", nodeName, reason, message)
131+
return nil
132+
}
133+
89134
type IPTablesClient interface {
90135
ListChains(table string) ([]string, error)
91136
List(table, chain string) ([]string, error)
@@ -231,6 +276,13 @@ func main() {
231276
klog.V(2).Infof("Successfully updated node label for %s: %s=%v", currentNodeName, nodeLabel, userIPTablesRulesFound)
232277
}
233278

279+
if *sendEvents && userIPTablesRulesFound {
280+
err = createNodeEvent(clientset, currentNodeName, "UnexpectedIPTablesRules", "Node has unexpected iptables rules", corev1.EventTypeWarning)
281+
if err != nil {
282+
klog.Errorf("failed to create event: %v", err)
283+
}
284+
}
285+
234286
time.Sleep(time.Duration(*checkInterval) * time.Second)
235287
}
236288
}

0 commit comments

Comments
 (0)