Merge pull request #7002 from concourse/issue/6720
containerd: add flag to allow host access
This commit is contained in:
commit
5c2e643d81
|
@ -159,9 +159,9 @@ func (b *GardenBackend) Start() (err error) {
|
|||
return fmt.Errorf("client init: %w", err)
|
||||
}
|
||||
|
||||
err = b.network.SetupRestrictedNetworks()
|
||||
err = b.network.SetupHostNetwork()
|
||||
if err != nil {
|
||||
return fmt.Errorf("setup restricted networks failed: %w", err)
|
||||
return fmt.Errorf("setup host network failed: %w", err)
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
@ -488,7 +488,7 @@ func (s *BackendSuite) TestStartInitsClientAndSetsUpRestrictedNetworks() {
|
|||
err := s.backend.Start()
|
||||
s.NoError(err)
|
||||
s.Equal(1, s.client.InitCallCount())
|
||||
s.Equal(1, s.network.SetupRestrictedNetworksCallCount())
|
||||
s.Equal(1, s.network.SetupHostNetworkCallCount())
|
||||
}
|
||||
|
||||
func (s *BackendSuite) TestStartInitError() {
|
||||
|
|
|
@ -154,12 +154,21 @@ func WithCNIFileStore(f FileStore) CNINetworkOpt {
|
|||
|
||||
// WithRestrictedNetworks defines the network ranges that containers will be restricted
|
||||
// from accessing.
|
||||
//
|
||||
func WithRestrictedNetworks(restrictedNetworks []string) CNINetworkOpt {
|
||||
return func(n *cniNetwork) {
|
||||
n.restrictedNetworks = restrictedNetworks
|
||||
}
|
||||
}
|
||||
|
||||
// WithAllowHostAccess allows containers to talk to the host
|
||||
//
|
||||
func WithAllowHostAccess() CNINetworkOpt {
|
||||
return func(n *cniNetwork) {
|
||||
n.allowHostAccess = true
|
||||
}
|
||||
}
|
||||
|
||||
// WithIptables allows for a custom implementation of the iptables.Iptables interface
|
||||
// to be provided.
|
||||
func WithIptables(ipt iptables.Iptables) CNINetworkOpt {
|
||||
|
@ -175,6 +184,7 @@ type cniNetwork struct {
|
|||
nameServers []string
|
||||
binariesDir string
|
||||
restrictedNetworks []string
|
||||
allowHostAccess bool
|
||||
ipt iptables.Iptables
|
||||
}
|
||||
|
||||
|
@ -225,6 +235,22 @@ func NewCNINetwork(opts ...CNINetworkOpt) (*cniNetwork, error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
func (n cniNetwork) SetupHostNetwork() error {
|
||||
err := n.setupRestrictedNetworks()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !n.allowHostAccess {
|
||||
err = n.restrictHostAccess()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n cniNetwork) SetupMounts(handle string) ([]specs.Mount, error) {
|
||||
if handle == "" {
|
||||
return nil, ErrInvalidInput("empty handle")
|
||||
|
@ -266,22 +292,23 @@ func (n cniNetwork) SetupMounts(handle string) ([]specs.Mount, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (n cniNetwork) SetupRestrictedNetworks() error {
|
||||
const tableName = "filter"
|
||||
err := n.ipt.CreateChainOrFlushIfExists(tableName, ipTablesAdminChainName)
|
||||
const filterTable = "filter"
|
||||
|
||||
func (n cniNetwork) setupRestrictedNetworks() error {
|
||||
err := n.ipt.CreateChainOrFlushIfExists(filterTable, ipTablesAdminChainName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create chain or flush if exists failed: %w", err)
|
||||
}
|
||||
|
||||
// Optimization that allows packets of ESTABLISHED and RELATED connections to go through without further rule matching
|
||||
err = n.ipt.AppendRule(tableName, ipTablesAdminChainName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT")
|
||||
err = n.ipt.AppendRule(filterTable, ipTablesAdminChainName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT")
|
||||
if err != nil {
|
||||
return fmt.Errorf("appending accept rule for RELATED & ESTABLISHED connections failed: %w", err)
|
||||
}
|
||||
|
||||
for _, restrictedNetwork := range n.restrictedNetworks {
|
||||
// Create REJECT rule in admin chain
|
||||
err = n.ipt.AppendRule(tableName, ipTablesAdminChainName, "-d", restrictedNetwork, "-j", "REJECT")
|
||||
err = n.ipt.AppendRule(filterTable, ipTablesAdminChainName, "-d", restrictedNetwork, "-j", "REJECT")
|
||||
if err != nil {
|
||||
return fmt.Errorf("appending reject rule for restricted network %s failed: %w", restrictedNetwork, err)
|
||||
}
|
||||
|
@ -303,6 +330,20 @@ func (n cniNetwork) generateResolvConfContents() ([]byte, error) {
|
|||
return []byte(contents), err
|
||||
}
|
||||
|
||||
func (n cniNetwork) restrictHostAccess() error {
|
||||
err := n.ipt.CreateChainOrFlushIfExists(filterTable, "INPUT")
|
||||
if err != nil {
|
||||
return fmt.Errorf("create chain or flush if exists failed: %w", err)
|
||||
}
|
||||
|
||||
err = n.ipt.AppendRule(filterTable, "INPUT", "-i", n.config.BridgeName, "-j", "REJECT", "--reject-with", "icmp-host-prohibited")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error appending iptables rule: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n cniNetwork) Add(ctx context.Context, task containerd.Task) error {
|
||||
if task == nil {
|
||||
return ErrInvalidInput("nil task")
|
||||
|
|
|
@ -3,6 +3,7 @@ package runtime_test
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/concourse/concourse/worker/runtime"
|
||||
|
@ -139,33 +140,108 @@ func (s *CNINetworkSuite) TestSetupMountsCallsStoreWithoutNameServers() {
|
|||
s.Equal(resolvConfContents, []byte(contents))
|
||||
}
|
||||
|
||||
func (s *CNINetworkSuite) TestSetupRestrictedNetworksCreatesEmptyAdminChain() {
|
||||
network, err := runtime.NewCNINetwork(
|
||||
runtime.WithRestrictedNetworks([]string{"1.1.1.1", "8.8.8.8"}),
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
func (s *CNINetworkSuite) TestSetupHostNetwork() {
|
||||
testCases := map[string]struct {
|
||||
cniNetworkSetup func() (runtime.Network, error)
|
||||
expectedTableName string
|
||||
expectedChainName string
|
||||
expectedRuleSpec []string
|
||||
}{
|
||||
"flushes the CONCOURSE-OPERATOR chain": {
|
||||
cniNetworkSetup: func() (runtime.Network, error) {
|
||||
return runtime.NewCNINetwork(
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
},
|
||||
expectedTableName: "filter",
|
||||
expectedChainName: "CONCOURSE-OPERATOR",
|
||||
},
|
||||
"adds rule to CONCOURSE-OPERATOR chain for accepting established connections": {
|
||||
cniNetworkSetup: func() (runtime.Network, error) {
|
||||
return runtime.NewCNINetwork(
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
},
|
||||
expectedTableName: "filter",
|
||||
expectedChainName: "CONCOURSE-OPERATOR",
|
||||
expectedRuleSpec: []string{"-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"},
|
||||
},
|
||||
"adds rule to CONCOURSE-OPERATOR chain to reject IP 1.1.1.1": {
|
||||
cniNetworkSetup: func() (runtime.Network, error) {
|
||||
return runtime.NewCNINetwork(
|
||||
runtime.WithRestrictedNetworks([]string{"1.1.1.1", "8.8.8.8"}),
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
},
|
||||
expectedTableName: "filter",
|
||||
expectedChainName: "CONCOURSE-OPERATOR",
|
||||
expectedRuleSpec: []string{"-d", "1.1.1.1", "-j", "REJECT"},
|
||||
},
|
||||
"adds rule to CONCOURSE-OPERATOR chain to reject IP 8.8.8.8": {
|
||||
cniNetworkSetup: func() (runtime.Network, error) {
|
||||
return runtime.NewCNINetwork(
|
||||
runtime.WithRestrictedNetworks([]string{"1.1.1.1", "8.8.8.8"}),
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
},
|
||||
expectedTableName: "filter",
|
||||
expectedChainName: "CONCOURSE-OPERATOR",
|
||||
expectedRuleSpec: []string{"-d", "8.8.8.8", "-j", "REJECT"},
|
||||
},
|
||||
"flushes the INPUT chain": {
|
||||
cniNetworkSetup: func() (runtime.Network, error) {
|
||||
return runtime.NewCNINetwork(
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
},
|
||||
expectedTableName: "filter",
|
||||
expectedChainName: "INPUT",
|
||||
},
|
||||
"adds rule to INPUT chain to block host access by default": {
|
||||
cniNetworkSetup: func() (runtime.Network, error) {
|
||||
return runtime.NewCNINetwork(
|
||||
runtime.WithIptables(s.iptables),
|
||||
)
|
||||
},
|
||||
expectedTableName: "filter",
|
||||
expectedChainName: "INPUT",
|
||||
expectedRuleSpec: []string{"-i", "concourse0", "-j", "REJECT", "--reject-with", "icmp-host-prohibited"},
|
||||
},
|
||||
}
|
||||
|
||||
err = network.SetupRestrictedNetworks()
|
||||
s.NoError(err)
|
||||
for description, testCase := range testCases {
|
||||
network, err := testCase.cniNetworkSetup()
|
||||
s.NoError(err)
|
||||
err = network.SetupHostNetwork()
|
||||
s.NoError(err)
|
||||
|
||||
tablename, chainName := s.iptables.CreateChainOrFlushIfExistsArgsForCall(0)
|
||||
s.Equal(tablename, "filter")
|
||||
s.Equal(chainName, "CONCOURSE-OPERATOR")
|
||||
foundExpected := false
|
||||
|
||||
tablename, chainName, rulespec := s.iptables.AppendRuleArgsForCall(0)
|
||||
s.Equal(tablename, "filter")
|
||||
s.Equal(chainName, "CONCOURSE-OPERATOR")
|
||||
s.Equal(rulespec, []string{"-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"})
|
||||
if testCase.expectedRuleSpec == nil {
|
||||
// Test cases to check if correct chain is created
|
||||
numOfCalls := s.iptables.CreateChainOrFlushIfExistsCallCount()
|
||||
for i := 0; i < numOfCalls; i++ {
|
||||
tablename, chainName := s.iptables.CreateChainOrFlushIfExistsArgsForCall(i)
|
||||
if tablename == testCase.expectedTableName && chainName == testCase.expectedChainName {
|
||||
foundExpected = true
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Test cases to check if correct rule is appended
|
||||
numOfCalls := s.iptables.AppendRuleCallCount()
|
||||
for i := 0; i < numOfCalls; i++ {
|
||||
tablename, chainName, rulespec := s.iptables.AppendRuleArgsForCall(i)
|
||||
if tablename == testCase.expectedTableName && chainName == testCase.expectedChainName && reflect.DeepEqual(rulespec, testCase.expectedRuleSpec) {
|
||||
foundExpected = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
tablename, chainName, rulespec = s.iptables.AppendRuleArgsForCall(1)
|
||||
s.Equal(tablename, "filter")
|
||||
s.Equal(chainName, "CONCOURSE-OPERATOR")
|
||||
s.Equal(rulespec, []string{"-d", "1.1.1.1", "-j", "REJECT"})
|
||||
}
|
||||
|
||||
tablename, chainName, rulespec = s.iptables.AppendRuleArgsForCall(2)
|
||||
s.Equal(tablename, "filter")
|
||||
s.Equal(chainName, "CONCOURSE-OPERATOR")
|
||||
s.Equal(rulespec, []string{"-d", "8.8.8.8", "-j", "REJECT"})
|
||||
s.Equal(foundExpected, true, description)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CNINetworkSuite) TestAddNilTask() {
|
||||
|
|
|
@ -4,6 +4,9 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
@ -100,7 +103,7 @@ func (s *IntegrationSuite) TearDownSuite() {
|
|||
s.NoError(os.RemoveAll(s.tmpDir))
|
||||
}
|
||||
|
||||
func (s *IntegrationSuite) SetupTest() {
|
||||
func (s *IntegrationSuite) BeforeTest(suiteName, testName string) {
|
||||
var (
|
||||
err error
|
||||
namespace = "test"
|
||||
|
@ -138,7 +141,7 @@ func (s *IntegrationSuite) setupRootfs() {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *IntegrationSuite) TearDownTest() {
|
||||
func (s *IntegrationSuite) AfterTest(suiteName, testName string) {
|
||||
s.gardenBackend.Stop()
|
||||
os.RemoveAll(s.rootfs)
|
||||
s.cleanupIptables()
|
||||
|
@ -233,6 +236,10 @@ func (s *IntegrationSuite) TestContainerNetworkEgress() {
|
|||
// we have blocked access to.
|
||||
//
|
||||
func (s *IntegrationSuite) TestContainerNetworkEgressWithRestrictedNetworks() {
|
||||
// Using custom backend, clean up BeforeTest() stuff
|
||||
s.gardenBackend.Stop()
|
||||
s.cleanupIptables()
|
||||
|
||||
namespace := "test-restricted-networks"
|
||||
requestTimeout := 3 * time.Second
|
||||
|
||||
|
@ -291,6 +298,142 @@ func (s *IntegrationSuite) TestContainerNetworkEgressWithRestrictedNetworks() {
|
|||
s.Contains(buf.String(), "connect: connection refused")
|
||||
}
|
||||
|
||||
// TestContainerBlocksHostAccess verifies that a process that we run in a
|
||||
// container is not able to reach the host but is able to reach the internet.
|
||||
//
|
||||
func (s *IntegrationSuite) TestContainerBlocksHostAccess() {
|
||||
handle := uuid()
|
||||
container, err := s.gardenBackend.Create(garden.ContainerSpec{
|
||||
Handle: handle,
|
||||
RootFSPath: "raw://" + s.rootfs,
|
||||
Privileged: true,
|
||||
})
|
||||
s.NoError(err)
|
||||
|
||||
defer func() {
|
||||
s.NoError(s.gardenBackend.Destroy(handle))
|
||||
s.gardenBackend.Stop()
|
||||
}()
|
||||
|
||||
hostIp, err := getHostIp()
|
||||
s.NoError(err)
|
||||
|
||||
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Hello, client")
|
||||
}))
|
||||
l, err := net.Listen("tcp", hostIp+":0")
|
||||
ts.Listener = l
|
||||
ts.Start()
|
||||
defer ts.Close()
|
||||
|
||||
buf := new(buffer)
|
||||
proc, err := container.Run(
|
||||
garden.ProcessSpec{
|
||||
Path: "/executable",
|
||||
Args: []string{
|
||||
"-http-get=" + ts.URL,
|
||||
},
|
||||
},
|
||||
garden.ProcessIO{
|
||||
Stdout: buf,
|
||||
Stderr: buf,
|
||||
},
|
||||
)
|
||||
s.NoError(err)
|
||||
|
||||
exitCode, err := proc.Wait()
|
||||
s.NoError(err)
|
||||
s.Equal(exitCode, 1, "Process in container should not be able to connect to host network")
|
||||
|
||||
proc, err = container.Run(
|
||||
garden.ProcessSpec{
|
||||
Path: "/executable",
|
||||
Args: []string{
|
||||
"-http-get=http://1.1.1.1",
|
||||
},
|
||||
},
|
||||
garden.ProcessIO{
|
||||
Stdout: buf,
|
||||
Stderr: buf,
|
||||
},
|
||||
)
|
||||
s.NoError(err)
|
||||
|
||||
exitCode, err = proc.Wait()
|
||||
s.NoError(err)
|
||||
s.Equal(exitCode, 0, "Process in container should also be able to reach the internet")
|
||||
}
|
||||
|
||||
func (s *IntegrationSuite) TestContainerAllowsHostAccess() {
|
||||
// Using custom backend, clean up BeforeTest() stuff
|
||||
s.gardenBackend.Stop()
|
||||
s.cleanupIptables()
|
||||
|
||||
namespace := "test-block-host-access"
|
||||
requestTimeout := 3 * time.Second
|
||||
|
||||
network, err := runtime.NewCNINetwork(runtime.WithAllowHostAccess())
|
||||
|
||||
s.NoError(err)
|
||||
|
||||
networkOpt := runtime.WithNetwork(network)
|
||||
customBackend, err := runtime.NewGardenBackend(
|
||||
libcontainerd.New(
|
||||
s.containerdSocket(),
|
||||
namespace,
|
||||
requestTimeout,
|
||||
),
|
||||
networkOpt,
|
||||
)
|
||||
s.NoError(err)
|
||||
|
||||
s.NoError(customBackend.Start())
|
||||
|
||||
handle := uuid()
|
||||
|
||||
container, err := customBackend.Create(garden.ContainerSpec{
|
||||
Handle: handle,
|
||||
RootFSPath: "raw://" + s.rootfs,
|
||||
Privileged: true,
|
||||
})
|
||||
s.NoError(err)
|
||||
|
||||
defer func() {
|
||||
s.NoError(customBackend.Destroy(handle))
|
||||
customBackend.Stop()
|
||||
}()
|
||||
|
||||
hostIp, err := getHostIp()
|
||||
s.NoError(err)
|
||||
|
||||
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Hello, client")
|
||||
}))
|
||||
l, err := net.Listen("tcp", hostIp+":0")
|
||||
ts.Listener = l
|
||||
ts.Start()
|
||||
defer ts.Close()
|
||||
|
||||
buf := new(buffer)
|
||||
proc, err := container.Run(
|
||||
garden.ProcessSpec{
|
||||
Path: "/executable",
|
||||
Args: []string{
|
||||
"-http-get=" + ts.URL,
|
||||
},
|
||||
},
|
||||
garden.ProcessIO{
|
||||
Stdout: buf,
|
||||
Stderr: buf,
|
||||
},
|
||||
)
|
||||
s.NoError(err)
|
||||
|
||||
exitCode, err := proc.Wait()
|
||||
s.NoError(err)
|
||||
s.Equal(exitCode, 0, "Process in container should be able to reach the host network")
|
||||
}
|
||||
|
||||
// TestRunPrivileged tests whether we're able to run a process in a privileged
|
||||
// container.
|
||||
//
|
||||
|
|
|
@ -53,6 +53,7 @@ func httpGet(url string) {
|
|||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
resp, err := client.Get(url)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os/user"
|
||||
"regexp"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
@ -56,3 +59,28 @@ func TestSuite(t *testing.T) {
|
|||
tmpDir: tmpDir,
|
||||
})
|
||||
}
|
||||
|
||||
func getHostIp() (string, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ethInterface := regexp.MustCompile("eth0")
|
||||
|
||||
for _, i := range ifaces {
|
||||
if ethInterface.MatchString(i.Name) {
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, address := range addrs {
|
||||
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
return ipnet.IP.String(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", errors.New("unable to find host's IP")
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@ import (
|
|||
|
||||
//counterfeiter:generate . Network
|
||||
type Network interface {
|
||||
// SetupHostNetwork sets up networking rules that
|
||||
// affect all containers
|
||||
//
|
||||
SetupHostNetwork() (err error)
|
||||
|
||||
// SetupMounts prepares mounts that might be necessary for proper
|
||||
// networking functionality.
|
||||
//
|
||||
SetupMounts(handle string) (mounts []specs.Mount, err error)
|
||||
|
||||
// SetupRestrictedNetworks sets up networking rules to prevent
|
||||
// container access to specified network ranges
|
||||
//
|
||||
SetupRestrictedNetworks() (err error)
|
||||
|
||||
// Add adds a task to the network.
|
||||
//
|
||||
Add(ctx context.Context, task containerd.Task) (err error)
|
||||
|
|
|
@ -35,6 +35,16 @@ type FakeNetwork struct {
|
|||
removeReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
SetupHostNetworkStub func() error
|
||||
setupHostNetworkMutex sync.RWMutex
|
||||
setupHostNetworkArgsForCall []struct {
|
||||
}
|
||||
setupHostNetworkReturns struct {
|
||||
result1 error
|
||||
}
|
||||
setupHostNetworkReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
SetupMountsStub func(string) ([]specs.Mount, error)
|
||||
setupMountsMutex sync.RWMutex
|
||||
setupMountsArgsForCall []struct {
|
||||
|
@ -48,16 +58,6 @@ type FakeNetwork struct {
|
|||
result1 []specs.Mount
|
||||
result2 error
|
||||
}
|
||||
SetupRestrictedNetworksStub func() error
|
||||
setupRestrictedNetworksMutex sync.RWMutex
|
||||
setupRestrictedNetworksArgsForCall []struct {
|
||||
}
|
||||
setupRestrictedNetworksReturns struct {
|
||||
result1 error
|
||||
}
|
||||
setupRestrictedNetworksReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
@ -186,6 +186,59 @@ func (fake *FakeNetwork) RemoveReturnsOnCall(i int, result1 error) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupHostNetwork() error {
|
||||
fake.setupHostNetworkMutex.Lock()
|
||||
ret, specificReturn := fake.setupHostNetworkReturnsOnCall[len(fake.setupHostNetworkArgsForCall)]
|
||||
fake.setupHostNetworkArgsForCall = append(fake.setupHostNetworkArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.SetupHostNetworkStub
|
||||
fakeReturns := fake.setupHostNetworkReturns
|
||||
fake.recordInvocation("SetupHostNetwork", []interface{}{})
|
||||
fake.setupHostNetworkMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupHostNetworkCallCount() int {
|
||||
fake.setupHostNetworkMutex.RLock()
|
||||
defer fake.setupHostNetworkMutex.RUnlock()
|
||||
return len(fake.setupHostNetworkArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupHostNetworkCalls(stub func() error) {
|
||||
fake.setupHostNetworkMutex.Lock()
|
||||
defer fake.setupHostNetworkMutex.Unlock()
|
||||
fake.SetupHostNetworkStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupHostNetworkReturns(result1 error) {
|
||||
fake.setupHostNetworkMutex.Lock()
|
||||
defer fake.setupHostNetworkMutex.Unlock()
|
||||
fake.SetupHostNetworkStub = nil
|
||||
fake.setupHostNetworkReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupHostNetworkReturnsOnCall(i int, result1 error) {
|
||||
fake.setupHostNetworkMutex.Lock()
|
||||
defer fake.setupHostNetworkMutex.Unlock()
|
||||
fake.SetupHostNetworkStub = nil
|
||||
if fake.setupHostNetworkReturnsOnCall == nil {
|
||||
fake.setupHostNetworkReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.setupHostNetworkReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupMounts(arg1 string) ([]specs.Mount, error) {
|
||||
fake.setupMountsMutex.Lock()
|
||||
ret, specificReturn := fake.setupMountsReturnsOnCall[len(fake.setupMountsArgsForCall)]
|
||||
|
@ -250,59 +303,6 @@ func (fake *FakeNetwork) SetupMountsReturnsOnCall(i int, result1 []specs.Mount,
|
|||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupRestrictedNetworks() error {
|
||||
fake.setupRestrictedNetworksMutex.Lock()
|
||||
ret, specificReturn := fake.setupRestrictedNetworksReturnsOnCall[len(fake.setupRestrictedNetworksArgsForCall)]
|
||||
fake.setupRestrictedNetworksArgsForCall = append(fake.setupRestrictedNetworksArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.SetupRestrictedNetworksStub
|
||||
fakeReturns := fake.setupRestrictedNetworksReturns
|
||||
fake.recordInvocation("SetupRestrictedNetworks", []interface{}{})
|
||||
fake.setupRestrictedNetworksMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupRestrictedNetworksCallCount() int {
|
||||
fake.setupRestrictedNetworksMutex.RLock()
|
||||
defer fake.setupRestrictedNetworksMutex.RUnlock()
|
||||
return len(fake.setupRestrictedNetworksArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupRestrictedNetworksCalls(stub func() error) {
|
||||
fake.setupRestrictedNetworksMutex.Lock()
|
||||
defer fake.setupRestrictedNetworksMutex.Unlock()
|
||||
fake.SetupRestrictedNetworksStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupRestrictedNetworksReturns(result1 error) {
|
||||
fake.setupRestrictedNetworksMutex.Lock()
|
||||
defer fake.setupRestrictedNetworksMutex.Unlock()
|
||||
fake.SetupRestrictedNetworksStub = nil
|
||||
fake.setupRestrictedNetworksReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) SetupRestrictedNetworksReturnsOnCall(i int, result1 error) {
|
||||
fake.setupRestrictedNetworksMutex.Lock()
|
||||
defer fake.setupRestrictedNetworksMutex.Unlock()
|
||||
fake.SetupRestrictedNetworksStub = nil
|
||||
if fake.setupRestrictedNetworksReturnsOnCall == nil {
|
||||
fake.setupRestrictedNetworksReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.setupRestrictedNetworksReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNetwork) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
|
@ -310,10 +310,10 @@ func (fake *FakeNetwork) Invocations() map[string][][]interface{} {
|
|||
defer fake.addMutex.RUnlock()
|
||||
fake.removeMutex.RLock()
|
||||
defer fake.removeMutex.RUnlock()
|
||||
fake.setupHostNetworkMutex.RLock()
|
||||
defer fake.setupHostNetworkMutex.RUnlock()
|
||||
fake.setupMountsMutex.RLock()
|
||||
defer fake.setupMountsMutex.RUnlock()
|
||||
fake.setupRestrictedNetworksMutex.RLock()
|
||||
defer fake.setupRestrictedNetworksMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
|
|
|
@ -70,6 +70,11 @@ func (cmd *WorkerCommand) containerdGardenServerRunner(
|
|||
networkOpts = append(networkOpts, runtime.WithRestrictedNetworks(cmd.Containerd.Network.RestrictedNetworks))
|
||||
}
|
||||
|
||||
// DNS proxy won't work without allowing access to host network
|
||||
if cmd.Containerd.Network.AllowHostAccess || cmd.Containerd.Network.DNS.Enable {
|
||||
networkOpts = append(networkOpts, runtime.WithAllowHostAccess())
|
||||
}
|
||||
|
||||
networkConfig := runtime.DefaultCNINetworkConfig
|
||||
if cmd.Containerd.Network.Pool != "" {
|
||||
networkConfig.Subnet = cmd.Containerd.Network.Pool
|
||||
|
|
|
@ -52,13 +52,14 @@ type ContainerdRuntime struct {
|
|||
RestrictedNetworks []string `long:"restricted-network" description:"Network ranges to which traffic from containers will be restricted. Can be specified multiple times."`
|
||||
Pool string `long:"network-pool" default:"10.80.0.0/16" description:"Network range to use for dynamically allocated container subnets."`
|
||||
MTU int `long:"mtu" description:"MTU size for container network interfaces. Defaults to the MTU of the interface used for outbound access by the host."`
|
||||
AllowHostAccess bool `long:"allow-host-access" description:"Allow containers to reach the host's network. This is turned off by default."`
|
||||
} `group:"Container Networking"`
|
||||
|
||||
MaxContainers int `long:"max-containers" default:"250" description:"Max container capacity. 0 means no limit."`
|
||||
}
|
||||
|
||||
type DNSConfig struct {
|
||||
Enable bool `long:"enable" description:"Enable proxy DNS server."`
|
||||
Enable bool `long:"enable" description:"Enable proxy DNS server. Note: this will enable containers to access the host network."`
|
||||
}
|
||||
|
||||
const containerdRuntime = "containerd"
|
||||
|
|
Loading…
Reference in New Issue