Listen for events and forward to external security scanning services.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package main // import "git.openstack.org/openstack/osel"
  2. import (
  3. "log"
  4. "net/url"
  5. "os"
  6. "time"
  7. "github.com/fsnotify/fsnotify"
  8. "github.com/nate-johnston/viper"
  9. )
  10. // OselVersion is exposed in the logged JSON in the "source_type" field. This
  11. // will allow us to track the version of the logging specification.
  12. // 1.0: Initial revision
  13. // 1.1: Added qualys_scan_id and qualys_scan_error
  14. const OselVersion = "osel1.1"
  15. // Debug is a global variable to toggle debug logging
  16. var Debug bool
  17. // RabbitMQ URI
  18. var rabbitURI string
  19. func main() {
  20. // Declare the configuration
  21. viperConfigs := []ViperConfig{
  22. ViperConfig{Key: "batch_interval", Description: "Interval of time in minutes for message batching"},
  23. ViperConfig{Key: "debug", Description: "Output additional messages for debugging"},
  24. ViperConfig{Key: "rabbit_uri", Description: "AMQP connection uri. See: https://www.rabbitmq.com/uri-spec.html"},
  25. ViperConfig{Key: "openstack.identity_endpoint", Description: "Openstack Keystone Endpoint"},
  26. ViperConfig{Key: "openstack.user", Description: "Openstack user that has at least read only access to all tenants/ports/security groups in the region."},
  27. ViperConfig{Key: "openstack.password", Description: "Password for the Openstack user"},
  28. ViperConfig{Key: "openstack.region", Description: "The name of the region running this process"},
  29. ViperConfig{Key: "qualys.drop6", Description: "Should IPv6 addresses be incorporated in Qualys scans? true or false."},
  30. ViperConfig{Key: "qualys.username", Description: "Username for credentials for the Qualys external scanning service"},
  31. ViperConfig{Key: "qualys.password", Description: "Password for credentials for the Qualys external scanning service"},
  32. ViperConfig{Key: "qualys.url", Description: "URL for thw Qualys service"},
  33. ViperConfig{Key: "qualys.proxy_url", Description: "URL for an HTTP proxy that will permit access to the Qualys service"},
  34. ViperConfig{Key: "syslog_server", Description: "FQDN of the server for events to log to over the network"},
  35. ViperConfig{Key: "syslog_port", Description: "Port for communication to syslog, defaults to 514"},
  36. ViperConfig{Key: "syslog_protocol", Description: "tcp or udp, defaults to tcp"},
  37. ViperConfig{Key: "retry_syslog", Description: "Should the process keep trying if it cannot reach syslog? true or false."},
  38. }
  39. configPath := os.Getenv("EL_CONFIG") //The config path comes from ENV.
  40. if configPath == "" {
  41. log.Fatalln("Fatal Error: The Config file was not set to EL_CONFIG.")
  42. }
  43. if err := InitViper(configPath, viperConfigs); err != nil {
  44. log.Fatalf("Fatal Error: (%s) while reading config file %s", err, configPath)
  45. }
  46. // Set defaults
  47. viper.SetDefault("batch_interval", 60)
  48. viper.SetDefault("debug", true)
  49. viper.SetDefault("qualys.drop6", true)
  50. viper.SetDefault("qualys.url", "https://qualysapi.qualys.com/api/2.0/fo/scan/")
  51. viper.SetDefault("syslog_port", "514")
  52. viper.SetDefault("syslog_protocol", "tcp")
  53. // Watch for config changes
  54. viper.WatchConfig()
  55. viper.OnConfigChange(func(fsnotify.Event) {
  56. if err := ValidateConfig(viperConfigs); err != nil {
  57. log.Printf("Fatal Error: %s while refreshing config file %s\n", err, configPath)
  58. }
  59. })
  60. batchInterval := viper.GetInt("batch_interval")
  61. Debug = viper.GetBool("debug")
  62. // Initialize AMQP
  63. rabbitURI = viper.GetString("rabbit_uri")
  64. amqpBus := new(AmqpActions)
  65. amqpBus.Options = AmqpOptions{
  66. RabbitURI: rabbitURI,
  67. }
  68. amqpIncoming, amqpErrorNotify, err := amqpBus.Connect()
  69. if err != nil {
  70. log.Fatalln(err)
  71. }
  72. // Initialize Qualys
  73. qualysURL, err := url.Parse(viper.GetString("qualys.url"))
  74. if err != nil {
  75. log.Fatal(err)
  76. }
  77. qualysProxyURL, err := url.Parse(viper.GetString("qualys.proxy_url"))
  78. if err != nil {
  79. log.Fatal(err)
  80. }
  81. qualys := new(QualysActions)
  82. qualys.Options = QualysOptions{
  83. DropIPv6: viper.GetBool("qualys.drop6"),
  84. Password: viper.GetString("qualys.password"),
  85. ProxyURL: qualysProxyURL,
  86. QualysURL: qualysURL,
  87. ScanOptionName: viper.GetString("qualys.option"),
  88. MinRemaining: viper.GetInt("qualys.min_remaining"),
  89. UserName: viper.GetString("qualys.username"),
  90. }
  91. // Initialize OpenStack
  92. openstack := new(OpenStackActions)
  93. openstack.Options = OpenStackOptions{
  94. KeystoneURI: viper.GetString("openstack.identity_endpoint"),
  95. Password: viper.GetString("openstack.password"),
  96. RegionName: viper.GetString("openstack.region"),
  97. UserName: viper.GetString("openstack.user"),
  98. }
  99. // Initialize Syslog
  100. logger := new(SyslogActions)
  101. logger.Options = SyslogOptions{
  102. Host: viper.GetString("syslog_server"),
  103. Port: viper.GetString("syslog_port"),
  104. Protocol: viper.GetString("syslog_protocol"),
  105. Retry: viper.GetBool("retry_syslog"),
  106. }
  107. err = logger.Connect()
  108. if err != nil {
  109. log.Fatal(err)
  110. }
  111. // run main loop
  112. batchDuration := time.Duration(batchInterval) * time.Minute
  113. mainLoop(batchDuration, amqpIncoming, amqpErrorNotify, openstack, logger, qualys)
  114. defer amqpBus.Close()
  115. }