Skip to content

Commit

Permalink
Merge pull request #162 from jingyuanliang/master
Browse files Browse the repository at this point in the history
Implement --to-ports flag to specify explicit masquerading to-ports
  • Loading branch information
k8s-ci-robot authored Oct 22, 2024
2 parents 342f661 + f9b9b63 commit 93dfa6e
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 8 deletions.
47 changes: 42 additions & 5 deletions cmd/ip-masq-agent/ip-masq-agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import (
"fmt"
"net"
"os"
"strconv"
"strings"
"time"

utilyaml "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/component-base/logs"
"k8s.io/component-base/version/verflag"
"k8s.io/ip-masq-agent/cmd/ip-masq-agent/testing/fakefs"
"k8s.io/ip-masq-agent/pkg/interval"
"k8s.io/ip-masq-agent/pkg/version"
"k8s.io/klog/v2"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
Expand All @@ -46,8 +48,14 @@ const (

var (
// name of nat chain for iptables masquerade rules
masqChain utiliptables.Chain
masqChainFlag = flag.String("masq-chain", "IP-MASQ-AGENT", `Name of nat chain for iptables masquerade rules.`)
masqChain utiliptables.Chain
masqChainFlag = flag.String("masq-chain", "IP-MASQ-AGENT", `Name of nat chain for iptables masquerade rules.`)

// create MASQUERADE iptables rules with --to-ports flag
toPorts interval.Intervals
toPortsProtocols = []string{"tcp", "udp", "sctp"}
toPortsFlag = flag.String("to-ports", "", fmt.Sprintf(`Masquerade to specified ports only, example: "1024-29999,32768-65535"; applicable to %s protocols.`, strings.Join(toPortsProtocols, ", ")))

noMasqueradeAllReservedRangesFlag = flag.Bool("nomasq-all-reserved-ranges", false, "Whether to disable masquerade for all IPv4 ranges reserved by RFCs.")
enableIPv6 = flag.Bool("enable-ipv6", false, "Whether to enable IPv6.")
randomFully = flag.Bool("random-fully", true, "Whether to add --random-fully to the masquerade rule.")
Expand Down Expand Up @@ -139,6 +147,14 @@ func main() {

masqChain = utiliptables.Chain(*masqChainFlag)

if *toPortsFlag != "" {
tp, err := interval.ParseIntervals(*toPortsFlag)
if err != nil {
klog.Exitf("Invalid --to-ports flag %q: %v", *toPortsFlag, err)
}
toPorts = tp
}

c := NewMasqConfig(*noMasqueradeAllReservedRangesFlag)

logs.InitLogs()
Expand Down Expand Up @@ -299,7 +315,7 @@ func (m *MasqDaemon) syncMasqRules() error {
}

// masquerade all other traffic that is not bound for a --dst-type LOCAL destination
writeMasqRule(lines)
writeMasqRules(lines, toPorts)

writeLine(lines, "COMMIT")

Expand Down Expand Up @@ -338,7 +354,7 @@ func (m *MasqDaemon) syncMasqRulesIPv6() error {
}

// masquerade all other traffic that is not bound for a --dst-type LOCAL destination
writeMasqRule(lines6)
writeMasqRules(lines6, toPorts)

writeLine(lines6, "COMMIT")

Expand Down Expand Up @@ -385,14 +401,35 @@ func writeNonMasqRule(lines *bytes.Buffer, cidr string) {

const masqRuleComment = `-m comment --comment "ip-masq-agent: outbound traffic is subject to MASQUERADE (must be last in chain)"`

func writeMasqRule(lines *bytes.Buffer) {
func writeMasqRules(lines *bytes.Buffer, toPorts interval.Intervals) {
args := []string{masqRuleComment, "-j", "MASQUERADE"}
if *randomFully {
args = append(args, "--random-fully")
}

for _, protocol := range toPortsProtocols {
writeMasqToPortsRules(lines, append(args, "-p", protocol), toPorts)
}

writeRule(lines, utiliptables.Append, masqChain, args...)
}

func writeMasqToPortsRules(lines *bytes.Buffer, args []string, toPorts interval.Intervals) {
size := toPorts.Size()

for _, i := range toPorts {
args := args

s := i.Size()
if size != s {
args = append(args, "-m", "statistic", "--mode", "random", "--probability", strconv.FormatFloat(float64(s)/float64(size), 'f', -1, 64))
}
size -= s

writeRule(lines, utiliptables.Append, masqChain, append(args, "--to-ports", i.String())...)
}
}

// Similar syntax to utiliptables.Interface.EnsureRule, except you don't pass a table
// (you must write these rules under the line with the table name)
func writeRule(lines *bytes.Buffer, position utiliptables.RulePosition, chain utiliptables.Chain, args ...string) {
Expand Down
115 changes: 112 additions & 3 deletions cmd/ip-masq-agent/ip-masq-agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"time"

"k8s.io/ip-masq-agent/cmd/ip-masq-agent/testing/fakefs"
"k8s.io/ip-masq-agent/pkg/interval"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
iptest "k8s.io/kubernetes/pkg/util/iptables/testing"
)
Expand All @@ -41,8 +42,8 @@ func TestMain(m *testing.M) {
ec := 0
randomFully := " --random-fully"

for _, tc := range []struct{
arg string
for _, tc := range []struct {
arg string
want string
}{
{
Expand All @@ -52,7 +53,7 @@ func TestMain(m *testing.M) {
arg: "false",
},
{
arg: "true",
arg: "true",
want: randomFully,
},
} {
Expand Down Expand Up @@ -476,6 +477,114 @@ func TestEnsurePostroutingJump(t *testing.T) {
}
}

// tests writeMasqRules
func TestWriteMasqRules(t *testing.T) {
var writeMasqRulesTests = []struct {
desc string
toPorts string
want string
}{
{
desc: "default",
want: string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + "\n",
},
{
desc: "single range",
toPorts: "1024-29999",
want: string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + "\n",
},
{
desc: "double ranges",
toPorts: "1024-29999,32768-65535",
want: string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp -m statistic --mode random --probability 0.469292562840114 --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp --to-ports 32768-65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp -m statistic --mode random --probability 0.469292562840114 --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp --to-ports 32768-65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp -m statistic --mode random --probability 0.469292562840114 --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp --to-ports 32768-65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + "\n",
},
{
desc: "triple ranges",
toPorts: "1024-29999,32768-49151,61000-65535",
want: string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp -m statistic --mode random --probability 0.5807279140612474 --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp -m statistic --mode random --probability 0.7831739961759082 --to-ports 32768-49151\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp --to-ports 61000-65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp -m statistic --mode random --probability 0.5807279140612474 --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp -m statistic --mode random --probability 0.7831739961759082 --to-ports 32768-49151\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp --to-ports 61000-65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp -m statistic --mode random --probability 0.5807279140612474 --to-ports 1024-29999\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp -m statistic --mode random --probability 0.7831739961759082 --to-ports 32768-49151\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp --to-ports 61000-65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + "\n",
},
{
desc: "individual ports",
toPorts: "1024,65535",
want: string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp -m statistic --mode random --probability 0.5 --to-ports 1024\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p tcp --to-ports 65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp -m statistic --mode random --probability 0.5 --to-ports 1024\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p udp --to-ports 65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp -m statistic --mode random --probability 0.5 --to-ports 1024\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + " -p sctp --to-ports 65535\n" +
string(utiliptables.Append) + " " + string(masqChain) + " " + masqRuleComment +
` -j MASQUERADE` + wantRandomFully + "\n",
},
}

for _, tt := range writeMasqRulesTests {
t.Run(tt.desc, func(t *testing.T) {
var toPorts interval.Intervals
if tt.toPorts != "" {
tp, err := interval.ParseIntervals(tt.toPorts)
if err != nil {
t.Fatalf("Invalid --to-ports spec: %q", tt.toPorts)
}
toPorts = tp
}

lines := bytes.NewBuffer(nil)
writeMasqRules(lines, toPorts)

s := lines.String()
if s != tt.want {
t.Errorf("writeMasqRules(lines, %q):\n got: %q\n want: %q", tt.toPorts, s, tt.want)
}
})
}
}

// tests writeNonMasqRule
func TestWriteNonMasqRule(t *testing.T) {
var writeNonMasqRuleTests = []struct {
Expand Down

0 comments on commit 93dfa6e

Please sign in to comment.