From 504a2a723befadb0a69c11ef10e0f86ba4bfa653 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Sun, 26 Apr 2026 17:37:25 +0200 Subject: [PATCH] f-25: vms: add iptables gestion Signed-off-by: GnomeZworc --- internal/iptables/iptables.go | 42 +++++++++++++++++++++++++++++++++++ internal/vm/create.go | 36 ++++++++++++++++++++---------- internal/vm/delete.go | 23 +++++++++++++++++++ 3 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 internal/iptables/iptables.go diff --git a/internal/iptables/iptables.go b/internal/iptables/iptables.go new file mode 100644 index 0000000..1d156a7 --- /dev/null +++ b/internal/iptables/iptables.go @@ -0,0 +1,42 @@ +package iptables + +import ( + "fmt" + "os/exec" +) + +func addRule(args ...string) error { + return exec.Command("iptables", append([]string{"-t", "nat", "-A"}, args...)...).Run() +} + +func deleteRule(args ...string) error { + return exec.Command("iptables", append([]string{"-t", "nat", "-D"}, args...)...).Run() +} + +func AddMetadataRedirect(vmIP, gatewayIP, metadataPort string) error { + if err := addRule("PREROUTING", + "-s", vmIP+"/32", + "-d", "169.254.169.254/32", + "-p", "tcp", "-m", "tcp", + "--dport", "80", + "-j", "DNAT", + "--to-destination", gatewayIP+":"+metadataPort, + ); err != nil { + return fmt.Errorf("iptables metadata redirect: %w", err) + } + return nil +} + +func DeleteMetadataRedirect(vmIP, gatewayIP, metadataPort string) error { + if err := deleteRule("PREROUTING", + "-s", vmIP+"/32", + "-d", "169.254.169.254/32", + "-p", "tcp", "-m", "tcp", + "--dport", "80", + "-j", "DNAT", + "--to-destination", gatewayIP+":"+metadataPort, + ); err != nil { + return fmt.Errorf("iptables delete metadata redirect: %w", err) + } + return nil +} diff --git a/internal/vm/create.go b/internal/vm/create.go index 3fc22af..243a8d6 100644 --- a/internal/vm/create.go +++ b/internal/vm/create.go @@ -4,6 +4,7 @@ import ( "fmt" "strconv" + "git.g3e.fr/syonad/two/internal/iptables" "git.g3e.fr/syonad/two/internal/metadata" "git.g3e.fr/syonad/two/internal/netif" "git.g3e.fr/syonad/two/internal/netns" @@ -41,6 +42,21 @@ func StartVM(db *badger.DB, name string) error { return fmt.Errorf("parse tap_id: %w", err) } + vmIP, err := kv.GetFromDB(db, "vm/"+name+"/ip") + if err != nil { + return fmt.Errorf("get ip: %w", err) + } + + gatewayIP, err := kv.GetFromDB(db, "vm/"+name+"/gateway_ip") + if err != nil { + return fmt.Errorf("get gateway_ip: %w", err) + } + + metadataPort, err := kv.GetFromDB(db, "vm/"+name+"/metadata_port") + if err != nil { + return fmt.Errorf("get metadata_port: %w", err) + } + mac, err := kv.GetFromDB(db, "vm/"+name+"/mac") if err != nil { return fmt.Errorf("get mac: %w", err) @@ -63,16 +79,6 @@ func StartVM(db *badger.DB, name string) error { } cpus, _ := strconv.Atoi(cpusStr) - bindIP, err := kv.GetFromDB(db, "vm/"+name+"/metadata_bind_ip") - if err != nil { - return fmt.Errorf("get metadata_bind_ip: %w", err) - } - - bindPort, err := kv.GetFromDB(db, "vm/"+name+"/metadata_bind_port") - if err != nil { - return fmt.Errorf("get metadata_bind_port: %w", err) - } - password, _ := kv.GetFromDB(db, "vm/"+name+"/password") sshkey, _ := kv.GetFromDB(db, "vm/"+name+"/sshkey") @@ -80,11 +86,17 @@ func StartVM(db *badger.DB, name string) error { return fmt.Errorf("create tap: %w", err) } + if err := netns.Call(vpcName, func() error { + return iptables.AddMetadataRedirect(vmIP, gatewayIP, metadataPort) + }); err != nil { + return fmt.Errorf("add metadata redirect: %w", err) + } + if err := metadata.StartMetadata(metadata.NoCloudConfig{ Name: name, VpcName: vpcName, - BindIP: bindIP, - BindPort: bindPort, + BindIP: gatewayIP, + BindPort: metadataPort, Password: password, SSHKEY: sshkey, }, db, false); err != nil { diff --git a/internal/vm/delete.go b/internal/vm/delete.go index d3f376c..7e89424 100644 --- a/internal/vm/delete.go +++ b/internal/vm/delete.go @@ -6,8 +6,10 @@ import ( "time" configuration "git.g3e.fr/syonad/two/internal/config/agent" + "git.g3e.fr/syonad/two/internal/iptables" "git.g3e.fr/syonad/two/internal/metadata" "git.g3e.fr/syonad/two/internal/netif" + "git.g3e.fr/syonad/two/internal/netns" "git.g3e.fr/syonad/two/internal/qmp" "git.g3e.fr/syonad/two/pkg/db/kv" @@ -37,6 +39,21 @@ func StopVM(db *badger.DB, name string, cfg *configuration.Config) error { return fmt.Errorf("parse tap_id: %w", err) } + vmIP, err := kv.GetFromDB(db, "vm/"+name+"/ip") + if err != nil { + return fmt.Errorf("get ip: %w", err) + } + + gatewayIP, err := kv.GetFromDB(db, "vm/"+name+"/gateway_ip") + if err != nil { + return fmt.Errorf("get gateway_ip: %w", err) + } + + metadataPort, err := kv.GetFromDB(db, "vm/"+name+"/metadata_port") + if err != nil { + return fmt.Errorf("get metadata_port: %w", err) + } + socketPath := fmt.Sprintf("/tmp/%s.qmp-sock", name) if _, err := qmp.Send(socketPath, []string{`{"execute":"system_powerdown"}`}); err != nil { @@ -59,6 +76,12 @@ func StopVM(db *badger.DB, name string, cfg *configuration.Config) error { } } + if err := netns.Call(vpcName, func() error { + return iptables.DeleteMetadataRedirect(vmIP, gatewayIP, metadataPort) + }); err != nil { + return fmt.Errorf("delete metadata redirect: %w", err) + } + if err := metadata.StopMetadata(name, db, false); err != nil { return fmt.Errorf("stop metadata: %w", err) }