89 lines
1.7 KiB
Go
Raw Normal View History

2024-09-06 14:24:55 +03:00
package netfilterHelper
import (
"fmt"
"github.com/coreos/go-iptables/iptables"
"strconv"
)
type PortRemap struct {
IPTables *iptables.IPTables
ChainName string
From uint16
To uint16
Enabled bool
}
2024-09-06 16:50:56 +03:00
func (r *PortRemap) PutIPTable(table string) error {
if table == "all" || table == "nat" {
err := r.IPTables.ClearChain("nat", r.ChainName)
if err != nil {
return fmt.Errorf("failed to clear chain: %w", err)
}
2024-09-06 14:24:55 +03:00
2024-10-22 01:52:31 +03:00
// TODO: Add `-d <IP>`
err = r.IPTables.AppendUnique("nat", r.ChainName, "-p", "udp", "--dport", strconv.Itoa(int(r.From)), "-j", "DNAT", "--to-destination", fmt.Sprintf(":%d", r.To))
2024-09-06 16:50:56 +03:00
if err != nil {
return fmt.Errorf("failed to create rule: %w", err)
}
err = r.IPTables.InsertUnique("nat", "PREROUTING", 1, "-j", r.ChainName)
if err != nil {
return fmt.Errorf("failed to linking chain: %w", err)
}
2024-09-06 14:24:55 +03:00
}
2024-09-06 16:50:56 +03:00
return nil
}
func (r *PortRemap) ForceEnable() error {
err := r.PutIPTable("all")
2024-09-06 14:24:55 +03:00
if err != nil {
2024-09-06 16:50:56 +03:00
return err
2024-09-06 14:24:55 +03:00
}
r.Enabled = true
return nil
}
func (r *PortRemap) Disable() []error {
var errs []error
err := r.IPTables.DeleteIfExists("nat", "PREROUTING", "-j", r.ChainName)
if err != nil {
errs = append(errs, fmt.Errorf("failed to unlinking chain: %w", err))
}
err = r.IPTables.ClearAndDeleteChain("nat", r.ChainName)
if err != nil {
errs = append(errs, fmt.Errorf("failed to delete chain: %w", err))
}
r.Enabled = false
return errs
}
func (r *PortRemap) Enable() error {
if r.Enabled {
return nil
}
err := r.ForceEnable()
if err != nil {
r.Disable()
return err
}
return nil
}
func (nh *NetfilterHelper) PortRemap(name string, from, to uint16) *PortRemap {
return &PortRemap{
IPTables: nh.IPTables,
ChainName: name,
From: from,
To: to,
}
}