Skip to content

Commit 2fa57f3

Browse files
committed
🐛 Bug fixes
1 parent 47fef76 commit 2fa57f3

19 files changed

+154
-105
lines changed

.vscode/launch.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
"${workspaceFolder}/dev/server.toml",
157157
"client",
158158
"add",
159-
"--common-name",
159+
"--client-common-name",
160160
"test2",
161161
// "--client-cert",
162162
// "${workspaceFolder}/dev/internal-client.crt",
@@ -198,7 +198,7 @@
198198
"${workspaceFolder}/dev/server.toml",
199199
"client",
200200
"remove",
201-
"--common-name",
201+
"--client-common-name",
202202
"test"
203203
]
204204
},

README.md

+45-12
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,46 @@ A Pluggable Authentication Module (PAM) and optional Name Service Switch (NSS) f
1313
### Setup
1414

1515
1. Download the latest release from the [releases page](https://github.com/wakeful-cloud/pam-oauth/releases)
16-
2. Extract/install the client on the client machine and the server on the server machine
16+
2. Extract/install the client on the client machine and the server on the server machine, for example:
17+
18+
```bash
19+
VERSION="X.Y.Z" # Get the latest semantic version (Without the "v" prefix!) from the releases page
20+
21+
# Debian/Ubuntu
22+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-client_${VERSION}_amd64.deb
23+
sudo dpkg -i pam-oauth-client_${VERSION}_amd64.deb
24+
25+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-server_${VERSION}_amd64.deb
26+
sudo dpkg -i pam-oauth-server_${VERSION}_amd64.deb
27+
28+
# Red Hat/CentOS
29+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-client-${VERSION}-1.x86_64.rpm
30+
sudo rpm -i pam-oauth-client-${VERSION}-1.x86_64.rpm
31+
32+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-server-${VERSION}-1.x86_64.rpm
33+
sudo rpm -i pam-oauth-server-${VERSION}-1.x86_64.rpm
34+
35+
# Arch Linux
36+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-client-${VERSION}-1-x86_64.pkg.tar.zst
37+
sudo pacman -U pam-oauth-client-${VERSION}-1-x86_64.pkg.tar.zst
38+
39+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-server-${VERSION}-1-x86_64.pkg.tar.zst
40+
sudo pacman -U pam-oauth-server-${VERSION}-1-x86_64.pkg.tar.zst
41+
42+
# Alpine Linux
43+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-client_${VERSION}_x86_64.apk
44+
sudo apk add pam-oauth-client_${VERSION}_x86_64.apk
45+
46+
wget -q https://github.com/Wakeful-Cloud/pam-oauth/releases/download/v${VERSION}/pam-oauth-server_${VERSION}_x86_64.apk
47+
sudo apk add pam-oauth-server_${VERSION}_x86_64.apk
48+
```
49+
1750
3. Initialize the server:
1851

1952
```bash
2053
# You will likely want to add the following flags so that clients can verify the server's TLS certificate in the future:
2154
# --server-common-name=hostname --server-dns-san=localhost --server-dns-san=<server hostname> --server-ip-san=127.0.0.1 --server-ip-san=::1 --server-ip-san=<server external IP>
22-
pam-oauth-server initialize
55+
sudo pam-oauth-server initialize
2356
```
2457

2558
4. Update the server configuration (e.g.: OAuth provider's details, listening address) in `/etc/pam-oauth/server.toml`
@@ -28,14 +61,14 @@ pam-oauth-server initialize
2861

2962
```bash
3063
# You will likely want to add the following flags so that the server can verify the client's TLS certificate in the future:
31-
# --dns-san=<client hostname> --ip-san=<client external IP>
32-
pam-oauth-server client add --common-name=test --client-cert=<path to client certificate> --client-key=<path to client key>
64+
# --client-dns-san=<client hostname> --client-ip-san=<client external IP>
65+
sudo pam-oauth-server client add --client-common-name=<client hostname> --client-cert=<path to client certificate> --client-key=<path to client key>
3366
```
3467

3568
6. Initialize the client:
3669

3770
```bash
38-
pam-oauth-client initialize
71+
sudo pam-oauth-client initialize
3972
```
4073

4174
7. Update the client configuration (e.g.: server's address) in `/etc/pam-oauth/client.toml`
@@ -44,16 +77,16 @@ pam-oauth-client initialize
4477

4578
```bash
4679
# If using systemd
47-
systemctl start pam-oauth-server
80+
sudo systemctl start pam-oauth-server
4881

4982
# Or manually
50-
pam-oauth-server serve
83+
sudo pam-oauth-server serve
5184
```
5285

5386
9. Update the PAM configuration (e.g.: `/etc/pam.d/sshd`):
5487

5588
```diff
56-
+ auth sufficient /path/to/pam_oauth.so [/path to client binary] --config [path to client config TOML] authenticate
89+
+ auth sufficient pam_oauth.so /usr/bin/pam-oauth-client --config /etc/pam-oauth/client.toml run
5790

5891
# All other auth rules
5992
@include common-auth
@@ -66,8 +99,8 @@ _Note: the `sufficient` keyword means that if this module succeeds, the rest of
6699
```diff
67100
- passwd: files systemd
68101
- group: files systemd
69-
+ passwd: files systemd pam_oauth
70-
+ group: files systemd pam_oauth
102+
+ passwd: files systemd oauth
103+
+ group: files systemd oauth
71104
```
72105

73106
11. Update the SSH server configuration (e.g.: `/etc/ssh/sshd_config`):
@@ -82,7 +115,7 @@ _Note: the `sufficient` keyword means that if this module succeeds, the rest of
82115
12. Restart the SSH server:
83116

84117
```bash
85-
systemctl restart sshd
118+
sudo systemctl restart sshd
86119
```
87120

88121
### Client Configuration
@@ -357,7 +390,7 @@ task package
357390
4. Add the client:
358391
359392
```bash
360-
./dist/bin/pam-oauth-server --config ./dev/server.toml client add --common-name test --client-cert ./dev/internal-client.crt --client-key ./dev/internal-client.key
393+
./dist/bin/pam-oauth-server --config ./dev/server.toml client add --client-common-name test --client-cert ./dev/internal-client.crt --client-key ./dev/internal-client.key
361394
```
362395
363396
5. Initialize the client:

Taskfile.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version: '3'
44

55
vars:
66
# The project version
7-
VERSION: '0.0.0'
7+
VERSION: '0.0.1'
88

99
# The current short Git commit hash
1010
COMMIT:

build/init/pam-oauth-server.service

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[Unit]
2+
Description=PAM OAuth server
3+
After=network.target
4+
5+
[Service]
6+
Type=simple
7+
Restart=always
8+
RestartSec=1
9+
10+
# Copy config and files to a folder before running (Which effectively grants read-only access to root files; see https://github.com/systemd/systemd/issues/16060#issuecomment-964168566)
11+
DynamicUser=yes
12+
RuntimeDirectory=pam-oauth-server
13+
ExecStartPre=+cp -r /etc/pam-oauth/. /run/pam-oauth-server/
14+
ExecStartPre=+bash -c "chown -R $(stat -c %%u /run/pam-oauth-server) /run/pam-oauth-server"
15+
ExecStartPre=+chmod -R 400 /run/pam-oauth-server
16+
17+
# Run the server
18+
ExecStart=/usr/bin/pam-oauth-server --config /run/pam-oauth-server/server.toml serve
19+
20+
# Hardening (See https://www.opensourcerers.org/2022/04/25/optimizing-a-systemd-service-for-security/ and https://gist.github.com/ageis/f5595e59b1cddb1513d1b425a323db04)
21+
DevicePolicy=closed
22+
LockPersonality=yes
23+
MemoryDenyWriteExecute=yes
24+
NoNewPrivileges=yes
25+
PrivateDevices=yes
26+
PrivateTmp=yes
27+
PrivateUsers=yes
28+
ProtectClock=yes
29+
ProtectControlGroups=yes
30+
ProtectHome=yes
31+
ProtectHostname=yes
32+
ProtectKernelLogs=yes
33+
ProtectKernelModules=yes
34+
ProtectKernelTunables=yes
35+
ProtectSystem=strict
36+
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
37+
RestrictNamespaces=yes
38+
RestrictRealtime=yes
39+
RestrictSUIDSGID=yes
40+
SecureBits=noroot-locked
41+
42+
[Install]
43+
WantedBy=multi-user.target

build/nfpm-server.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ contents:
3232
mode: 0600
3333

3434
# Systemd service
35-
- src: ./init/pam-oauth-server.service
35+
- src: ./build/init/pam-oauth-server.service
3636
dst: /lib/systemd/system/pam-oauth-server.service
3737
file_info:
3838
group: root
@@ -46,6 +46,8 @@ contents:
4646
group: root
4747
owner: root
4848
mode: 0644
49+
scripts:
50+
postinstall: ./build/scripts/postinstall-server.sh
4951
# rpm:
5052
# signature:
5153
# key_file: ${SIGNING_KEY_FILE}

build/scripts/postinstall-server.sh

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
3+
# Reload the Systemd daemon
4+
systemctl daemon-reload

cmd/client/run.go

+21
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ var runCmd = &cobra.Command{
3232
defer cleanup()
3333

3434
// Get information from the environment
35+
smType, err := client.GetType()
36+
37+
if err != nil {
38+
// Log
39+
slog.Error("failed to get type",
40+
slog.Any("error", err),
41+
)
42+
43+
return err
44+
}
45+
3546
username, err := client.GetUsername()
3647

3748
if err != nil {
@@ -43,6 +54,16 @@ var runCmd = &cobra.Command{
4354
return err
4455
}
4556

57+
// Skip non-authentication requests
58+
if smType != client.PAM_SM_AUTHENTICATE {
59+
// Log
60+
slog.Info("skipping non-authentication request",
61+
slog.String("type", string(smType)),
62+
)
63+
64+
return errSkipMethod
65+
}
66+
4667
// Initialize the client
4768
internalClient, err := client.NewInternalClient(config.InternalClientConfig)
4869

cmd/server/add_client.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ func init() {
105105
clientCmd.AddCommand(addClientCmd)
106106

107107
// Register the flags
108-
addClientCmd.Flags().StringVar(&addClientCommonName, "common-name", "", "Common Name (CN)")
109-
addClientCmd.Flags().StringSliceVar(&addClientDnsSans, "dns-san", []string{}, "DNS Subject Alternative Name (SAN)")
110-
addClientCmd.Flags().StringSliceVar(&addClientIpSans, "ip-san", []string{}, "IP Subject Alternative Name (SAN)")
108+
addClientCmd.Flags().StringVar(&addClientCommonName, "client-common-name", "", "Client Common Name (CN)")
109+
addClientCmd.Flags().StringSliceVar(&addClientDnsSans, "client-dns-san", []string{}, "Client DNS Subject Alternative Name (SAN)")
110+
addClientCmd.Flags().StringSliceVar(&addClientIpSans, "client-ip-san", []string{}, "Client IP Subject Alternative Name (SAN)")
111111
addClientCmd.Flags().StringVar(&addClientClientCertPath, "client-cert", "stdout", "Client certificate path")
112112
addClientCmd.Flags().StringVar(&addClientClientKeyPath, "client-key", "stdout", "Client key path")
113113

114114
// Mark the flags as required
115-
err := addClientCmd.MarkFlagRequired("common-name")
115+
err := addClientCmd.MarkFlagRequired("client-common-name")
116116

117117
if err != nil {
118118
panic(err)

cmd/server/initialize.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func init() {
6060
// Register the flags
6161
initializeCmd.Flags().BoolVar(&initializeOverwrite, "overwrite", false, "Overwrite existing files")
6262
initializeCmd.Flags().BoolVar(&initializeConfig, "initialize-config", true, "Initialize the configuration")
63-
initializeCmd.Flags().BoolVar(&initializeInternalServerPki, "initialize-internal-server-pki", true, "Initialize the internal server PKI")
63+
initializeCmd.Flags().BoolVar(&initializeInternalServerPki, "initialize-server-pki", true, "Initialize the internal server PKI")
6464
initializeCmd.Flags().StringVar(&initializeServerCommonName, "server-common-name", "localhost", "Internal server common name")
6565
initializeCmd.Flags().StringSliceVar(&initializeServerDnsSans, "server-dns-san", []string{"localhost"}, "Internal server DNS Subject Alternative Name (SAN)")
6666
initializeCmd.Flags().StringSliceVar(&initializeServerIpSans, "server-ip-san", []string{"127.0.0.1", "::1"}, "Internal server IP Subject Alternative Name (SAN)")

cmd/server/list_clients.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var listClientCmd = &cobra.Command{
1919
// Print the clients
2020
err := gout.Print(lo.Map(config.InternalServerConfig.ClientAllowList.GetEntries(), func(entry *x509.Certificate, _ int) map[string]any {
2121
return map[string]any{
22-
"common_name": entry.Subject.CommonName,
22+
"subject": entry.Subject.String(),
2323
"issuer": entry.Issuer.String(),
2424
"serial": entry.SerialNumber.String(),
2525
"signature": hex.EncodeToString(entry.Signature),

cmd/server/remove_client.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ func init() {
4141
clientCmd.AddCommand(removeClientCmd)
4242

4343
// Register the flags
44-
removeClientCmd.Flags().StringVar(&removeClientCommonName, "common-name", "", "Client common name")
44+
removeClientCmd.Flags().StringVar(&removeClientCommonName, "client-common-name", "", "Client common name")
4545

4646
// Mark the flags as required
47-
err := removeClientCmd.MarkFlagRequired("common-name")
47+
err := removeClientCmd.MarkFlagRequired("client-common-name")
4848

4949
if err != nil {
5050
panic(err)

go.mod

-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ require (
1616
github.com/pelletier/go-toml/v2 v2.1.1
1717
github.com/samber/lo v1.38.1
1818
github.com/samber/slog-echo v1.12.1
19-
github.com/samber/slog-syslog/v2 v2.1.0
2019
github.com/spf13/cobra v1.8.0
2120
golang.org/x/crypto v0.19.0
2221
golang.org/x/oauth2 v0.17.0
@@ -38,7 +37,6 @@ require (
3837
github.com/mattn/go-isatty v0.0.20 // indirect
3938
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4039
github.com/russross/blackfriday/v2 v2.1.0 // indirect
41-
github.com/samber/slog-common v0.14.0 // indirect
4240
github.com/spf13/pflag v1.0.5 // indirect
4341
github.com/valyala/bytebufferpool v1.0.0 // indirect
4442
github.com/valyala/fasttemplate v1.2.2 // indirect

go.sum

-4
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
7070
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
7171
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
7272
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
73-
github.com/samber/slog-common v0.14.0 h1:g4TGALXmqogbJu3epRhjIWUJKSpgqB9VyN2OEnS8Wyg=
74-
github.com/samber/slog-common v0.14.0/go.mod h1:Qjrfhwk79XiCIhBj8+jTq1Cr0u9rlWbjawh3dWXzaHk=
7573
github.com/samber/slog-echo v1.12.1 h1:TgpA4luiqe2sa6SDsraM1hUcLAXF8ZofjXM0SzIJkJc=
7674
github.com/samber/slog-echo v1.12.1/go.mod h1:/f78pHjVxGrIlHlS5fzWiW+BxkWltQ+SWKk8LKMjAMQ=
77-
github.com/samber/slog-syslog/v2 v2.1.0 h1:90UFePPjsLK7RG2pdkLVG2fjpg5QTIi55uC1ngelq8M=
78-
github.com/samber/slog-syslog/v2 v2.1.0/go.mod h1:/1Y0U4qCKuN4/uj6adIOCszCWLMWMjLyVj91yP8bNvI=
7975
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
8076
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
8177
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=

init/pam-oauth-server.service

-38
This file was deleted.

internal/client/config.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ type InternalClientConfig struct {
3333
// LogConfig is the logging configuration
3434
type LogConfig struct {
3535
File string `toml:"file" comment:"Log file (if output is file)" default:"/var/log/pam-oauth-client.log"`
36-
Level common.LogLevel `toml:"level" comment:"Log level" default:"info"`
37-
Output common.LogOutput `toml:"output" comment:"Log output" default:"stderr"`
36+
Level common.LogLevel `toml:"level" comment:"Log level (One of debug, info, warn, or error)" default:"info"`
37+
Output common.LogOutput `toml:"output" comment:"Log output (One of file, stdout, or stderr)" default:"stderr"`
3838
}
3939

4040
// PromptConfig is the prompt configuration

0 commit comments

Comments
 (0)