@@ -26,6 +26,7 @@ import (
26
26
"os/signal"
27
27
"runtime"
28
28
"strings"
29
+ "sync"
29
30
"syscall"
30
31
"time"
31
32
)
46
47
47
48
MetricsAddr = flag .String ("metrics.addr" , ":8080" , "Metrics address" )
48
49
MetricsPath = flag .String ("metrics.path" , "/metrics" , "Metrics path" )
49
- RTRVersion = flag .Int ("protocol" , 1 , "RTR protocol version" )
50
+
51
+ ExportPath = flag .String ("export.path" , "/rpki.json" , "Export path" )
52
+ ExportSign = flag .String ("export.sign" , "" , "Sign export with key" )
53
+
54
+ RTRVersion = flag .Int ("protocol" , 1 , "RTR protocol version" )
50
55
51
56
Bind = flag .String ("bind" , ":8282" , "Bind address" )
52
57
75
80
MaxConn = flag .Int ("maxconn" , 0 , "Max simultaneous connections (0 to disable limit)" )
76
81
SendNotifs = flag .Bool ("notifications" , true , "Send notifications to clients" )
77
82
83
+ Slurm = flag .String ("slurm" , "" , "Slurm configuration file (filters and assertions)" )
84
+ SlurmRefresh = flag .Bool ("slurm.refresh" , true , "Refresh along the cache" )
85
+
78
86
LogLevel = flag .String ("loglevel" , "info" , "Log level" )
79
87
Version = flag .Bool ("version" , false , "Print version" )
80
88
@@ -201,15 +209,15 @@ func decodeJSON(data []byte) (*prefixfile.ROAList, error) {
201
209
return & roalistjson , err
202
210
}
203
211
204
- func processData (roalistjson * prefixfile.ROAList ) ([]rtr.ROA , int , int , int ) {
212
+ func processData (roalistjson [] prefixfile.ROAJson ) ([]rtr.ROA , int , int , int ) {
205
213
filterDuplicates := make (map [string ]bool )
206
214
207
215
roalist := make ([]rtr.ROA , 0 )
208
216
209
217
var count int
210
218
var countv4 int
211
219
var countv6 int
212
- for _ , v := range roalistjson . Data {
220
+ for _ , v := range roalistjson {
213
221
prefix , err := v .GetPrefix2 ()
214
222
if err != nil {
215
223
log .Error (err )
@@ -300,7 +308,37 @@ func (s *state) updateFile(file string) error {
300
308
log .Debugf ("Signature verified" )
301
309
}
302
310
303
- roas , count , countv4 , countv6 := processData (roalistjson )
311
+ roasjson := roalistjson .Data
312
+ if s .slurm != nil {
313
+ kept , removed := s .slurm .FilterOnROAs (roasjson )
314
+ asserted := s .slurm .AssertROAs ()
315
+ log .Infof ("Slurm filtering: %v kept, %v removed, %v asserted" , len (kept ), len (removed ), len (asserted ))
316
+ roasjson = append (kept , asserted ... )
317
+ }
318
+ s .lockJson .Lock ()
319
+ s .exported = prefixfile.ROAList {
320
+ Metadata : prefixfile.MetaData {
321
+ Counts : len (roasjson ),
322
+ Generated : roalistjson .Metadata .Generated ,
323
+ Valid : roalistjson .Metadata .Valid ,
324
+ /*Signature: roalistjson.Metadata.Signature,
325
+ SignatureDate: roalistjson.Metadata.SignatureDate,*/
326
+ },
327
+ Data : roasjson ,
328
+ }
329
+
330
+ if s .key != nil {
331
+ signdate , sign , err := s .exported .Sign (s .key )
332
+ if err != nil {
333
+ log .Error (err )
334
+ }
335
+ s .exported .Metadata .Signature = sign
336
+ s .exported .Metadata .SignatureDate = signdate
337
+ }
338
+
339
+ s .lockJson .Unlock ()
340
+
341
+ roas , count , countv4 , countv6 := processData (roasjson )
304
342
if err != nil {
305
343
return err
306
344
}
@@ -333,8 +371,26 @@ func (s *state) updateFile(file string) error {
333
371
return nil
334
372
}
335
373
336
- func (s * state ) routineUpdate (file string , interval int ) {
337
- log .Debugf ("Starting refresh routine (file: %v, interval: %vs)" , file , interval )
374
+ func (s * state ) updateSlurm (file string ) error {
375
+ log .Debugf ("Refreshing slurm from %v" , file )
376
+ data , err := fetchFile (file , s .userAgent )
377
+ if err != nil {
378
+ log .Error (err )
379
+ return err
380
+ }
381
+
382
+ buf := bytes .NewBuffer (data )
383
+
384
+ slurm , err := prefixfile .DecodeJSONSlurm (buf )
385
+ if err != nil {
386
+ return err
387
+ }
388
+ s .slurm = slurm
389
+ return nil
390
+ }
391
+
392
+ func (s * state ) routineUpdate (file string , interval int , slurmFile string ) {
393
+ log .Debugf ("Starting refresh routine (file: %v, interval: %vs, slurm: %v)" , file , interval , slurmFile )
338
394
signals := make (chan os.Signal , 1 )
339
395
signal .Notify (signals , syscall .SIGHUP )
340
396
for {
@@ -345,6 +401,12 @@ func (s *state) routineUpdate(file string, interval int) {
345
401
log .Debug ("Received HUP signal" )
346
402
}
347
403
delay .Stop ()
404
+ if slurmFile != "" {
405
+ err := s .updateSlurm (slurmFile )
406
+ if err != nil {
407
+ log .Errorf ("Slurm: %v" , err )
408
+ }
409
+ }
348
410
err := s .updateFile (file )
349
411
if err != nil {
350
412
switch err .(type ) {
@@ -357,6 +419,14 @@ func (s *state) routineUpdate(file string, interval int) {
357
419
}
358
420
}
359
421
422
+ func (s * state ) exporter (wr http.ResponseWriter , r * http.Request ) {
423
+ s .lockJson .RLock ()
424
+ toExport := s .exported
425
+ s .lockJson .RUnlock ()
426
+ enc := json .NewEncoder (wr )
427
+ enc .Encode (toExport )
428
+ }
429
+
360
430
type state struct {
361
431
lastdata []byte
362
432
lastconverted []byte
@@ -369,6 +439,12 @@ type state struct {
369
439
370
440
metricsEvent * metricsEvent
371
441
442
+ exported prefixfile.ROAList
443
+ lockJson * sync.RWMutex
444
+ key * ecdsa.PrivateKey
445
+
446
+ slurm * prefixfile.SlurmConfig
447
+
372
448
pubkey * ecdsa.PublicKey
373
449
verify bool
374
450
checktime bool
@@ -420,6 +496,19 @@ func ReadPublicKey(key []byte, isPem bool) (*ecdsa.PublicKey, error) {
420
496
return kconv , nil
421
497
}
422
498
499
+ func ReadKey (key []byte , isPem bool ) (* ecdsa.PrivateKey , error ) {
500
+ if isPem {
501
+ block , _ := pem .Decode (key )
502
+ key = block .Bytes
503
+ }
504
+
505
+ k , err := x509 .ParseECPrivateKey (key )
506
+ if err != nil {
507
+ return nil , err
508
+ }
509
+ return k , nil
510
+ }
511
+
423
512
func main () {
424
513
runtime .GOMAXPROCS (runtime .NumCPU ())
425
514
@@ -443,10 +532,11 @@ func main() {
443
532
}
444
533
445
534
var me * metricsEvent
535
+ var enableHTTP bool
446
536
if * MetricsAddr != "" {
447
537
initMetrics ()
448
- go metricHTTP ()
449
538
me = & metricsEvent {}
539
+ enableHTTP = true
450
540
}
451
541
452
542
server := rtr .NewServer (sc , me , deh )
@@ -473,6 +563,31 @@ func main() {
473
563
verify : * Verify ,
474
564
checktime : * TimeCheck ,
475
565
userAgent : * UserAgent ,
566
+ lockJson : & sync.RWMutex {},
567
+ }
568
+
569
+ if * ExportSign != "" {
570
+ keyFile , err := os .Open (* ExportSign )
571
+ if err != nil {
572
+ log .Fatal (err )
573
+ }
574
+ keyBytes , err := ioutil .ReadAll (keyFile )
575
+ if err != nil {
576
+ log .Fatal (err )
577
+ }
578
+ keyFile .Close ()
579
+ keyDec , err := ReadKey (keyBytes , true )
580
+ if err != nil {
581
+ log .Fatal (err )
582
+ }
583
+ s .key = keyDec
584
+ }
585
+
586
+ if enableHTTP {
587
+ if * ExportPath != "" {
588
+ http .HandleFunc (* ExportPath , s .exporter )
589
+ }
590
+ go metricHTTP ()
476
591
}
477
592
478
593
if * Bind == "" && * BindTLS == "" && * BindSSH == "" {
@@ -589,6 +704,17 @@ func main() {
589
704
}()
590
705
}
591
706
707
+ slurmFile := * Slurm
708
+ if slurmFile != "" {
709
+ err := s .updateSlurm (slurmFile )
710
+ if err != nil {
711
+ log .Errorf ("Slurm: %v" , err )
712
+ }
713
+ if ! * SlurmRefresh {
714
+ slurmFile = ""
715
+ }
716
+ }
717
+
592
718
err := s .updateFile (* CacheBin )
593
719
if err != nil {
594
720
switch err .(type ) {
@@ -598,6 +724,6 @@ func main() {
598
724
log .Errorf ("Error updating: %v" , err )
599
725
}
600
726
}
601
- s .routineUpdate (* CacheBin , * RefreshInterval )
727
+ s .routineUpdate (* CacheBin , * RefreshInterval , slurmFile )
602
728
603
729
}
0 commit comments