Skip to content

Commit

Permalink
Merge pull request #1 from at88mph/main
Browse files Browse the repository at this point in the history
feat: initial commit for sshd with common utility library
  • Loading branch information
shinybrar authored Dec 9, 2024
2 parents cf8cff7 + 1e815cb commit 16abaa2
Show file tree
Hide file tree
Showing 17 changed files with 664 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:

# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
# Runs weekly at 16:29 on Mondays.
schedule:
- cron: '29 16 * * 1'
push:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
charts/
6 changes: 6 additions & 0 deletions helm/applications/sshd/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies:
- name: common
repository: file://../../common
version: 1.0.0
digest: sha256:002240b61dab8d637689129ba617df79c1ee616902bfa8c05ec39fdf0a7ee8ac
generated: "2024-11-18T15:06:05.433377648-08:00"
29 changes: 29 additions & 0 deletions helm/applications/sshd/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: v2
name: sshd
description: "An SSHD service with SSSD to get users from LDAP"

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"

dependencies:
- name: common
version: "^1.0.0"
repository: "file://../../common"
46 changes: 46 additions & 0 deletions helm/applications/sshd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Deployment Guilde

- [Dependencies](#dependencies)
- [Helm](#helm-repository)


## Dependencies

- An existing Kubernetes cluster, version 1.26 or greater.
- A working [`base` Helm Chart](https://github.com/opencadc/science-platform/tree/main/deployment/helm#base-install) install. If using Traefik, add a port (entry point) that this SSHD service will expose, which will be declared in the `traefik.ports` section. Example:
```yaml
# Install Traefik by default. Set to true to add it in. Omitting it defaults to true, so beware.
traefik:
install: true
ports:
sshd:
port: 64022 # Expose port 64022.
expose: true
```
- A `PersistentVolumeClaim` claiming storage that contains the root of the User Storage. This will be the same `PersistentVolumeClaim` that Cavern uses (if installed). See
- A Kubernetes secret called `sssd-ldap-secret` in the Skaha Namespace (defaults to `skaha-system`) with a single key of `ldap-password` whose value is the password of the LDAP bind user as configured in the `values.yaml` file for (`deployment.sshd.ldap.bindDN`):
- `kubectl -n skaha-system create secret generic sssd-ldap-secret --from-literal="ldap-password=my-super-secret-passwd"`

## Sample Values file

```yaml
deployment:
sshd:
entryPoint: sshd
rootPath: "/cavern" # If Cavern is installed, this will point to the same location as deployment.cavern.filesystem.subPath.
# LDAP configuration information. Authentication is handled by the secret/sssd.conf file.
ldap:
url: "ldaps://my-ldap-host.example.org"
searchBase: "dc=exmaple,dc=org"
userSearchBase: "ou=users,ou=ds,dc=example,dc=org"
groupSearchBase: "ou=groups,ou=ds,dc=example,dc=org"
bindDN: "uid=superuser,ou=Admins,dc=example,dc=org"
storage:
service:
spec:
persistentVolumeClaim:
claimName: skaha-pvc # Match this label up with whatever was installed in the base install, or the desired PVC, or create dynamically provisioned storage.
```
142 changes: 142 additions & 0 deletions helm/applications/sshd/config/sshd_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
Port 2222
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

# override default of no subsystems
#Subsystem sftp /usr/libexec/sftp-server
Subsystem sftp internal-sftp

# Example of overriding settings on a per-user basis
Match User *
ChrootDirectory {{ .Values.rootPath }}
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
ForceCommand internal-sftp
38 changes: 38 additions & 0 deletions helm/applications/sshd/secret/sssd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[sssd]
config_file_version = 2
services = nss, pam
domains = cadc
debug_level = 9
[nss]
filter_groups = nobody,root,daemon,bin,sys,adm,uucp,nuucp,security,cron,lpd,audit,lp,printq,staff,system,usr,smmsp,ldap,guest,wheel,milter,sshd,centos
filter_users = nobody,root,daemon,bin,sys,adm,uucp,nuucp,security,cron,lpd,audit,lp,printq,staff,system,usr,smmsp,ldap,guest,wheel,milter,sshd,centos
[pam]
[domain/cadc]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
access_provider = ldap
filter_users = nobody, root, daemon, bin, sys, adm, uucp, nuucp, security, cron, lpd, audit, lp, printq, staff, system, usr, smmsp, ldap, guest, wheel, milter, sshd, centos
access_provider = permit
min_id = 1001
cache_credentials = True
enumerate = False
override_homedir = {{ .Values.rootPath }}/home/%u
debug_level = 8
{{ $ldapPassword := include "getSecretKeyValue" (list "sssd-ldap-secret" "ldap-password" .Release.Namespace) -}}
{{ with .Values.ldap -}}
ldap_uri = {{ .url }}
ldap_search_base = {{ .searchBase }}
ldap_user_search_base = {{ .userSearchBase }}
ldap_group_search_base = {{ .groupSearchBase }}
ldap_group_member = uniqueMember
ldap_user_member_of = memberOf
ldap_default_bind_dn = {{ .bindDN }}
ldap_user_name = {{ .userNameField | default "cn" }}
ldap_user_gecos = email
ldap_default_authtok_type = password
ldap_default_authtok = {{ $ldapPassword }}
ldap_user_object_class = cadcaccount
ldap_group_object_class = groupofuniquenames
ldap_schema = rfc2307bis
{{- end }}
39 changes: 39 additions & 0 deletions helm/applications/sshd/templates/_helper.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{{- /*
Generate a new key field in the given secret if it does not already exist. The .pub field is intentionally
left empty as Helm cannot generate it. We maintain the private keys though, so the user won't be bothered
by the constant host name issue.
*/}}
{{- define "sshd.gen.key" -}}
{{- $namespace := .namespace }}
{{- $secretName := .secretName }}
{{- $secretFieldName := .secretFieldName }}
{{- $keyType := .keyType }}
# retrieve the secret data using lookup function and when not exists, return an empty dictionary / map as result
{{- $secretObj := (lookup "v1" "Secret" $namespace $secretName) | default dict }}
{{- $secretData := (get $secretObj "data") | default dict }}
# set $apiSecret to existing secret data or generate a random one when not exists
{{- $apiSecret := (get $secretData $secretFieldName) | default (genPrivateKey $keyType | b64enc) }}
{{ $secretFieldName }}: {{ $apiSecret }}
{{- end -}}
{{/*
GetSecretKeyValue gets the value of a key from within a specified Secret.
Usage: {{ getSecretKeyValue "existingSecretName" "keyName" "namespace" }}
*/}}
{{- define "getSecretKeyValue" -}}
{{- $secretName := index . 0 -}}
{{- $keyName := index . 1 -}}
{{- $namespace := index . 2 -}}
{{- $secret := (lookup "v1" "Secret" $namespace $secretName) -}}
{{- if $secret -}}
{{- $value := index $secret.data $keyName -}}
{{- if $value -}}
{{- $decodedValue := $value | b64dec -}}
{{- print $decodedValue -}}
{{- else -}}
{{- fail (printf "Error: Key %s not found in the secret %s in namespace %s" $keyName $secretName $namespace) -}}
{{- end -}}
{{- else -}}
{{- fail (printf "Error: Secret %s not found in namespace %s" $secretName $namespace) -}}
{{- end -}}
{{- end -}}
13 changes: 13 additions & 0 deletions helm/applications/sshd/templates/sshd-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{ $secretName := printf "%s-config" .Release.Name }}
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
namespace: {{ .Release.Namespace }}
type: Opaque
data:
{{- range list "rsa" "ecdsa" "ed25519" }}
{{- $keyFileName := printf "ssh_host_%s_key" . -}}
{{- include "sshd.gen.key" (dict "namespace" $.Release.Namespace "secretName" $secretName "secretFieldName" $keyFileName "keyType" .) -}}
{{- end }}
sshd_config: {{ tpl (.Files.Get "config/sshd_config") . | b64enc }}
Loading

0 comments on commit 16abaa2

Please sign in to comment.