Pārlūkot izejas kodu

Revert changes to dockerfiles.

amd64 standalone docker image with ipsec

 * Removed the build of strongswan compeletey. Even alpine linux has it
build already.
 * We package docker with strongswan as a separate image.

Switch back to setting charon executable path from cli

 * DRYer
 * Correct stop if hadn't finished init sequence.
Max Kutsevol 7 gadi atpakaļ
vecāks
revīzija
a87573a4f2
5 mainītis faili ar 108 papildinājumiem un 64 dzēšanām
  1. 14 0
      Dockerfile.ipsec.amd64
  2. 60 47
      backend/ipsec/handle_charon.go
  3. 3 1
      backend/ipsec/ipsec.go
  4. 25 15
      backend/ipsec/ipsec_network.go
  5. 6 1
      main.go

+ 14 - 0
Dockerfile.ipsec.amd64

@@ -0,0 +1,14 @@
+FROM frolvlad/alpine-glibc
+
+MAINTAINER Tom Denham <tom@tigera.io>
+
+ENV FLANNEL_ARCH=amd64
+
+RUN apk update && apk add --no-cache iproute2 net-tools ca-certificates strongswan && \
+	update-ca-certificates
+
+COPY dist/flanneld-$FLANNEL_ARCH /opt/bin/flanneld
+COPY dist/iptables-$FLANNEL_ARCH /usr/local/bin/iptables
+COPY dist/mk-docker-opts.sh /opt/bin/
+
+ENTRYPOINT ["/opt/bin/flanneld"]

+ 60 - 47
backend/ipsec/handle_charon.go

@@ -29,11 +29,7 @@ import (
 	"time"
 )
 
-const (
-	charonExecutablePath = "/opt/strongswan/libexec/ipsec/charon"
-)
-
-var defaultViciUri = Uri{"unix", "/var/run/charon.vici"}
+const defaultViciUri = "unix:///var/run/charon.vici"
 
 type Uri struct {
 	network, address string
@@ -42,52 +38,73 @@ type Uri struct {
 type CharonIKEDaemon struct {
 	viciUri     Uri
 	espProposal string
+	ctx         context.Context
 }
 
-func NewCharonIKEDaemon(ctx context.Context, wg sync.WaitGroup, charonViciUri string,
-	espProposal string) (*CharonIKEDaemon, error) {
+func NewCharonIKEDaemon(ctx context.Context, wg sync.WaitGroup, charonExecutablePath string,
+	charonViciUri string, espProposal string) (*CharonIKEDaemon, error) {
+
+	charon := &CharonIKEDaemon{ctx: ctx, espProposal: espProposal}
 
-	charon := &CharonIKEDaemon{viciUri: defaultViciUri, espProposal: espProposal}
-	log.Infof("Using ESP proposal: %s", espProposal)
 	if charonViciUri == "" {
-		cmd, err := charon.runBundled()
+		charonViciUri = defaultViciUri
+	}
+
+	log.Infof("Using charon at: %s", charonViciUri)
+	addr := strings.Split(charonViciUri, "://")
+	charon.viciUri = Uri{addr[0], addr[1]}
+
+	log.Infof("Using ESP proposal: %s", espProposal)
+	if charonExecutablePath != "" {
+		cmd, err := charon.runBundled(charonExecutablePath)
 
 		if err != nil {
-			log.Errorf("Error starting bundled charon daemon: %v", err)
+			log.Errorf("Error starting charon daemon: %v", err)
 			return nil, err
 		} else {
-			log.Info("Bundled charon daemon started")
+			log.Info("Charon daemon started")
 		}
 		wg.Add(1)
 		go func() {
 			select {
 			case <-ctx.Done():
 				cmd.Process.Signal(syscall.SIGTERM)
-				log.Infof("Stopped bundled charon daemon")
+				log.Infof("Stopped charon daemon")
 				wg.Done()
 				return
 			}
 		}()
-	} else {
-		log.Infof("Using external charon at: %s", charonViciUri)
-		addr := strings.Split(charonViciUri, "://")
-		charon.viciUri = Uri{addr[0], addr[1]}
 	}
-
 	return charon, nil
 }
 
-func (charon *CharonIKEDaemon) getClient() (
+func (charon *CharonIKEDaemon) getClient(wait bool) (
 	client *goStrongswanVici.ClientConn, err error) {
-	conn, err := net.Dial(charon.viciUri.network, charon.viciUri.address)
-	if err != nil {
-		return
+	for {
+		socket_conn, err := net.Dial(charon.viciUri.network, charon.viciUri.address)
+		if err == nil {
+			return goStrongswanVici.NewClientConn(socket_conn), nil
+		} else {
+			if wait {
+				select {
+				case <-charon.ctx.Done():
+					log.Error("Cancel waiting for charon")
+					return nil, err
+				default:
+					log.Errorf("ClientConnection failed: %v", err)
+				}
+
+				log.Info("Retrying in a second ...")
+				time.Sleep(time.Second)
+			} else {
+				return nil, err
+			}
+		}
 	}
-	return goStrongswanVici.NewClientConn(conn), nil
 }
 
-func (charon *CharonIKEDaemon) runBundled() (cmd *exec.Cmd, err error) {
-	path, err := exec.LookPath(charonExecutablePath)
+func (charon *CharonIKEDaemon) runBundled(execPath string) (cmd *exec.Cmd, err error) {
+	path, err := exec.LookPath(execPath)
 	if err != nil {
 		return nil, err
 	}
@@ -106,15 +123,10 @@ func (charon *CharonIKEDaemon) LoadSharedKey(remotePublicIP, password string) er
 	var err error
 	var client *goStrongswanVici.ClientConn
 
-	for {
-		client, err = charon.getClient()
-		if err == nil {
-			break
-		} else {
-			log.Error("ClientConnection failed: ", err)
-			log.Info("Retrying in 1 second ...")
-			time.Sleep(1 * time.Second)
-		}
+	client, err = charon.getClient(true)
+	if err != nil {
+		log.Errorf("Failed to acquire Vici client: %v", err)
+		return err
 	}
 
 	defer client.Close()
@@ -125,9 +137,14 @@ func (charon *CharonIKEDaemon) LoadSharedKey(remotePublicIP, password string) er
 		Owners: []string{remotePublicIP},
 	}
 
-	err = client.LoadShared(sharedKey)
-	if err != nil {
-		return err
+	for {
+		err = client.LoadShared(sharedKey)
+		if err != nil {
+			log.Errorf("Failed to load my key. Retrying. %v", err)
+			time.Sleep(time.Second)
+		} else {
+			break
+		}
 	}
 
 	log.Infof("Loaded shared key for: %v", remotePublicIP)
@@ -139,15 +156,10 @@ func (charon *CharonIKEDaemon) LoadConnection(localLease, remoteLease *subnet.Le
 	var err error
 	var client *goStrongswanVici.ClientConn
 
-	for {
-		client, err = charon.getClient()
-		if err == nil {
-			break
-		} else {
-			log.Info("ClientConnection failed: ", err)
-			log.Infof("Retying in 1 second ...")
-			time.Sleep(1 * time.Second)
-		}
+	client, err = charon.getClient(true)
+	if err != nil {
+		log.Errorf("Failed to acquire Vici client: %s", err)
+		return err
 	}
 	defer client.Close()
 
@@ -202,8 +214,9 @@ func (charon *CharonIKEDaemon) LoadConnection(localLease, remoteLease *subnet.Le
 
 func (charon *CharonIKEDaemon) UnloadCharonConnection(localLease,
 	remoteLease *subnet.Lease) error {
-	client, err := charon.getClient()
+	client, err := charon.getClient(false)
 	if err != nil {
+		log.Errorf("Failed to acquire Vici client: %s", err)
 		return err
 	}
 	defer client.Close()

+ 3 - 1
backend/ipsec/ipsec.go

@@ -26,6 +26,7 @@ import (
 	"github.com/coreos/flannel/subnet"
 )
 
+var CharonExecutablePath string
 var CharonViciUri string
 
 const (
@@ -94,7 +95,8 @@ func (be *IPSECBackend) RegisterNetwork(
 		return nil, fmt.Errorf("failed to acquire lease: %v", err)
 	}
 
-	ikeDaemon, err := NewCharonIKEDaemon(ctx, wg, CharonViciUri, cfg.ESPProposal)
+	ikeDaemon, err := NewCharonIKEDaemon(ctx, wg, CharonExecutablePath, CharonViciUri,
+		cfg.ESPProposal)
 	if err != nil {
 		return nil, fmt.Errorf("error creating CharonIKEDaemon struct: %v", err)
 	}

+ 25 - 15
backend/ipsec/ipsec_network.go

@@ -71,6 +71,13 @@ func newNetwork(sm subnet.Manager, extIface *backend.ExternalInterface,
 }
 
 func (n *network) Run(ctx context.Context) {
+
+	err := n.iked.LoadSharedKey(n.SimpleNetwork.SubnetLease.Attrs.PublicIP.ToIP().String(), n.password)
+	if err != nil {
+		log.Errorf("Failed to load PSK: %v", err)
+		return
+	}
+
 	wg := sync.WaitGroup{}
 	defer wg.Wait()
 
@@ -85,15 +92,6 @@ func (n *network) Run(ctx context.Context) {
 		wg.Done()
 	}()
 
-	for {
-		err := n.iked.LoadSharedKey(n.SimpleNetwork.SubnetLease.Attrs.PublicIP.ToIP().String(), n.password)
-		if err == nil {
-			break
-		}
-		log.Error(err, " Failed to load my key. Retrying")
-		time.Sleep(time.Second)
-	}
-
 	initialEvtsBatch := <-evts
 	for {
 		err := n.handleInitialSubnetEvents(initialEvtsBatch)
@@ -134,12 +132,16 @@ func (n *network) handleInitialSubnetEvents(batch []subnet.Event) error {
 		}
 
 		for j, policy := range installedPolicies {
-			if (policy.Src.String() == n.SubnetLease.Subnet.ToIPNet().String()) && (policy.Dst.String() == evt.Lease.Subnet.ToIPNet().String()) {
+			if (policy.Src.String() == n.SubnetLease.Subnet.ToIPNet().String()) &&
+				(policy.Dst.String() == evt.Lease.Subnet.ToIPNet().String()) {
+
 				if policy.Dir != netlink.XFRM_DIR_OUT {
 					continue
 				}
 
-				if (policy.Tmpls[0].Src.Equal(n.SubnetLease.Attrs.PublicIP.ToIP())) && (policy.Tmpls[0].Dst.Equal(evt.Lease.Attrs.PublicIP.ToIP())) {
+				if (policy.Tmpls[0].Src.Equal(n.SubnetLease.Attrs.PublicIP.ToIP())) &&
+					(policy.Tmpls[0].Dst.Equal(evt.Lease.Attrs.PublicIP.ToIP())) {
+
 					evtMarker[k] = true
 					policyMarker[j] = true
 				}
@@ -160,7 +162,9 @@ func (n *network) handleInitialSubnetEvents(batch []subnet.Event) error {
 			log.Errorf("error loading initial shared key: %v", err)
 		}
 
-		if err := n.iked.LoadConnection(n.SubnetLease, &evt.Lease, strconv.Itoa(defaultReqID), strconv.FormatBool(n.UDPEncap)); err != nil {
+		if err := n.iked.LoadConnection(n.SubnetLease, &evt.Lease, strconv.Itoa(defaultReqID),
+			strconv.FormatBool(n.UDPEncap)); err != nil {
+
 			log.Errorf("error loading initial connection into IKE daemon: %v", err)
 		}
 	}
@@ -171,7 +175,10 @@ func (n *network) handleInitialSubnetEvents(batch []subnet.Event) error {
 				continue
 			}
 
-			if err := n.DeleteIPSECPolicies(installedPolicies[j].Src, installedPolicies[j].Dst, installedPolicies[j].Tmpls[0].Src, installedPolicies[j].Tmpls[0].Dst, installedPolicies[j].Tmpls[0].Reqid); err != nil {
+			if err := n.DeleteIPSECPolicies(installedPolicies[j].Src, installedPolicies[j].Dst,
+				installedPolicies[j].Tmpls[0].Src, installedPolicies[j].Tmpls[0].Dst,
+				installedPolicies[j].Tmpls[0].Reqid); err != nil {
+
 				log.Errorf("error deleting installed policy")
 			}
 		}
@@ -204,7 +211,8 @@ func (n *network) handleSubnetEvents(batch []subnet.Event) {
 				log.Errorf("error loading shared key into IKE daemon: %v", err)
 			}
 
-			if err := n.iked.LoadConnection(n.SubnetLease, &evt.Lease, strconv.Itoa(defaultReqID), strconv.FormatBool(n.UDPEncap)); err != nil {
+			if err := n.iked.LoadConnection(n.SubnetLease, &evt.Lease, strconv.Itoa(defaultReqID),
+				strconv.FormatBool(n.UDPEncap)); err != nil {
 				log.Errorf("error loading connection into IKE daemon: %v", err)
 			}
 
@@ -224,7 +232,9 @@ func (n *network) handleSubnetEvents(batch []subnet.Event) {
 				log.Errorf("error unloading charon connections: %v", err)
 			}
 
-			if err := n.DeleteIPSECPolicies(n.SubnetLease.Subnet.ToIPNet(), evt.Lease.Subnet.ToIPNet(), n.SubnetLease.Attrs.PublicIP.ToIP(), evt.Lease.Attrs.PublicIP.ToIP(), defaultReqID); err != nil {
+			if err := n.DeleteIPSECPolicies(n.SubnetLease.Subnet.ToIPNet(), evt.Lease.Subnet.ToIPNet(),
+				n.SubnetLease.Attrs.PublicIP.ToIP(), evt.Lease.Attrs.PublicIP.ToIP(), defaultReqID); err != nil {
+
 				log.Errorf("error deleting ipsec policies: %v", err)
 			}
 		}

+ 6 - 1
main.go

@@ -93,6 +93,7 @@ type CmdLineOpts struct {
 	subnetLeaseRenewMargin int
 	healthzIP              string
 	healthzPort            int
+	charonExecutablePath   string
 	charonViciUri          string
 }
 
@@ -123,7 +124,8 @@ func init() {
 	flannelFlags.BoolVar(&opts.version, "version", false, "print version and exit")
 	flannelFlags.StringVar(&opts.healthzIP, "healthz-ip", "0.0.0.0", "the IP address for healthz server to listen")
 	flannelFlags.IntVar(&opts.healthzPort, "healthz-port", 0, "the port for healthz server to listen(0 to disable)")
-	flannelFlags.StringVar(&opts.charonViciUri, "vici-uri", "", "Charon vici URI (default: launch a bundled one)")
+	flannelFlags.StringVar(&opts.charonExecutablePath, "charon-exec-path", "", "Path to charon executable. Setting it will make flannel attempt to start charon.")
+	flannelFlags.StringVar(&opts.charonViciUri, "charon-vici-uri", "", "Charon vici URI (default: unix:///var/run/charon.vici")
 
 	// glog will log to tmp files by default. override so all entries
 	// can flow into journald (if running under systemd)
@@ -233,6 +235,9 @@ func main() {
 	if opts.charonViciUri != "" {
 		ipsec.CharonViciUri = opts.charonViciUri
 	}
+	if opts.charonExecutablePath != "" {
+		ipsec.CharonExecutablePath = opts.charonExecutablePath
+	}
 
 	sm, err := newSubnetManager()
 	if err != nil {