github.com/outbrain/consul@v1.4.5/agent/keyring_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/hashicorp/consul/testutil"
    14  	"github.com/hashicorp/memberlist"
    15  )
    16  
    17  func checkForKey(key string, keyring *memberlist.Keyring) error {
    18  	rk, err := base64.StdEncoding.DecodeString(key)
    19  	if err != nil {
    20  		return err
    21  	}
    22  
    23  	pk := keyring.GetPrimaryKey()
    24  	if !bytes.Equal(rk, pk) {
    25  		return fmt.Errorf("got %q want %q", pk, rk)
    26  	}
    27  	return nil
    28  }
    29  
    30  func TestAgent_LoadKeyrings(t *testing.T) {
    31  	t.Parallel()
    32  	key := "tbLJg26ZJyJ9pK3qhc9jig=="
    33  
    34  	// Should be no configured keyring file by default
    35  	t.Run("no keys", func(t *testing.T) {
    36  		a1 := NewTestAgent(t, t.Name(), "")
    37  		defer a1.Shutdown()
    38  
    39  		c1 := a1.consulConfig()
    40  		if c1.SerfLANConfig.KeyringFile != "" {
    41  			t.Fatalf("bad: %#v", c1.SerfLANConfig.KeyringFile)
    42  		}
    43  		if c1.SerfLANConfig.MemberlistConfig.Keyring != nil {
    44  			t.Fatalf("keyring should not be loaded")
    45  		}
    46  		if c1.SerfWANConfig.KeyringFile != "" {
    47  			t.Fatalf("bad: %#v", c1.SerfLANConfig.KeyringFile)
    48  		}
    49  		if c1.SerfWANConfig.MemberlistConfig.Keyring != nil {
    50  			t.Fatalf("keyring should not be loaded")
    51  		}
    52  	})
    53  
    54  	// Server should auto-load LAN and WAN keyring files
    55  	t.Run("server with keys", func(t *testing.T) {
    56  		a2 := &TestAgent{Name: t.Name(), Key: key}
    57  		a2.Start(t)
    58  		defer a2.Shutdown()
    59  
    60  		c2 := a2.consulConfig()
    61  		if c2.SerfLANConfig.KeyringFile == "" {
    62  			t.Fatalf("should have keyring file")
    63  		}
    64  		if c2.SerfLANConfig.MemberlistConfig.Keyring == nil {
    65  			t.Fatalf("keyring should be loaded")
    66  		}
    67  		if err := checkForKey(key, c2.SerfLANConfig.MemberlistConfig.Keyring); err != nil {
    68  			t.Fatalf("err: %v", err)
    69  		}
    70  		if c2.SerfWANConfig.KeyringFile == "" {
    71  			t.Fatalf("should have keyring file")
    72  		}
    73  		if c2.SerfWANConfig.MemberlistConfig.Keyring == nil {
    74  			t.Fatalf("keyring should be loaded")
    75  		}
    76  		if err := checkForKey(key, c2.SerfWANConfig.MemberlistConfig.Keyring); err != nil {
    77  			t.Fatalf("err: %v", err)
    78  		}
    79  	})
    80  
    81  	// Client should auto-load only the LAN keyring file
    82  	t.Run("client with keys", func(t *testing.T) {
    83  		a3 := &TestAgent{Name: t.Name(), HCL: `
    84  			server = false
    85  			bootstrap = false
    86  		`, Key: key}
    87  		a3.Start(t)
    88  		defer a3.Shutdown()
    89  
    90  		c3 := a3.consulConfig()
    91  		if c3.SerfLANConfig.KeyringFile == "" {
    92  			t.Fatalf("should have keyring file")
    93  		}
    94  		if c3.SerfLANConfig.MemberlistConfig.Keyring == nil {
    95  			t.Fatalf("keyring should be loaded")
    96  		}
    97  		if err := checkForKey(key, c3.SerfLANConfig.MemberlistConfig.Keyring); err != nil {
    98  			t.Fatalf("err: %v", err)
    99  		}
   100  		if c3.SerfWANConfig.KeyringFile != "" {
   101  			t.Fatalf("bad: %#v", c3.SerfWANConfig.KeyringFile)
   102  		}
   103  		if c3.SerfWANConfig.MemberlistConfig.Keyring != nil {
   104  			t.Fatalf("keyring should not be loaded")
   105  		}
   106  	})
   107  }
   108  
   109  func TestAgent_InmemKeyrings(t *testing.T) {
   110  	t.Parallel()
   111  	key := "tbLJg26ZJyJ9pK3qhc9jig=="
   112  
   113  	// Should be no configured keyring file by default
   114  	t.Run("no keys", func(t *testing.T) {
   115  		a1 := NewTestAgent(t, t.Name(), "")
   116  		defer a1.Shutdown()
   117  
   118  		c1 := a1.consulConfig()
   119  		if c1.SerfLANConfig.KeyringFile != "" {
   120  			t.Fatalf("bad: %#v", c1.SerfLANConfig.KeyringFile)
   121  		}
   122  		if c1.SerfLANConfig.MemberlistConfig.Keyring != nil {
   123  			t.Fatalf("keyring should not be loaded")
   124  		}
   125  		if c1.SerfWANConfig.KeyringFile != "" {
   126  			t.Fatalf("bad: %#v", c1.SerfLANConfig.KeyringFile)
   127  		}
   128  		if c1.SerfWANConfig.MemberlistConfig.Keyring != nil {
   129  			t.Fatalf("keyring should not be loaded")
   130  		}
   131  	})
   132  
   133  	// Server should auto-load LAN and WAN keyring
   134  	t.Run("server with keys", func(t *testing.T) {
   135  		a2 := &TestAgent{Name: t.Name(), HCL: `
   136  			encrypt = "` + key + `"
   137  			disable_keyring_file = true
   138  		`}
   139  		a2.Start(t)
   140  		defer a2.Shutdown()
   141  
   142  		c2 := a2.consulConfig()
   143  		if c2.SerfLANConfig.KeyringFile != "" {
   144  			t.Fatalf("should not have keyring file")
   145  		}
   146  		if c2.SerfLANConfig.MemberlistConfig.Keyring == nil {
   147  			t.Fatalf("keyring should be loaded")
   148  		}
   149  		if err := checkForKey(key, c2.SerfLANConfig.MemberlistConfig.Keyring); err != nil {
   150  			t.Fatalf("err: %v", err)
   151  		}
   152  		if c2.SerfWANConfig.KeyringFile != "" {
   153  			t.Fatalf("should not have keyring file")
   154  		}
   155  		if c2.SerfWANConfig.MemberlistConfig.Keyring == nil {
   156  			t.Fatalf("keyring should be loaded")
   157  		}
   158  		if err := checkForKey(key, c2.SerfWANConfig.MemberlistConfig.Keyring); err != nil {
   159  			t.Fatalf("err: %v", err)
   160  		}
   161  	})
   162  
   163  	// Client should auto-load only the LAN keyring
   164  	t.Run("client with keys", func(t *testing.T) {
   165  		a3 := &TestAgent{Name: t.Name(), HCL: `
   166  			encrypt = "` + key + `"
   167  			server = false
   168  			bootstrap = false
   169  			disable_keyring_file = true
   170  		`}
   171  		a3.Start(t)
   172  		defer a3.Shutdown()
   173  
   174  		c3 := a3.consulConfig()
   175  		if c3.SerfLANConfig.KeyringFile != "" {
   176  			t.Fatalf("should not have keyring file")
   177  		}
   178  		if c3.SerfLANConfig.MemberlistConfig.Keyring == nil {
   179  			t.Fatalf("keyring should be loaded")
   180  		}
   181  		if err := checkForKey(key, c3.SerfLANConfig.MemberlistConfig.Keyring); err != nil {
   182  			t.Fatalf("err: %v", err)
   183  		}
   184  		if c3.SerfWANConfig.KeyringFile != "" {
   185  			t.Fatalf("bad: %#v", c3.SerfWANConfig.KeyringFile)
   186  		}
   187  		if c3.SerfWANConfig.MemberlistConfig.Keyring != nil {
   188  			t.Fatalf("keyring should not be loaded")
   189  		}
   190  	})
   191  
   192  	// Any keyring files should be ignored
   193  	t.Run("ignore files", func(t *testing.T) {
   194  		dir := testutil.TempDir(t, "consul")
   195  		defer os.RemoveAll(dir)
   196  
   197  		badKey := "unUzC2X3JgMKVJlZna5KVg=="
   198  		if err := initKeyring(filepath.Join(dir, SerfLANKeyring), badKey); err != nil {
   199  			t.Fatalf("err: %v", err)
   200  		}
   201  		if err := initKeyring(filepath.Join(dir, SerfWANKeyring), badKey); err != nil {
   202  			t.Fatalf("err: %v", err)
   203  		}
   204  
   205  		a4 := &TestAgent{Name: t.Name(), HCL: `
   206  			encrypt = "` + key + `"
   207  			disable_keyring_file = true
   208  			data_dir = "` + dir + `"
   209  		`}
   210  		a4.Start(t)
   211  		defer a4.Shutdown()
   212  
   213  		c4 := a4.consulConfig()
   214  		if c4.SerfLANConfig.KeyringFile != "" {
   215  			t.Fatalf("should not have keyring file")
   216  		}
   217  		if c4.SerfLANConfig.MemberlistConfig.Keyring == nil {
   218  			t.Fatalf("keyring should be loaded")
   219  		}
   220  		if err := checkForKey(key, c4.SerfLANConfig.MemberlistConfig.Keyring); err != nil {
   221  			t.Fatalf("err: %v", err)
   222  		}
   223  		if c4.SerfWANConfig.KeyringFile != "" {
   224  			t.Fatalf("should not have keyring file")
   225  		}
   226  		if c4.SerfWANConfig.MemberlistConfig.Keyring == nil {
   227  			t.Fatalf("keyring should be loaded")
   228  		}
   229  		if err := checkForKey(key, c4.SerfWANConfig.MemberlistConfig.Keyring); err != nil {
   230  			t.Fatalf("err: %v", err)
   231  		}
   232  	})
   233  }
   234  
   235  func TestAgent_InitKeyring(t *testing.T) {
   236  	t.Parallel()
   237  	key1 := "tbLJg26ZJyJ9pK3qhc9jig=="
   238  	key2 := "4leC33rgtXKIVUr9Nr0snQ=="
   239  	expected := fmt.Sprintf(`["%s"]`, key1)
   240  
   241  	dir := testutil.TempDir(t, "consul")
   242  	defer os.RemoveAll(dir)
   243  
   244  	file := filepath.Join(dir, "keyring")
   245  
   246  	// First initialize the keyring
   247  	if err := initKeyring(file, key1); err != nil {
   248  		t.Fatalf("err: %s", err)
   249  	}
   250  
   251  	content, err := ioutil.ReadFile(file)
   252  	if err != nil {
   253  		t.Fatalf("err: %s", err)
   254  	}
   255  	if string(content) != expected {
   256  		t.Fatalf("bad: %s", content)
   257  	}
   258  
   259  	// Try initializing again with a different key
   260  	if err := initKeyring(file, key2); err != nil {
   261  		t.Fatalf("err: %s", err)
   262  	}
   263  
   264  	// Content should still be the same
   265  	content, err = ioutil.ReadFile(file)
   266  	if err != nil {
   267  		t.Fatalf("err: %s", err)
   268  	}
   269  	if string(content) != expected {
   270  		t.Fatalf("bad: %s", content)
   271  	}
   272  }
   273  
   274  func TestAgentKeyring_ACL(t *testing.T) {
   275  	t.Parallel()
   276  	key1 := "tbLJg26ZJyJ9pK3qhc9jig=="
   277  	key2 := "4leC33rgtXKIVUr9Nr0snQ=="
   278  
   279  	a := &TestAgent{Name: t.Name(), HCL: TestACLConfig() + `
   280  		acl_datacenter = "dc1"
   281  		acl_master_token = "root"
   282  		acl_default_policy = "deny"
   283  	`, Key: key1}
   284  	a.Start(t)
   285  	defer a.Shutdown()
   286  
   287  	// List keys without access fails
   288  	_, err := a.ListKeys("", 0)
   289  	if err == nil || !strings.Contains(err.Error(), "denied") {
   290  		t.Fatalf("expected denied error, got: %#v", err)
   291  	}
   292  
   293  	// List keys with access works
   294  	_, err = a.ListKeys("root", 0)
   295  	if err != nil {
   296  		t.Fatalf("err: %s", err)
   297  	}
   298  
   299  	// Install without access fails
   300  	_, err = a.InstallKey(key2, "", 0)
   301  	if err == nil || !strings.Contains(err.Error(), "denied") {
   302  		t.Fatalf("expected denied error, got: %#v", err)
   303  	}
   304  
   305  	// Install with access works
   306  	_, err = a.InstallKey(key2, "root", 0)
   307  	if err != nil {
   308  		t.Fatalf("err: %s", err)
   309  	}
   310  
   311  	// Use without access fails
   312  	_, err = a.UseKey(key2, "", 0)
   313  	if err == nil || !strings.Contains(err.Error(), "denied") {
   314  		t.Fatalf("expected denied error, got: %#v", err)
   315  	}
   316  
   317  	// Use with access works
   318  	_, err = a.UseKey(key2, "root", 0)
   319  	if err != nil {
   320  		t.Fatalf("err: %s", err)
   321  	}
   322  
   323  	// Remove without access fails
   324  	_, err = a.RemoveKey(key1, "", 0)
   325  	if err == nil || !strings.Contains(err.Error(), "denied") {
   326  		t.Fatalf("expected denied error, got: %#v", err)
   327  	}
   328  
   329  	// Remove with access works
   330  	_, err = a.RemoveKey(key1, "root", 0)
   331  	if err != nil {
   332  		t.Fatalf("err: %s", err)
   333  	}
   334  }