config: nest PAM settings under pam: with per-service overrides - #1675
config: nest PAM settings under pam: with per-service overrides#1675adombeck wants to merge 3 commits into
pam: with per-service overrides#1675Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1675 +/- ##
==========================================
+ Coverage 87.91% 87.93% +0.02%
==========================================
Files 96 96
Lines 6976 7005 +29
Branches 112 112
==========================================
+ Hits 6133 6160 +27
- Misses 787 789 +2
Partials 56 56 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
1d62be1 to
e9ca42b
Compare
670cdcb to
81fbdc9
Compare
There was a problem hiding this comment.
Pull request overview
This PR moves PAM brute-force mitigation settings into a dedicated pam: config section and introduces per-PAM-service override support, requiring the PAM client to send the PAM service name to authd so the daemon can apply the correct policy.
Changes:
- Add
service_nametoSBRequestand propagate PAM service name from the PAM adapter → gRPC → broker session tracking. - Refactor PAM service brute-force mitigation configuration to support defaults plus per-service overrides (e.g.,
pam.services.sshd). - Add startup warning for config entries referencing PAM services not present in
/etc/pam.d, plus tests for override behavior.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pam/internal/adapter/model.go | Captures PAM service name from PAM transaction for later propagation. |
| pam/internal/adapter/commands.go | Sends PAM service name in SelectBroker (SBRequest). |
| internal/services/pam/pam.go | Introduces nested PAM brute-force config with per-service overrides and uses service name during auth failure delay logic. |
| internal/services/pam/pam_test.go | Adds tests for unknown-service warnings and per-service fail-delay/reset-window behavior. |
| internal/services/pam/auth_fail_tracker_test.go | Updates tracker tests for new recordFailure signature. |
| internal/proto/authd/authd.proto | Adds service_name field to SBRequest. |
| internal/proto/authd/authd.pb.go | Regenerates Go protobuf for service_name. |
| internal/brokers/manager.go | Stores service name alongside session ID for later policy lookup. |
| internal/brokers/manager_test.go | Extends tests to validate service name is remembered per session. |
| debian/authd-config/authd.yaml | Updates example config comments to document pam: nesting and per-service overrides. |
| cmd/authd/daemon/daemon.go | Nests PAM config under pam: and warns on unknown PAM services at startup. |
| cmd/authd/daemon/daemon_test.go | Verifies default PAM config is set on daemon startup. |
Files not reviewed (1)
- internal/proto/authd/authd.pb.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d010c23 to
60475ce
Compare
denisonbarbosa
left a comment
There was a problem hiding this comment.
Looks good to me, but I'd like to see if @3v1n0 has something to point out
|
Oh nice this was what I was also working on in the past, and it would ideally be used in future by the module itself to control module-only settings there without having to deal with pam config files. |
| var oldDBDir = consts.OldDBDir | ||
|
|
||
| // pamDDir is the directory containing PAM service configuration files. | ||
| var pamDDir = "/etc/pam.d" |
There was a problem hiding this comment.
Well, this can also be /usr/lib/pam.d, we don't have a dynamic way to figure it out though.
Thread the PAM service name (e.g. "sshd", "gdm-authd") through the gRPC SelectBroker call so authd can look it up later by session ID. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The auth_fail_* brute-force mitigation settings belong to the PAM
service, not to authd globally. They are now nested under pam: in
authd.yaml, and can be overridden per PAM service under pam.services:
pam:
auth_fail_delay: 2s
services:
sshd:
auth_fail_delay: 5s
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PAM service definitions may be installed in /usr/lib/pam.d rather than /etc/pam.d. Check both locations before warning that a configured per-service override has no matching PAM configuration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
60475ce to
c426f82
Compare
|
Ah, I found what I was sketching on, not sure if that gives some hints, but just leaving it as it was my package pam
const (
// SSHServiceName is the default PAM service name for sshd.
SSHServiceName = "sshd"
)
type ConfigValues struct {
DisableLocalStack bool `mapstructure:"disable_local_stack" yaml:"disable_local_stack"`
}
// Config is the configuration for the PAM service.
type Config struct {
ConfigValues `mapstructure:",squash" yaml:",inline"`
// TODO: Include here all the relevant PAM module `supportedArgs` values and
// providing them to the client via a new GetConfig GRPC request, thus
// only allow to override them from the PAM module side, since they may
// be useful for debugging.
// ServicesOverrides is a map containing the [ConfigValue] overrides for
// specific services.
ServicesOverrides map[string]ConfigValues `mapstructure:"services_overrides" yaml:"services_overrides"`
}
func (c Config) GetServiceConfigValues(serviceName string) ConfigValues {
so, ok := c.ServicesOverrides[serviceName]
if !ok {
return c.ConfigValues
}
// FIXME: Use reflect to iterate over values when we'll have more...
c.DisableLocalStack = so.DisableLocalStack
return c.ConfigValues
}
// DefaultConfig is the default configuration for the PAM service.
var DefaultConfig = Config{
ServicesOverrides: map[string]ConfigValues{SSHServiceName: {DisableLocalStack: true}},
}And that was used as per in commit 3v1n0@dab2981 |
The
auth_fail_*brute-force mitigation settings belong to the PAM service, not to authd globally. They are now nested underpam:inauthd.yaml, and can be overridden per PAM service: