-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.ini
More file actions
338 lines (293 loc) · 10.8 KB
/
config.ini
File metadata and controls
338 lines (293 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# =============================================================================
# PAM SSH 2FA Configuration File
# =============================================================================
#
# This file configures the PAM SSH 2FA push notification module.
# Location: /etc/pam-ssh-2fa/config.ini
#
# After making changes, no restart is required - changes take effect on
# the next SSH authentication attempt.
#
# SECURITY NOTE: This file may contain sensitive URLs with API keys.
# Ensure permissions are set to 0600 (owner read/write only):
# chmod 600 /etc/pam-ssh-2fa/config.ini
#
# =============================================================================
# PER-USER CONFIGURATION
# =============================================================================
#
# Different users can receive codes via different notification services.
# Create per-user config files in: /etc/pam-ssh-2fa/users/
#
# File naming: <username>.conf (e.g., doug.conf, ben.conf)
#
# Per-user files only need the [notifications] section:
#
# # /etc/pam-ssh-2fa/users/doug.conf
# [notifications]
# apprise_urls = pover://DOUG_USER_KEY@APP_TOKEN
#
# # /etc/pam-ssh-2fa/users/ben.conf
# [notifications]
# apprise_urls = ntfy://ntfy.sh/ben-secret-topic
#
# If a user has no personal config, the global settings below are used.
# Per-user configs can only override notification settings (not security
# settings like timeouts or bypass lists).
#
# =============================================================================
# -----------------------------------------------------------------------------
# GENERAL SETTINGS
# -----------------------------------------------------------------------------
[general]
# Enable debug logging for troubleshooting
# When true, detailed logs are written including code hashes (not codes)
# Set to false in production for cleaner logs
# Valid values: true, false, yes, no, 1, 0
debug = false
# Log file location
# Directory will be created if it doesn't exist
# Logs include timestamps, authentication events, and errors
# Also logs to syslog AUTH facility regardless of this setting
log_file = /var/log/pam-ssh-2fa.log
# -----------------------------------------------------------------------------
# CODE SETTINGS
# -----------------------------------------------------------------------------
[codes]
# Length of the generated OTP code (number of digits)
# Longer codes are more secure but harder to type
# Recommended: 6 (standard TOTP length)
# Valid range: 4-10
length = 4
# Code validity timeout in seconds
# After this time, the code expires and user must reconnect
# Balance between security (shorter) and usability (longer)
# Recommended: 300 (5 minutes)
# Valid range: 60-900
timeout = 300
# Maximum number of attempts to enter the code
# After this many failures, authentication fails completely
# Protects against brute force attempts
# Recommended: 3
# Valid range: 1-10
max_attempts = 3
# Directory for temporary code storage
# Codes are stored here between generation and validation
# Should be on tmpfs/ramfs if possible for security
# Directory is created with 0700 permissions
storage_dir = /var/run/pam-ssh-2fa
# -----------------------------------------------------------------------------
# NOTIFICATION SETTINGS
# -----------------------------------------------------------------------------
[notifications]
# Apprise notification URLs (comma-separated)
#
# Apprise supports 80+ notification services. Common examples:
#
# ntfy (self-hosted or ntfy.sh):
# ntfy://ntfy.sh/your-topic-name
# ntfy://your-server.com/your-topic
# ntfys://your-server.com/your-topic (HTTPS)
#
# Pushover:
# pover://user-key@app-token
#
# Telegram:
# tgram://bot-token/chat-id
#
# Slack:
# slack://token-a/token-b/token-c/#channel
#
# Discord:
# discord://webhook-id/webhook-token
#
# Email (SMTP):
# mailto://user:password@smtp.example.com?to=you@example.com
#
# Gotify:
# gotify://hostname/token
# gotifys://hostname/token (HTTPS)
#
# Pushbullet:
# pbul://access-token
#
# Signal (via signal-cli-rest-api):
# signal://hostname:port/from/to
#
# For full list and URL formats, see:
# https://github.com/caronc/apprise/wiki
#
# Multiple URLs can be specified for redundancy (notification sent to all):
# apprise_urls = ntfy://ntfy.sh/my-ssh-codes, pover://user@token
#
# SECURITY: Keep this file secure as URLs may contain API keys!
#
apprise_urls =
# Notification title template
# Available variables: {code}, {link}, {user}, {host}, {rhost}, {timeout}
title = SSH Login
# Notification body template for CODE-ONLY authentication
# Used when auth_method = code
body = Your SSH verification code is: {code}
Host: {host}
User: {user}
From: {rhost}
This code expires in {timeout} minutes.
# Notification body template for LINK-ONLY authentication
# Used when auth_method = link
body_link = Click to approve SSH login:
{link}
Host: {host}
User: {user}
From: {rhost}
This link expires in {timeout} minutes.
# Notification body template for BOTH code and link
# Used when auth_method = both
body_both = SSH Login for {user}@{host}
Click to approve:
{link}
Or enter code: {code}
From: {rhost}
Expires in {timeout} minutes.
# -----------------------------------------------------------------------------
# APPROVAL SERVER SETTINGS
# -----------------------------------------------------------------------------
# Required for link-based authentication (auth_method = link or both)
[server]
# Port the approval server listens on
# Make sure this port is open in your firewall
port = 9110
# Public URL where the approval server can be reached
# This URL is included in notification links - it must be reachable from
# the user's phone (public IP, hostname, or Tailscale/VPN address)
#
# Examples:
# url = http://203.0.113.50:9110
# url = http://myserver.example.com:9110
# url = http://myserver.tailnet-name.ts.net:9110
#
# IMPORTANT: This must be set for link-based authentication to work!
url =
# Log file for the approval server (separate from PAM module log)
log_file = /var/log/pam-ssh-2fa-server.log
# -----------------------------------------------------------------------------
# USER INTERFACE MESSAGES
# -----------------------------------------------------------------------------
[messages]
# Prompt shown when asking user to enter the code (auth_method = code)
prompt = Enter verification code:
# Prompt shown for combined auth (auth_method = both)
# User can either type code or press Enter after clicking link
prompt_both = Enter code OR press Enter after clicking link:
# Message shown on successful verification
success = Verification successful.
# Message shown when verification fails (after all attempts)
failure = Verification failed. Access denied.
# Message shown when code has expired
expired = Code expired. Please reconnect to receive a new code.
# -----------------------------------------------------------------------------
# BYPASS SETTINGS
# -----------------------------------------------------------------------------
# Use these to skip 2FA for certain users or networks.
# Be careful - bypassed connections only use single-factor authentication!
[bypass]
# Users to bypass 2FA (comma-separated)
# Useful for:
# - Service accounts (ansible, backup, monitoring)
# - Emergency access accounts
# - Users who can't receive push notifications
#
# Example: users = ansible, backup, nagios
users =
# Networks to bypass 2FA (comma-separated CIDR notation)
# Useful for:
# - Trusted internal networks
# - VPN connections
# - Management networks
#
# Example: networks = 192.168.1.0/24, 10.0.0.0/8, 172.16.0.0/12
# Use with caution - this trusts the entire network!
networks =
# -----------------------------------------------------------------------------
# USER CONFIGURATION SETTINGS
# -----------------------------------------------------------------------------
# Control how users without per-user config files are handled.
[users]
# Allow unconfigured users
# Controls what happens when a user has no notification URLs configured
# (no per-user config file AND no global apprise_urls).
#
# false (default) - Users without config are DENIED access
# true - Users without config BYPASS 2FA (less secure)
#
# When false (recommended for production):
# - Only users with a config file in /etc/pam-ssh-2fa/users/<username>.conf
# OR a global apprise_urls setting can authenticate
# - Unknown users are rejected with "2FA not configured for this user"
#
# When true (useful during rollout):
# - Users without notification config skip 2FA entirely
# - Allows gradual rollout by adding users one at a time
# - WARNING: This reduces security for unconfigured users!
#
allow_unconfigured_users = false
# Default authentication method
# This is the default for users without a per-user config that specifies
# a different auth_method. Can be overridden in per-user config files.
#
# Options:
# code - Send a 4-digit code, user types it in (default)
# link - Send an approval link, user clicks it on their phone
# both - Send both code and link, user can use either method
# none - Skip 2FA for this user (same as adding to bypass list)
#
# For "link" and "both" to work, you must configure the [server] section.
#
auth_method = code
# =============================================================================
# EXAMPLE CONFIGURATIONS
# =============================================================================
#
# Example 1: ntfy.sh (free, no account needed)
# --------------------------------------------
# [notifications]
# apprise_urls = ntfy://ntfy.sh/my-secret-ssh-codes-abc123
#
# Note: Anyone who knows your topic name can subscribe to it.
# Use a long, random topic name for security.
# For private notifications, self-host ntfy or use authentication.
#
#
# Example 2: Pushover (recommended, $5 one-time)
# ----------------------------------------------
# [notifications]
# apprise_urls = pover://USERKEY@APPTOKEN
#
# Get credentials at https://pushover.net
# User Key: Found in your Pushover dashboard
# App Token: Create an application in your Pushover account
#
#
# Example 3: Multiple services (redundancy)
# -----------------------------------------
# [notifications]
# apprise_urls = ntfy://ntfy.sh/my-topic, pover://user@token
#
# Notification sent to both services. If one fails, the other may succeed.
#
#
# Example 4: Self-hosted ntfy with authentication
# -----------------------------------------------
# [notifications]
# apprise_urls = ntfys://user:password@ntfy.example.com/ssh-codes
#
#
# Example 5: Telegram bot
# -----------------------
# [notifications]
# apprise_urls = tgram://123456789:ABCdefGHIjklMNOpqrsTUVwxyz/987654321
#
# Bot token: Get from @BotFather
# Chat ID: Get from @userinfobot or @getidsbot
#
# =============================================================================