pasta: add new --map-guest-addr option

The --map-guest-addr option allows us to sepcify a ip that is remapped
to the actual host ip that was used by pasta. This is done to fix the
problem where connecting to the host ip was not possible as the same ip
was used in the netns.

We now set --map-guest-addr 169.254.1.2 which follows the same idea we
already used for the --dns-forward option. With that podman can use this
ip to set it for host.containers.internal which should the case where
there was no second host ip available, see
https://github.com/containers/podman/issues/19213

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-08-26 14:45:32 +02:00
parent 12e36c11c1
commit 374514285f
3 changed files with 131 additions and 37 deletions

View File

@ -26,11 +26,16 @@ import (
)
const (
dnsForwardOpt = "--dns-forward"
dnsForwardOpt = "--dns-forward"
mapGuestAddrOpt = "--map-guest-addr"
// dnsForwardIpv4 static ip used as nameserver address inside the netns,
// given this is a "link local" ip it should be very unlikely that it causes conflicts
dnsForwardIpv4 = "169.254.1.1"
// mapGuestAddrIpv4 static ip used as forwarder address inside the netns to reach the host,
// given this is a "link local" ip it should be very unlikely that it causes conflicts
mapGuestAddrIpv4 = "169.254.1.2"
)
type SetupOptions struct {
@ -60,7 +65,7 @@ func Setup2(opts *SetupOptions) (*SetupResult, error) {
return nil, fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err)
}
cmdArgs, dnsForwardIPs, err := createPastaArgs(opts)
cmdArgs, dnsForwardIPs, mapGuestAddrIPs, err := createPastaArgs(opts)
if err != nil {
return nil, err
}
@ -112,19 +117,27 @@ func Setup2(opts *SetupOptions) (*SetupResult, error) {
}
result.IPv6 = ipv6
for _, ip := range dnsForwardIPs {
ipp := net.ParseIP(ip)
// add the namesever ip only if the address family matches
if ipv4 && util.IsIPv4(ipp) || ipv6 && util.IsIPv6(ipp) {
result.DNSForwardIPs = append(result.DNSForwardIPs, ip)
}
}
result.DNSForwardIPs = filterIpFamily(dnsForwardIPs, ipv4, ipv6)
result.MapGuestAddrIPs = filterIpFamily(mapGuestAddrIPs, ipv4, ipv6)
return result, nil
}
// createPastaArgs creates the pasta arguments, it returns the args to be passed to pasta(1) and as second arg the dns forward ips used.
func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
func filterIpFamily(ips []string, ipv4, ipv6 bool) []string {
var result []string
for _, ip := range ips {
ipp := net.ParseIP(ip)
// add the ip only if the address family matches
if ipv4 && util.IsIPv4(ipp) || ipv6 && util.IsIPv6(ipp) {
result = append(result, ip)
}
}
return result
}
// createPastaArgs creates the pasta arguments, it returns the args to be passed to pasta(1)
// and as second arg the dns forward ips used. As third arg the map guest addr ips used.
func createPastaArgs(opts *SetupOptions) ([]string, []string, []string, error) {
noTCPInitPorts := true
noUDPInitPorts := true
noTCPNamespacePorts := true
@ -149,6 +162,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
})
var dnsForwardIPs []string
var mapGuestAddrIPs []string
for i, opt := range cmdArgs {
switch opt {
case "-t", "--tcp-ports":
@ -166,6 +180,10 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
if len(cmdArgs) > i+1 {
dnsForwardIPs = append(dnsForwardIPs, cmdArgs[i+1])
}
case mapGuestAddrOpt:
if len(cmdArgs) > i+1 {
mapGuestAddrIPs = append(mapGuestAddrIPs, cmdArgs[i+1])
}
}
}
@ -186,7 +204,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
noUDPInitPorts = false
cmdArgs = append(cmdArgs, "-u")
default:
return nil, nil, fmt.Errorf("can't forward protocol: %s", protocol)
return nil, nil, nil, fmt.Errorf("can't forward protocol: %s", protocol)
}
arg := fmt.Sprintf("%s%d-%d:%d-%d", addr,
@ -226,5 +244,13 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
cmdArgs = append(cmdArgs, "--netns", opts.Netns)
return cmdArgs, dnsForwardIPs, nil
// do this as last arg
if len(mapGuestAddrIPs) == 0 {
// the user did not request custom --map-guest-addr so add our own so that we can use this
// for our own host.containers.internal host entry.
cmdArgs = append(cmdArgs, mapGuestAddrOpt, mapGuestAddrIpv4)
mapGuestAddrIPs = append(mapGuestAddrIPs, mapGuestAddrIpv4)
}
return cmdArgs, dnsForwardIPs, mapGuestAddrIPs, nil
}

View File

@ -20,11 +20,12 @@ func makeSetupOptions(configArgs, extraArgs []string, ports []types.PortMapping)
func Test_createPastaArgs(t *testing.T) {
tests := []struct {
name string
input *SetupOptions
wantArgs []string
wantDnsForward []string
wantErr string
name string
input *SetupOptions
wantArgs []string
wantDnsForward []string
wantMapGuestAddr []string
wantErr string
}{
{
name: "default options",
@ -36,8 +37,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", dnsForwardIpv4, "-t", "none", "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "basic port",
@ -49,8 +52,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:80-80", "--dns-forward", dnsForwardIpv4, "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "port range",
@ -62,8 +67,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-82:80-82", "--dns-forward", dnsForwardIpv4, "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "different host and container port",
@ -75,8 +82,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:60-60", "--dns-forward", dnsForwardIpv4, "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "tcp and udp port",
@ -91,8 +100,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:60-60", "-u", "100-100:100-100", "--dns-forward",
dnsForwardIpv4, "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "two tcp ports",
@ -107,8 +118,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:60-60", "-t", "100-100:100-100", "--dns-forward",
dnsForwardIpv4, "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "invalid port",
@ -131,8 +144,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-i", "eth0", "-n", "24", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "config options before extra options",
@ -144,8 +159,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-i", "eth0", "-n", "24", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "-T option",
@ -157,8 +174,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--tcp-ns option",
@ -170,8 +189,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--tcp-ns", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--map-gw option",
@ -183,8 +204,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", dnsForwardIpv4, "-t", "none",
"-u", "none", "-T", "none", "-U", "none", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
// https://github.com/containers/podman/issues/22477
@ -196,8 +219,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "two --map-gw",
@ -209,8 +234,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--dns-forward option",
@ -222,8 +249,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", "192.168.255.255", "-t", "none",
"-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{"192.168.255.255"},
wantDnsForward: []string{"192.168.255.255"},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "two --dns-forward options",
@ -235,8 +264,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", "192.168.255.255", "--dns-forward", "::1", "-t", "none",
"-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{"192.168.255.255", "::1"},
wantDnsForward: []string{"192.168.255.255", "::1"},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "port and custom opt",
@ -248,8 +279,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-i", "eth0", "-t", "80-80:80-80", "--dns-forward", dnsForwardIpv4,
"-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "Add verbose logging",
@ -261,14 +294,45 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--log-file=/tmp/log", "--trace", "--debug",
"--dns-forward", dnsForwardIpv4, "-t", "none", "-u", "none", "-T", "none", "-U", "none",
"--no-map-gw", "--netns", "netns123",
"--no-map-gw", "--netns", "netns123", mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--map-guest-addr option",
input: makeSetupOptions(
nil,
[]string{mapGuestAddrOpt, "192.168.255.255"},
nil,
),
wantArgs: []string{
"--config-net", mapGuestAddrOpt, "192.168.255.255", dnsForwardOpt, dnsForwardIpv4,
"-t", "none", "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet",
"--netns", "netns123",
},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{"192.168.255.255"},
},
{
name: "two --map-guest-addr options",
input: makeSetupOptions(
nil,
[]string{mapGuestAddrOpt, "192.168.255.255", mapGuestAddrOpt, "::1"},
nil,
),
wantArgs: []string{
"--config-net", mapGuestAddrOpt, "192.168.255.255", mapGuestAddrOpt, "::1",
dnsForwardOpt, dnsForwardIpv4, "-t", "none", "-u", "none", "-T", "none",
"-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{"192.168.255.255", "::1"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
args, dnsForward, err := createPastaArgs(tt.input)
args, dnsForward, mapGuestAddr, err := createPastaArgs(tt.input)
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr, "createPastaArgs error")
return
@ -276,6 +340,7 @@ func Test_createPastaArgs(t *testing.T) {
assert.NoError(t, err, "expect no createPastaArgs error")
assert.Equal(t, tt.wantArgs, args, "check arguments")
assert.Equal(t, tt.wantDnsForward, dnsForward, "check dns forward")
assert.Equal(t, tt.wantMapGuestAddr, mapGuestAddr, "check map guest addr")
})
}
}

View File

@ -10,6 +10,9 @@ type SetupResult struct {
// DNSForwardIP is the ip used in --dns-forward, it should be added as first
// entry to resolv.conf in the container.
DNSForwardIPs []string
// MapGuestIps are the ips used for the --map-guest-addr option which
// we can use for the host.containers.internal entry.
MapGuestAddrIPs []string
// IPv6 says whenever pasta run with ipv6 support
IPv6 bool
}