mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Gracefully handle missing xfrm modules
If xfrm modules cannot be loaded: - Create netlink.Handle only for ROUTE socket - Reject local join on overlay secure network Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
b39f13f80e
commit
117131c41b
6 changed files with 36 additions and 10 deletions
|
@ -3,6 +3,7 @@ package overlay
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/libnetwork/driverapi"
|
"github.com/docker/libnetwork/driverapi"
|
||||||
|
@ -31,6 +32,12 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return fmt.Errorf("cannot join secure network: encryption keys not present")
|
return fmt.Errorf("cannot join secure network: encryption keys not present")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlh := ns.NlHandle()
|
||||||
|
|
||||||
|
if n.secure && !nlh.SupportsNetlinkFamily(syscall.NETLINK_XFRM) {
|
||||||
|
return fmt.Errorf("cannot join secure network: required modules to install IPSEC rules are missing on host")
|
||||||
|
}
|
||||||
|
|
||||||
s := n.getSubnetforIP(ep.addr)
|
s := n.getSubnetforIP(ep.addr)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return fmt.Errorf("could not find subnet for endpoint %s", eid)
|
return fmt.Errorf("could not find subnet for endpoint %s", eid)
|
||||||
|
@ -65,8 +72,6 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return fmt.Errorf("failed to update overlay endpoint %s to local data store: %v", ep.id[0:7], err)
|
return fmt.Errorf("failed to update overlay endpoint %s to local data store: %v", ep.id[0:7], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nlh := ns.NlHandle()
|
|
||||||
|
|
||||||
// Set the container interface and its peer MTU to 1450 to allow
|
// Set the container interface and its peer MTU to 1450 to allow
|
||||||
// for 50 bytes vxlan encap (inner eth header(14) + outer IP(20) +
|
// for 50 bytes vxlan encap (inner eth header(14) + outer IP(20) +
|
||||||
// outer UDP(8) + vxlan header(8))
|
// outer UDP(8) + vxlan header(8))
|
||||||
|
|
|
@ -284,7 +284,7 @@ func populateVNITbl() {
|
||||||
}
|
}
|
||||||
defer ns.Close()
|
defer ns.Close()
|
||||||
|
|
||||||
nlh, err := netlink.NewHandleAt(ns)
|
nlh, err := netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Could not open netlink handle during vni population for ns %s: %v", path, err)
|
logrus.Errorf("Could not open netlink handle during vni population for ns %s: %v", path, err)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -3,6 +3,7 @@ package overlay
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/libnetwork/netutils"
|
"github.com/docker/libnetwork/netutils"
|
||||||
|
@ -128,7 +129,7 @@ func deleteVxlanByVNI(path string, vni uint32) error {
|
||||||
}
|
}
|
||||||
defer ns.Close()
|
defer ns.Close()
|
||||||
|
|
||||||
nlh, err = netlink.NewHandleAt(ns)
|
nlh, err = netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err)
|
return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package ns
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
@ -24,7 +26,7 @@ func Init() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not get initial namespace: %v", err)
|
log.Errorf("could not get initial namespace: %v", err)
|
||||||
}
|
}
|
||||||
initNl, err = netlink.NewHandle()
|
initNl, err = netlink.NewHandle(getSupportedNlFamilies()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not create netlink handle on initial namespace: %v", err)
|
log.Errorf("could not create netlink handle on initial namespace: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +34,7 @@ func Init() {
|
||||||
|
|
||||||
// SetNamespace sets the initial namespace handler
|
// SetNamespace sets the initial namespace handler
|
||||||
func SetNamespace() error {
|
func SetNamespace() error {
|
||||||
|
initOnce.Do(Init)
|
||||||
if err := netns.Set(initNs); err != nil {
|
if err := netns.Set(initNs); err != nil {
|
||||||
linkInfo, linkErr := getLink()
|
linkInfo, linkErr := getLink()
|
||||||
if linkErr != nil {
|
if linkErr != nil {
|
||||||
|
@ -62,3 +65,22 @@ func NlHandle() *netlink.Handle {
|
||||||
initOnce.Do(Init)
|
initOnce.Do(Init)
|
||||||
return initNl
|
return initNl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSupportedNlFamilies() []int {
|
||||||
|
fams := []int{syscall.NETLINK_ROUTE}
|
||||||
|
if err := loadXfrmModules(); err != nil {
|
||||||
|
log.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
|
||||||
|
return fams
|
||||||
|
}
|
||||||
|
return append(fams, syscall.NETLINK_XFRM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadXfrmModules() error {
|
||||||
|
if out, err := exec.Command("modprobe", "-va", "xfrm_user").CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("Running modprobe xfrm_user failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
||||||
|
}
|
||||||
|
if out, err := exec.Command("modprobe", "-va", "xfrm_algo").CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("Running modprobe xfrm_algo failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ var (
|
||||||
gpmWg sync.WaitGroup
|
gpmWg sync.WaitGroup
|
||||||
gpmCleanupPeriod = 60 * time.Second
|
gpmCleanupPeriod = 60 * time.Second
|
||||||
gpmChan = make(chan chan struct{})
|
gpmChan = make(chan chan struct{})
|
||||||
nsOnce sync.Once
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The networkNamespace type is the linux implementation of the Sandbox
|
// The networkNamespace type is the linux implementation of the Sandbox
|
||||||
|
@ -196,7 +195,7 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) {
|
||||||
}
|
}
|
||||||
defer sboxNs.Close()
|
defer sboxNs.Close()
|
||||||
|
|
||||||
n.nlHandle, err = netlink.NewHandleAt(sboxNs)
|
n.nlHandle, err = netlink.NewHandleAt(sboxNs, syscall.NETLINK_ROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -238,7 +237,7 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
|
||||||
}
|
}
|
||||||
defer sboxNs.Close()
|
defer sboxNs.Close()
|
||||||
|
|
||||||
n.nlHandle, err = netlink.NewHandleAt(sboxNs)
|
n.nlHandle, err = netlink.NewHandleAt(sboxNs, syscall.NETLINK_ROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -326,7 +325,6 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
|
||||||
|
|
||||||
// InitOSContext initializes OS context while configuring network resources
|
// InitOSContext initializes OS context while configuring network resources
|
||||||
func InitOSContext() func() {
|
func InitOSContext() func() {
|
||||||
nsOnce.Do(ns.Init)
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
if err := ns.SetNamespace(); err != nil {
|
if err := ns.SetNamespace(); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
|
|
@ -197,7 +197,7 @@ func TestDisableIPv6DAD(t *testing.T) {
|
||||||
LinkAttrs: netlink.LinkAttrs{Name: "sideA"},
|
LinkAttrs: netlink.LinkAttrs{Name: "sideA"},
|
||||||
PeerName: "sideB",
|
PeerName: "sideB",
|
||||||
}
|
}
|
||||||
nlh, err := netlink.NewHandle()
|
nlh, err := netlink.NewHandle(syscall.NETLINK_ROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue