61 lines
1.3 KiB
Go
61 lines
1.3 KiB
Go
package nat
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
)
|
|
|
|
// Config holds NAT masquerade settings per interface.
|
|
type Config struct {
|
|
Interfaces []string `json:"interfaces"`
|
|
}
|
|
|
|
func configPath() string {
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
return filepath.Join("configs", "nat.json")
|
|
}
|
|
return filepath.Join(filepath.Dir(exe), "configs", "nat.json")
|
|
}
|
|
|
|
// IsInstalled reports whether the nft (nftables) binary is available.
|
|
func IsInstalled() bool {
|
|
_, err := exec.LookPath("nft")
|
|
return err == nil
|
|
}
|
|
|
|
// Load reads the NAT config from disk.
|
|
func Load() (*Config, error) {
|
|
data, err := os.ReadFile(configPath())
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return &Config{Interfaces: []string{}}, nil
|
|
}
|
|
return nil, fmt.Errorf("read nat config: %w", err)
|
|
}
|
|
var cfg Config
|
|
if err := json.Unmarshal(data, &cfg); err != nil {
|
|
return nil, fmt.Errorf("parse nat config: %w", err)
|
|
}
|
|
if cfg.Interfaces == nil {
|
|
cfg.Interfaces = []string{}
|
|
}
|
|
return &cfg, nil
|
|
}
|
|
|
|
// Save writes the NAT config to the configs/ directory.
|
|
func Save(cfg *Config) error {
|
|
p := configPath()
|
|
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
|
|
return fmt.Errorf("mkdir configs: %w", err)
|
|
}
|
|
data, err := json.MarshalIndent(cfg, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(p, data, 0644)
|
|
}
|