@@ -64,9 +64,10 @@ const (
64
64
)
65
65
66
66
type registryConfigurator struct {
67
- guid string
68
- routingAll bool
69
- gpo bool
67
+ guid string
68
+ routingAll bool
69
+ gpo bool
70
+ nrptEntryCount int
70
71
}
71
72
72
73
func newHostManager (wgInterface WGIface ) (* registryConfigurator , error ) {
@@ -177,7 +178,11 @@ func (r *registryConfigurator) applyDNSConfig(config HostDNSConfig, stateManager
177
178
log .Infof ("removed %s as main DNS forwarder for this peer" , config .ServerIP )
178
179
}
179
180
180
- if err := stateManager .UpdateState (& ShutdownState {Guid : r .guid , GPO : r .gpo }); err != nil {
181
+ if err := stateManager .UpdateState (& ShutdownState {
182
+ Guid : r .guid ,
183
+ GPO : r .gpo ,
184
+ NRPTEntryCount : r .nrptEntryCount ,
185
+ }); err != nil {
181
186
log .Errorf ("failed to update shutdown state: %s" , err )
182
187
}
183
188
@@ -193,13 +198,24 @@ func (r *registryConfigurator) applyDNSConfig(config HostDNSConfig, stateManager
193
198
}
194
199
195
200
if len (matchDomains ) != 0 {
196
- if err := r .addDNSMatchPolicy (matchDomains , config .ServerIP ); err != nil {
201
+ count , err := r .addDNSMatchPolicy (matchDomains , config .ServerIP )
202
+ if err != nil {
197
203
return fmt .Errorf ("add dns match policy: %w" , err )
198
204
}
205
+ r .nrptEntryCount = count
199
206
} else {
200
207
if err := r .removeDNSMatchPolicies (); err != nil {
201
208
return fmt .Errorf ("remove dns match policies: %w" , err )
202
209
}
210
+ r .nrptEntryCount = 0
211
+ }
212
+
213
+ if err := stateManager .UpdateState (& ShutdownState {
214
+ Guid : r .guid ,
215
+ GPO : r .gpo ,
216
+ NRPTEntryCount : r .nrptEntryCount ,
217
+ }); err != nil {
218
+ log .Errorf ("failed to update shutdown state: %s" , err )
203
219
}
204
220
205
221
if err := r .updateSearchDomains (searchDomains ); err != nil {
@@ -220,28 +236,34 @@ func (r *registryConfigurator) addDNSSetupForAll(ip netip.Addr) error {
220
236
return nil
221
237
}
222
238
223
- func (r * registryConfigurator ) addDNSMatchPolicy (domains []string , ip netip.Addr ) error {
239
+ func (r * registryConfigurator ) addDNSMatchPolicy (domains []string , ip netip.Addr ) ( int , error ) {
224
240
// if the gpo key is present, we need to put our DNS settings there, otherwise our config might be ignored
225
241
// see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gpnrpt/8cc31cb9-20cb-4140-9e85-3e08703b4745
226
- if r .gpo {
227
- if err := r .configureDNSPolicy (gpoDnsPolicyConfigMatchPath , domains , ip ); err != nil {
228
- return fmt .Errorf ("configure GPO DNS policy: %w" , err )
242
+ for i , domain := range domains {
243
+ policyPath := fmt .Sprintf ("%s-%d" , dnsPolicyConfigMatchPath , i )
244
+ if r .gpo {
245
+ policyPath = fmt .Sprintf ("%s-%d" , gpoDnsPolicyConfigMatchPath , i )
229
246
}
230
247
248
+ singleDomain := []string {domain }
249
+
250
+ if err := r .configureDNSPolicy (policyPath , singleDomain , ip ); err != nil {
251
+ return i , fmt .Errorf ("configure DNS policy for domain %s: %w" , domain , err )
252
+ }
253
+
254
+ log .Debugf ("added NRPT entry for domain: %s" , domain )
255
+ }
256
+
257
+ if r .gpo {
231
258
if err := refreshGroupPolicy (); err != nil {
232
259
log .Warnf ("failed to refresh group policy: %v" , err )
233
260
}
234
- } else {
235
- if err := r .configureDNSPolicy (dnsPolicyConfigMatchPath , domains , ip ); err != nil {
236
- return fmt .Errorf ("configure local DNS policy: %w" , err )
237
- }
238
261
}
239
262
240
- log .Infof ("added %d match domains . Domain list: %s" , len (domains ), domains )
241
- return nil
263
+ log .Infof ("added %d separate NRPT entries . Domain list: %s" , len (domains ), domains )
264
+ return len ( domains ), nil
242
265
}
243
266
244
- // configureDNSPolicy handles the actual configuration of a DNS policy at the specified path
245
267
func (r * registryConfigurator ) configureDNSPolicy (policyPath string , domains []string , ip netip.Addr ) error {
246
268
if err := removeRegistryKeyFromDNSPolicyConfig (policyPath ); err != nil {
247
269
return fmt .Errorf ("remove existing dns policy: %w" , err )
@@ -374,12 +396,25 @@ func (r *registryConfigurator) restoreHostDNS() error {
374
396
375
397
func (r * registryConfigurator ) removeDNSMatchPolicies () error {
376
398
var merr * multierror.Error
399
+
400
+ // Try to remove the base entries (for backward compatibility)
377
401
if err := removeRegistryKeyFromDNSPolicyConfig (dnsPolicyConfigMatchPath ); err != nil {
378
- merr = multierror .Append (merr , fmt .Errorf ("remove local registry key : %w" , err ))
402
+ merr = multierror .Append (merr , fmt .Errorf ("remove local base entry : %w" , err ))
379
403
}
380
-
381
404
if err := removeRegistryKeyFromDNSPolicyConfig (gpoDnsPolicyConfigMatchPath ); err != nil {
382
- merr = multierror .Append (merr , fmt .Errorf ("remove GPO registry key: %w" , err ))
405
+ merr = multierror .Append (merr , fmt .Errorf ("remove GPO base entry: %w" , err ))
406
+ }
407
+
408
+ for i := 0 ; i < r .nrptEntryCount ; i ++ {
409
+ localPath := fmt .Sprintf ("%s-%d" , dnsPolicyConfigMatchPath , i )
410
+ gpoPath := fmt .Sprintf ("%s-%d" , gpoDnsPolicyConfigMatchPath , i )
411
+
412
+ if err := removeRegistryKeyFromDNSPolicyConfig (localPath ); err != nil {
413
+ merr = multierror .Append (merr , fmt .Errorf ("remove local entry %d: %w" , i , err ))
414
+ }
415
+ if err := removeRegistryKeyFromDNSPolicyConfig (gpoPath ); err != nil {
416
+ merr = multierror .Append (merr , fmt .Errorf ("remove GPO entry %d: %w" , i , err ))
417
+ }
383
418
}
384
419
385
420
if err := refreshGroupPolicy (); err != nil {
0 commit comments