Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: customize kerberos settings #709

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions charts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ The following table lists the configurable parameters of the latest SMB CSI Driv
| `linux.dsName` | name of driver daemonset on linux | `csi-smb-node` |
| `linux.dnsPolicy` | dnsPolicy of driver node daemonset, available values: `Default`, `ClusterFirstWithHostNet`, `ClusterFirst` | `ClusterFirstWithHostNet` |
| `linux.kubelet` | configure kubelet directory path on Linux agent node node | `/var/lib/kubelet` |
| `linux.krb5CacheDirectory` | directory for kerberos cache on Linux agent node node | `/var/lib/kubelet/kerberos/` |
| `linux.krb5Prefix` | prefix for kerberos cache on Linux agent node node | `krb5cc_` |
| `linux.resources.livenessProbe.limits.memory` | liveness-probe memory limits | `100Mi` |
| `linux.resources.livenessProbe.requests.cpu` | liveness-probe cpu requests limits | `10m` |
| `linux.resources.livenessProbe.requests.memory` | liveness-probe memory requests limits | `20Mi` |
Expand Down
Binary file modified charts/latest/csi-driver-smb-v0.0.0.tgz
Binary file not shown.
2 changes: 2 additions & 0 deletions charts/latest/csi-driver-smb/templates/csi-smb-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ spec:
- "--endpoint=$(CSI_ENDPOINT)"
- "--nodeid=$(KUBE_NODE_NAME)"
- "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}"
- "--krb5-cache-directory={{ .Values.linux.krb5CacheDirectory }}"
- "--krb5-prefix={{ .Values.linux.krb5Prefix }}"
ports:
- containerPort: {{ .Values.node.livenessProbe.healthPort }}
name: healthz
Expand Down
2 changes: 2 additions & 0 deletions charts/latest/csi-driver-smb/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ linux:
dsName: csi-smb-node # daemonset name
dnsPolicy: ClusterFirstWithHostNet # available values: Default, ClusterFirstWithHostNet, ClusterFirst
kubelet: /var/lib/kubelet
krb5CacheDirectory: /var/lib/kubelet/kerberos/ # directory for kerberos credential cache
krb5Prefix: "krb5cc_" # prefix for kerberos credential cache
tolerations:
- operator: "Exists"
resources:
Expand Down
4 changes: 4 additions & 0 deletions cmd/smbplugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ var (
removeSMBMappingDuringUnmount = flag.Bool("remove-smb-mapping-during-unmount", true, "remove SMBMapping during unmount on Windows node")
workingMountDir = flag.String("working-mount-dir", "/tmp", "working directory for provisioner to mount smb shares temporarily")
volStatsCacheExpireInMinutes = flag.Int("vol-stats-cache-expire-in-minutes", 10, "The cache expire time in minutes for volume stats cache")
krb5CacheDirectory = flag.String("krb5-cache-directory", "/var/lib/kubelet/kerberos/", "The directory for kerberos cache")
krb5Prefix = flag.String("krb5-prefix", "krb5cc_", "The prefix for kerberos cache")
)

func main() {
Expand Down Expand Up @@ -74,6 +76,8 @@ func handle() {
RemoveSMBMappingDuringUnmount: *removeSMBMappingDuringUnmount,
WorkingMountDir: *workingMountDir,
VolStatsCacheExpireInMinutes: *volStatsCacheExpireInMinutes,
Krb5CacheDirectory: *krb5CacheDirectory,
Krb5Prefix: *krb5Prefix,
}
driver := smb.NewDriver(&driverOptions)
driver.Run(*endpoint, *kubeconfig, false)
Expand Down
32 changes: 16 additions & 16 deletions pkg/smb/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (d *Driver) NodeStageVolume(_ context.Context, req *csi.NodeStageVolumeRequ
sensitiveMountOptions = []string{password}
}
} else {
var useKerberosCache, err = ensureKerberosCache(volumeID, mountFlags, secrets)
var useKerberosCache, err = ensureKerberosCache(d.krb5CacheDirectory, d.krb5Prefix, volumeID, mountFlags, secrets)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("Error writing kerberos cache: %v", err))
}
Expand Down Expand Up @@ -264,7 +264,7 @@ func (d *Driver) NodeUnstageVolume(_ context.Context, req *csi.NodeUnstageVolume
return nil, status.Errorf(codes.Internal, "failed to unmount staging target %q: %v", stagingTargetPath, err)
}

if err := deleteKerberosCache(volumeID); err != nil {
if err := deleteKerberosCache(d.krb5CacheDirectory, volumeID); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete kerberos cache: %v", err)
}

Expand Down Expand Up @@ -469,12 +469,12 @@ func getCredUID(mountFlags []string) (int, error) {
return -1, fmt.Errorf("Can't find credUid in mount flags")
}

func getKrb5CcacheName(credUID int) string {
func getKrb5CcacheName(krb5Prefix string, credUID int) string {
return fmt.Sprintf("%s%d", krb5Prefix, credUID)
}

// returns absolute path for name of file inside krb5CacheDirectory
func getKerberosFilePath(fileName string) string {
func getKerberosFilePath(krb5CacheDirectory, fileName string) string {
return fmt.Sprintf("%s%s", krb5CacheDirectory, fileName)
}

Expand All @@ -483,7 +483,7 @@ func volumeKerberosCacheName(volumeID string) string {
return strings.ReplaceAll(strings.ReplaceAll(encoded, "/", "-"), "+", "_")
}

func kerberosCacheDirectoryExists() (bool, error) {
func kerberosCacheDirectoryExists(krb5CacheDirectory string) (bool, error) {
_, err := os.Stat(krb5CacheDirectory)
if os.IsNotExist(err) {
return false, status.Error(codes.Internal, fmt.Sprintf("Directory for kerberos caches must exist, it will not be created: %s: %v", krb5CacheDirectory, err))
Expand All @@ -493,8 +493,8 @@ func kerberosCacheDirectoryExists() (bool, error) {
return true, nil
}

func getKerberosCache(credUID int, secrets map[string]string) (string, []byte, error) {
var krb5CcacheName = getKrb5CcacheName(credUID)
func getKerberosCache(krb5CacheDirectory, krb5Prefix string, credUID int, secrets map[string]string) (string, []byte, error) {
var krb5CcacheName = getKrb5CcacheName(krb5Prefix, credUID)
var krb5CcacheContent string
for k, v := range secrets {
switch strings.ToLower(k) {
Expand All @@ -509,33 +509,33 @@ func getKerberosCache(credUID int, secrets map[string]string) (string, []byte, e
if err != nil {
return "", nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Malformed kerberos cache in key %s, expected to be in base64 form: %v", krb5CcacheName, err))
}
var krb5CacheFileName = getKerberosFilePath(getKrb5CcacheName(credUID))
var krb5CacheFileName = getKerberosFilePath(krb5CacheDirectory, getKrb5CcacheName(krb5Prefix, credUID))

return krb5CacheFileName, content, nil
}

// Create kerberos cache in the file based on the VolumeID, so it can be cleaned up during unstage
// At the same time, kerberos expects to find cache in file named "krb5cc_*", so creating symlink
// will allow both clean up and serving proper cache to the kerberos.
func ensureKerberosCache(volumeID string, mountFlags []string, secrets map[string]string) (bool, error) {
func ensureKerberosCache(krb5CacheDirectory, krb5Prefix, volumeID string, mountFlags []string, secrets map[string]string) (bool, error) {
var securityIsKerberos = hasKerberosMountOption(mountFlags)
if securityIsKerberos {
_, err := kerberosCacheDirectoryExists()
_, err := kerberosCacheDirectoryExists(krb5CacheDirectory)
if err != nil {
return false, err
}
credUID, err := getCredUID(mountFlags)
if err != nil {
return false, err
}
krb5CacheFileName, content, err := getKerberosCache(credUID, secrets)
krb5CacheFileName, content, err := getKerberosCache(krb5CacheDirectory, krb5Prefix, credUID, secrets)
if err != nil {
return false, err
}
// Write cache into volumeId-based filename, so it can be cleaned up later
volumeIDCacheFileName := volumeKerberosCacheName(volumeID)

volumeIDCacheAbsolutePath := getKerberosFilePath(volumeIDCacheFileName)
volumeIDCacheAbsolutePath := getKerberosFilePath(krb5CacheDirectory, volumeIDCacheFileName)
if err := os.WriteFile(volumeIDCacheAbsolutePath, content, os.FileMode(0700)); err != nil {
return false, status.Error(codes.Internal, fmt.Sprintf("Couldn't write kerberos cache to file %s: %v", volumeIDCacheAbsolutePath, err))
}
Expand All @@ -561,8 +561,8 @@ func ensureKerberosCache(volumeID string, mountFlags []string, secrets map[strin
return false, nil
}

func deleteKerberosCache(volumeID string) error {
exists, err := kerberosCacheDirectoryExists()
func deleteKerberosCache(krb5CacheDirectory, volumeID string) error {
exists, err := kerberosCacheDirectoryExists(krb5CacheDirectory)
// If not supported, simply return
if !exists {
return nil
Expand All @@ -573,7 +573,7 @@ func deleteKerberosCache(volumeID string) error {

volumeIDCacheFileName := volumeKerberosCacheName(volumeID)

var volumeIDCacheAbsolutePath = getKerberosFilePath(volumeIDCacheFileName)
var volumeIDCacheAbsolutePath = getKerberosFilePath(krb5CacheDirectory, volumeIDCacheFileName)
_, err = os.Stat(volumeIDCacheAbsolutePath)
// Not created or already removed
if os.IsNotExist(err) {
Expand All @@ -585,7 +585,7 @@ func deleteKerberosCache(volumeID string) error {
// If file with cache exists, full clean means removing symlinks to the file.
dirEntries, _ := os.ReadDir(krb5CacheDirectory)
for _, dirEntry := range dirEntries {
filePath := getKerberosFilePath(dirEntry.Name())
filePath := getKerberosFilePath(krb5CacheDirectory, dirEntry.Name())
lStat, _ := os.Lstat(filePath)
// If it's a symlink, checking if it's pointing to the volume file in question
if lStat != nil {
Expand Down
4 changes: 3 additions & 1 deletion pkg/smb/nodeserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,8 @@ func TestGetKerberosCache(t *testing.T) {
ticket := []byte{'G', 'O', 'L', 'A', 'N', 'G'}
base64Ticket := base64.StdEncoding.EncodeToString(ticket)
credUID := 1000
krb5CacheDirectory := "/var/lib/kubelet/kerberos/"
krb5Prefix := "krb5cc_"
goodFileName := fmt.Sprintf("%s%s%d", krb5CacheDirectory, krb5Prefix, credUID)
krb5CcacheName := "krb5cc_1000"

Expand Down Expand Up @@ -855,7 +857,7 @@ func TestGetKerberosCache(t *testing.T) {
}

for _, test := range tests {
fileName, content, err := getKerberosCache(test.credUID, test.secrets)
fileName, content, err := getKerberosCache(krb5CacheDirectory, krb5Prefix, test.credUID, test.secrets)
if !reflect.DeepEqual(err, test.expectedErr) {
t.Errorf("[%s]: Expected error : %v, Actual error: %v", test.desc, test.expectedErr, err)
} else {
Expand Down
8 changes: 6 additions & 2 deletions pkg/smb/smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ const (
sourceField = "source"
subDirField = "subdir"
domainField = "domain"
krb5Prefix = "krb5cc_"
krb5CacheDirectory = "/var/lib/kubelet/kerberos/"
mountOptionsField = "mountoptions"
defaultDomainName = "AZURE"
pvcNameKey = "csi.storage.k8s.io/pvc/name"
Expand All @@ -59,6 +57,8 @@ type DriverOptions struct {
RemoveSMBMappingDuringUnmount bool
WorkingMountDir string
VolStatsCacheExpireInMinutes int
Krb5CacheDirectory string
Krb5Prefix string
}

// Driver implements all interfaces of CSI drivers
Expand All @@ -74,6 +74,8 @@ type Driver struct {
volStatsCache azcache.Resource
// this only applies to Windows node
removeSMBMappingDuringUnmount bool
krb5CacheDirectory string
krb5Prefix string
}

// NewDriver Creates a NewCSIDriver object. Assumes vendor version is equal to driver version &
Expand All @@ -86,6 +88,8 @@ func NewDriver(options *DriverOptions) *Driver {
driver.enableGetVolumeStats = options.EnableGetVolumeStats
driver.removeSMBMappingDuringUnmount = options.RemoveSMBMappingDuringUnmount
driver.workingMountDir = options.WorkingMountDir
driver.krb5CacheDirectory = options.Krb5CacheDirectory
driver.krb5Prefix = options.Krb5Prefix
driver.volumeLocks = newVolumeLocks()

if options.VolStatsCacheExpireInMinutes <= 0 {
Expand Down
Loading