Skip to content

Commit 96859a3

Browse files
committed
P:puppet::server: Restrict CA operations to CA server
Use Puppet's auth configuration to ensure CA operations only happen from the active CA server, instead of the default (certs with the "pp_cli_auth" extension, so in practice any Puppet server).
1 parent 7528040 commit 96859a3

File tree

2 files changed

+248
-1
lines changed

2 files changed

+248
-1
lines changed

modules/profile/manifests/puppet/server.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
Concat::Fragment <| target == $::profile::puppet::common::config_file |> ~> Service['puppetserver']
161161
Concat[$::profile::puppet::common::config_file] ~> Service['puppetserver']
162162

163-
['puppetserver.conf'].each |String $file| {
163+
['auth.conf', 'puppetserver.conf'].each |String $file| {
164164
$puppet_agent_base_path = $profile::puppet::common::config_path
165165
file { "${server_config_path}/conf.d/${file}":
166166
ensure => file,
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
authorization: {
2+
version: 1
3+
rules: [
4+
{
5+
# Allow nodes to retrieve their own catalog
6+
match-request: {
7+
path: "^/puppet/v3/catalog/([^/]+)$"
8+
type: regex
9+
method: [get, post]
10+
}
11+
allow: "$1"
12+
sort-order: 500
13+
name: "puppetlabs v3 catalog from agents"
14+
},
15+
{
16+
# Allow services to retrieve catalogs on behalf of others
17+
match-request: {
18+
path: "^/puppet/v4/catalog/?$"
19+
type: regex
20+
method: post
21+
}
22+
deny: "*"
23+
sort-order: 500
24+
name: "puppetlabs v4 catalog for services"
25+
},
26+
{
27+
# Allow nodes to retrieve the certificate they requested earlier
28+
match-request: {
29+
path: "/puppet-ca/v1/certificate/"
30+
type: path
31+
method: get
32+
}
33+
allow-unauthenticated: true
34+
sort-order: 500
35+
name: "puppetlabs certificate"
36+
},
37+
{
38+
# Allow all nodes to access the certificate revocation list
39+
match-request: {
40+
path: "/puppet-ca/v1/certificate_revocation_list/ca"
41+
type: path
42+
method: get
43+
}
44+
allow-unauthenticated: true
45+
sort-order: 500
46+
name: "puppetlabs crl"
47+
},
48+
{
49+
# Allow nodes to request a new certificate
50+
match-request: {
51+
path: "/puppet-ca/v1/certificate_request"
52+
type: path
53+
method: [get, put]
54+
}
55+
allow-unauthenticated: true
56+
sort-order: 500
57+
name: "puppetlabs csr"
58+
},
59+
{
60+
# Allow the CA CLI to access the certificate_status endpoint
61+
match-request: {
62+
path: "/puppet-ca/v1/certificate_status"
63+
type: path
64+
method: [get, put, delete]
65+
}
66+
allow: "<%= @primary_host %>"
67+
sort-order: 500
68+
name: "puppetlabs cert status"
69+
},
70+
{
71+
match-request: {
72+
path: "^/puppet-ca/v1/certificate_revocation_list$"
73+
type: regex
74+
method: put
75+
}
76+
allow: "<%= @primary_host %>"
77+
sort-order: 500
78+
name: "puppetlabs CRL update"
79+
},
80+
{
81+
# Allow the CA CLI to access the certificate_statuses endpoint
82+
match-request: {
83+
path: "/puppet-ca/v1/certificate_statuses"
84+
type: path
85+
method: get
86+
}
87+
allow: "<%= @primary_host %>"
88+
sort-order: 500
89+
name: "puppetlabs cert statuses"
90+
},
91+
{
92+
# Allow authenticated access to the CA expirations endpoint
93+
match-request: {
94+
path: "/puppet-ca/v1/expirations"
95+
type: path
96+
method: get
97+
}
98+
allow: "*"
99+
sort-order: 500
100+
name: "puppetlabs CA cert and CRL expirations"
101+
},
102+
{
103+
# Allow the CA CLI to access the certificate clean endpoint
104+
match-request: {
105+
path: "/puppet-ca/v1/clean"
106+
type: path
107+
method: put
108+
}
109+
allow: "<%= @primary_host %>"
110+
sort-order: 500
111+
name: "puppetlabs cert clean"
112+
},
113+
{
114+
# Allow unauthenticated access to the status service endpoint
115+
match-request: {
116+
path: "/status/v1/services"
117+
type: path
118+
method: get
119+
}
120+
allow-unauthenticated: true
121+
sort-order: 500
122+
name: "puppetlabs status service - full"
123+
},
124+
{
125+
match-request: {
126+
path: "/status/v1/simple"
127+
type: path
128+
method: get
129+
}
130+
allow-unauthenticated: true
131+
sort-order: 500
132+
name: "puppetlabs status service - simple"
133+
},
134+
{
135+
match-request: {
136+
path: "/puppet/v3/environments"
137+
type: path
138+
method: get
139+
}
140+
allow: "*"
141+
sort-order: 500
142+
name: "puppetlabs environments"
143+
},
144+
{
145+
# Allow nodes to access all file_bucket_files. Note that access for
146+
# the 'delete' method is forbidden by Puppet regardless of the
147+
# configuration of this rule.
148+
match-request: {
149+
path: "/puppet/v3/file_bucket_file"
150+
type: path
151+
method: [get, head, post, put]
152+
}
153+
allow: "*"
154+
sort-order: 500
155+
name: "puppetlabs file bucket file"
156+
},
157+
{
158+
# Allow nodes to access all file_content. Note that access for the
159+
# 'delete' method is forbidden by Puppet regardless of the
160+
# configuration of this rule.
161+
match-request: {
162+
path: "/puppet/v3/file_content"
163+
type: path
164+
method: [get, post]
165+
}
166+
allow: "*"
167+
sort-order: 500
168+
name: "puppetlabs file content"
169+
},
170+
{
171+
# Allow nodes to access all file_metadata. Note that access for the
172+
# 'delete' method is forbidden by Puppet regardless of the
173+
# configuration of this rule.
174+
match-request: {
175+
path: "/puppet/v3/file_metadata"
176+
type: path
177+
method: [get, post]
178+
}
179+
allow: "*"
180+
sort-order: 500
181+
name: "puppetlabs file metadata"
182+
},
183+
{
184+
# Allow nodes to retrieve only their own node definition
185+
match-request: {
186+
path: "^/puppet/v3/node/([^/]+)$"
187+
type: regex
188+
method: get
189+
}
190+
allow: "$1"
191+
sort-order: 500
192+
name: "puppetlabs node"
193+
},
194+
{
195+
# Allow nodes to store only their own reports
196+
match-request: {
197+
path: "^/puppet/v3/report/([^/]+)$"
198+
type: regex
199+
method: put
200+
}
201+
allow: "$1"
202+
sort-order: 500
203+
name: "puppetlabs report"
204+
},
205+
{
206+
# Allow nodes to update their own facts
207+
match-request: {
208+
path: "^/puppet/v3/facts/([^/]+)$"
209+
type: regex
210+
method: put
211+
}
212+
allow: "$1"
213+
sort-order: 500
214+
name: "puppetlabs facts"
215+
},
216+
{
217+
match-request: {
218+
path: "/puppet/v3/static_file_content"
219+
type: path
220+
method: get
221+
}
222+
allow: "*"
223+
sort-order: 500
224+
name: "puppetlabs static file content"
225+
},
226+
{
227+
match-request: {
228+
path: "/puppet/v3/tasks"
229+
type: path
230+
}
231+
allow: "*"
232+
sort-order: 500
233+
name: "puppet tasks information"
234+
},
235+
{
236+
# Deny everything else. This ACL is not strictly
237+
# necessary, but illustrates the default policy
238+
match-request: {
239+
path: "/"
240+
type: path
241+
}
242+
deny: "*"
243+
sort-order: 999
244+
name: "puppetlabs deny all"
245+
}
246+
]
247+
}

0 commit comments

Comments
 (0)