# Scale the whole chart down without uninstalling it: scaleDown: true renders # every Deployment/StatefulSet with replicas: 0 (and suspends CronJobs) and # takes precedence over any per-workload replicas value. PVCs, Secrets and # Services stay in place; scaleDown: false brings the workloads back up. scaleDown: false secrets: # users.conf is mounted into the samba container from the Secret the 1Password # operator materializes from this item. # # Known limitation (#82): changing the item in the vault does NOT restart # samba, so added, removed or re-passworded users stay invisible to the # running smbd. Helm cannot hash the content (it never sees it - the operator # fills the Secret in-cluster after rendering), so the checksum/config # mechanism used for smb.conf does not apply here. The operator's own # "operator.1password.io/auto-restart" annotation is no help either: it only # ever restarts Deployments, and this workload is a StatefulSet (verified # against onepassword-operator 1.12.0). After changing the users item, # restart samba by hand: # kubectl rollout restart statefulset -samba-sfs sambaUsersSecretRef: null samba: # Replica count for this workload; 0 is allowed and scales it down. # The chart-global scaleDown flag takes precedence. replicas: 1 # NodePorts the SMB service is published on (service type NodePort). smbNodePort: 30445 netbiosNodePort: 30139 shares: - name: null validUsers: null description: null size: null # Extra environment variables for the samba container. Values are rendered # through tpl; value, secretKeyRef and configMapKeyRef forms are supported. env: [] # SMB is not an HTTP protocol, so probe the main SMB TCP port. livenessProbe: tcpSocket: port: 445 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: tcpSocket: port: 445 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 # The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s. startupProbe: tcpSocket: port: 445 periodSeconds: 5 timeoutSeconds: 5 failureThreshold: 30 resources: # Limits are optional: memory and ephemeral-storage limits default to # limitFactor x the request, an explicitly set limit always wins, and a # CPU limit is only set when configured explicitly under "limits". limitFactor: 3 requests: memory: 50Mi cpu: 0.1 ephemeralStorage: 50Mi # Deviations from the repo's hardening baseline, forced by the # ghcr.io/dockur/samba image (its entrypoint samba.sh): # - no runAsNonRoot: the entrypoint creates the Unix users from users.conf # (groupadd/adduser/usermod) and smbd impersonates the authenticated # share user per session, both of which require starting as root. # - readOnlyRootFilesystem: false: the entrypoint writes to the root # filesystem at startup (/etc/passwd + /etc/group for user creation, # the /etc/samba.conf healthcheck symlink, mkdir /shared and the Samba # TDB databases under /var/lib/samba). # - capabilities: ALL dropped except what a multi-user root file server # needs: NET_BIND_SERVICE (ports 445/139), SETUID/SETGID (per-session # user impersonation), CHOWN/FOWNER/DAC_OVERRIDE (managing share files # on behalf of the users). securityContext: pod: fsGroup: 1000 container: allowPrivilegeEscalation: false readOnlyRootFilesystem: false capabilities: drop: - ALL add: - CHOWN - DAC_OVERRIDE - FOWNER - NET_BIND_SERVICE - SETGID - SETUID storageClass: longhorn # --------------------------------------------------------------------------- # NetworkPolicy (Gitea #5). On by default. The reference implementation with # the full reasoning is template-chart; the convention is in README, "Chart # style guidelines", and the operator's view on this chart's wiki page. # --------------------------------------------------------------------------- networkPolicy: # THERE IS ONLY ONE VALUE HERE BESIDES enabled, AND THAT IS DELIBERATE. # Both of this chart's inbound rules are open to any source (see below), so # neither allowedNamespaces nor probeSources would reach a rule - and a value # that silently does nothing is worse than a value that is absent: it reads # as a control. If a source restriction is ever wanted here it needs a rule # to attach to first. # # WHAT THIS POLICY ALLOWS: inbound 445 and 139 - the POD ports - open to any # source, and outbound nothing but DNS. # # BOTH INBOUND RULES ARE OPEN ON PURPOSE. The ports are published as # NodePorts and the clients are machines on the LAN; after NodePort # masquerading the source address is a cluster node, so a source selector # could only be a list of node IPs - a restriction in appearance and a # maintenance trap in fact. 445 is also the probe port. # # AND THE NUMBERS ARE 445 AND 139, NOT samba.smbNodePort AND # samba.netbiosNodePort. A NetworkPolicy is evaluated at the pod's interface # after kube-proxy has translated the NodePort, so the NodePort numbers would # match nothing while looking strict - and would block every client. # # Not covered, and it does not matter here: the NetBIOS name-service # broadcasts on 137/138 UDP are not published by this chart's Service at all, # and clients reach the share by address rather than by browse list. enabled: true # The policy's INBOUND side. Mind the three names that overlap as substrings, # because a search for "ingress" matches all of them and they are different # things: # # ingress (top level) the Ingress OBJECT this chart # renders - host, TLS, className # networkPolicy.ingress this block: what the policy lets IN # networkPolicy.ingressController the SOURCE SELECTOR for the ingress # controller's pods. A SIBLING of this block # and NO PART OF IT, despite the name. ingress: # Opens the pod for Istio's ambient mesh (Gitea #143). OFF by default and # additive: while it is false this chart renders byte for byte as it did # before the value existed. # # It renders 15008/TCP inbound - ztunnel's HBONE tunnel. Every inbound mesh # connection arrives on it, and ambient "does not and will never bypass # Kubernetes NetworkPolicy enforcement", so without this port a pod whose # namespace has joined the mesh is unreachable. # # ONE HALF SHORTER THAN ELSEWHERE, deliberately. In other charts this switch # also adds 169.254.7.127/32 as a probe source, because inside the mesh the # kubelet's probes are redirected away from the worker node's address. This # chart has no networkPolicy.probeSources at all, so the rule carrying the # probe port is never restricted by source - and an unrestricted rule needs # no probe address. An ipBlock for one would match nothing while making the # rule look like it did something, which is the kind of strict-looking empty # rule ci/run-networkpolicy-test.sh exists to catch; that script ties the # exemption to the absence of probeSources rather than to a chart name. # # NOT PROVEN: that 15008 alone is enough comes from Istio's documentation; # measured on this cluster is only which listeners ztunnel opens, and no # namespace carries istio.io/dataplane-mode yet. # BOTH NUMBERS BELOW ARE ISTIO CONSTANTS, NOT STANDARDS, and they are values # rather than template literals for exactly that reason: a vendor constant # can change, and an operator should be able to correct it without waiting # for a chart release. Their provenance is written on each one. # # DELETING THIS OBJECT IS SAFE. Every read falls back to the defaults # declared here (#99), so "ambientMesh: null", or an object carrying only # "enabled: true", renders the documented defaults instead of failing. ambientMesh: # The switch. Everything else here is inert while it is false, and the # chart renders exactly as it did before the object existed. enabled: false # ISTIO'S HBONE PORT. A constant Istio chose, not a standard: not # registered with IANA for this, prescribed by no protocol, and unknown to # Kubernetes. Read for ztunnel 1.30.6 (measured on this cluster: ztunnel # opens [::]:15008 as its inbound listener). # # If Istio changes it, a pod in the mesh cannot be reached. Change it here # in all 30 charts AND in the pinned expectation inside # ci/run-networkpolicy-test.sh - the test is deliberately what forces # someone to look, because the exception it grants this port is pinned to # the number IT knows and not to whatever this value says. A value-driven # exception would let a mistyped port through, which is the hole design A # of #143 was rejected for. # # NOT MEASURED: that this port ALONE suffices comes from Istio's # documentation. Measured here is only which listeners ztunnel opens, and # no namespace carries istio.io/dataplane-mode yet. port: 15008 egress: # Additional outbound TCP ports. DNS (UDP and TCP 53) is always allowed and # has no switch - a knob whose only other setting breaks every name lookup # in the pod is a trap, not a feature. # # PORTS, NOT DESTINATIONS, and that is a limit of the object rather than # laziness: a NetworkPolicy matches CIDRs and selectors and never hostnames, # so "only to the database host" cannot be written at all. Each entry # permits its port to ANY destination. What the cap still buys is real: a # compromised pod cannot open arbitrary outbound connections. # # A domain-joined Samba needs Kerberos (88) and LDAP (389 or 636) here. A # standalone one needs nothing. extraPorts: []