Your message dated Sat, 22 Jul 2023 13:19:43 +0000
with message-id <e1qncwn-005ruf...@coccia.debian.org>
and subject line Released with 12.1
has caused the Debian Bug report #1041163,
regarding bookworm-pu: package crowdsec/1.4.6-6~deb12u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1041163: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1041163
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: debian.pack...@crowdsec.net

Hi,

[ Reason ]
I'd like to fix serious bug #1040976 in bookworm. In a nutshell, both
upstream and I missed the fact Debian 12 comes without rsyslog by
default now, meaning /var/log/auth.log stays empty and the detection of
failed SSH logins is ineffective.


[ Impact ]
There's still some protection provided by the crowd-generated decisions,
but for a tool that's commonly described as a fail2ban on steroids, this
is a very bad bug, giving users some illusion of security.


[ Tests ]
Both upstream and I have tested the package uploaded to unstable and the
one prepared with the attached debdiff in bookworm VMs, “attacking” them
over SSH, and checking that:
 - `cscli metrics` reports SSH lines under both “Acquisition Metrics”
   (confirming the update of the default config for the acquisition part
   is fine) and “Parser Metrics” (confirming the relevant parser are
   indeed able to parse and extract information from those lines).
   Sample output can be found at the bottom of this mail — keeping in
   mind it's fine to have unparsed lines, we're focussing on some
   specific strings to identify unwanted activity.
 - An online machine would report the unwanted activity to the Central
   API, which confirms that we're indeed participating in the bad agent
   reporting effort. (Upstream uses disposable VMs in the cloud to test
   this: some whitelists are in place, and local IPs are never reported,
   so I haven't tested that myself.) That's confirmed via such lines in
   the logs: “Signal push: 1 signals to push”.

I also verified that installing bookworm's version and upgrading to the
proposed package doesn't trigger any undesired prompts about conffiles,
does deploy the updated config, and does activate the detection of
failed SSH logins immediately.


[ Risks ]
Trying to have some edits in /etc/crowdsec/acquis.yaml depending on
what's installed on a system definitely seemed riskier, and more
cumbersome for users (leading to prompts during upgrades etc.). That's
why we went for the 0017 patch instead (enabling journalctl
unconditionally). Upstream anticipated the obvious problem: the engine
would error out if it's not available, that's why there's a longer 0018
patch to allow for unavailable datasources (that part has been tested by
me as well, moving the journalctl executable out of the way).

Regarding patches:
 - 0017 is only in a PR for the time being; some colleagues of my usual
   contact (who is very well versed into Debian topics) would like some
   more time to think about the impact for other distributions before
   merging it into master, but it seems very clear to me we should go
   this route for Debian.
 - 0018 was merged into master, and backported to their releases/1.4.x
   branch.
 - 0019 is just about disabling a buggy test.


[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in stable
  [x] the issue is verified as fixed in unstable


[ Changes ]
Since we're talking about a configuration file (marked conffiles), the
easiest is to enable the journalctl datasource in all cases [0017], but
that required another patch to make sure the engine doesn't error out
when that datasource is present but not available [0018]; the resulting
1.4.6-5 package uploaded to unstable then uncovered flaws in a test case
during autopkgtest runs (the test seems fine during a normal build, but
errors out when autopkgtest runs build + test — which happens for most
if not all Go packages), hence another patch [0019]. The tracker page
doesn't list all autopkgtest runs yet, but that seems greener with
1.4.6-6 than it was with 1.4.6-5…


[ Other info ]
As mentioned above, some parts of `clsci metrics`'s output confirming
things are much better with the proposed package:

    Acquisition Metrics:
    
╭─────────────────────────────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────╮
    │                     Source                      │ Lines read │ Lines 
parsed │ Lines unparsed │ Lines poured to bucket │
    
├─────────────────────────────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┤
    │ journalctl:journalctl-_SYSTEMD_UNIT=ssh.service │ 14         │ 5          
  │ 9              │ -                      │
    
╰─────────────────────────────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────╯
    
    Parser Metrics:
    ╭─────────────────────────────────┬──────┬────────┬──────────╮
    │             Parsers             │ Hits │ Parsed │ Unparsed │
    ├─────────────────────────────────┼──────┼────────┼──────────┤
    │ crowdsecurity/sshd-logs         │ 14   │ 5      │ 9        │
    ╰─────────────────────────────────┴──────┴────────┴──────────╯


Thanks for your time.


Cheers,
-- 
Cyril Brulebois -- Debian Consultant @ DEBAMAX -- https://debamax.com/
diff -Nru crowdsec-1.4.6/debian/changelog crowdsec-1.4.6/debian/changelog
--- crowdsec-1.4.6/debian/changelog     2023-05-31 18:54:17.000000000 +0200
+++ crowdsec-1.4.6/debian/changelog     2023-07-15 11:29:33.000000000 +0200
@@ -1,3 +1,32 @@
+crowdsec (1.4.6-6~deb12u1) bookworm; urgency=medium
+
+  * Rebuild for bookworm.
+  * Adjust gbp.conf accordingly.
+
+ -- Cyril Brulebois <cy...@debamax.com>  Sat, 15 Jul 2023 11:29:33 +0200
+
+crowdsec (1.4.6-6) unstable; urgency=medium
+
+  * Disable unreliable TestStreaming test, as seen under autopkgtest
+    (https://github.com/crowdsecurity/crowdsec/issues/2352):
+     - 0019-disable-unreliable-test-TestStreaming.patch
+
+ -- Cyril Brulebois <cy...@debamax.com>  Fri, 14 Jul 2023 20:54:27 +0200
+
+crowdsec (1.4.6-5) unstable; urgency=medium
+
+  * Fix default acquis.yaml to also include the journalctl datasource,
+    limited to the ssh.service unit, making sure acquisition works even
+    without the traditional auth.log file (Closes: #1040976):
+     - 0017-fix-default-acquisition.patch
+  * Make sure an invalid datasource doesn't make the engine error out,
+    making it possible to include the journalctl datasource in the default
+    config file unconditionally, without having to worry whether
+    journalctl is actually deployed and usable:
+     - 0018-non-fatal-errors-for-invalid-datasources.patch
+
+ -- Cyril Brulebois <cy...@debamax.com>  Thu, 13 Jul 2023 17:23:01 +0200
+
 crowdsec (1.4.6-4) unstable; urgency=medium
 
   * Implement support for pending registration: since bouncers list crowdsec
diff -Nru crowdsec-1.4.6/debian/gbp.conf crowdsec-1.4.6/debian/gbp.conf
--- crowdsec-1.4.6/debian/gbp.conf      2023-03-20 23:10:51.000000000 +0100
+++ crowdsec-1.4.6/debian/gbp.conf      2023-07-15 11:28:38.000000000 +0200
@@ -1,3 +1,3 @@
 [DEFAULT]
-debian-branch = debian/sid
+debian-branch = debian/bookworm
 dist = DEP14
diff -Nru crowdsec-1.4.6/debian/patches/0017-fix-default-acquisition.patch 
crowdsec-1.4.6/debian/patches/0017-fix-default-acquisition.patch
--- crowdsec-1.4.6/debian/patches/0017-fix-default-acquisition.patch    
1970-01-01 01:00:00.000000000 +0100
+++ crowdsec-1.4.6/debian/patches/0017-fix-default-acquisition.patch    
2023-07-13 17:20:18.000000000 +0200
@@ -0,0 +1,21 @@
+From: Manuel Sabban <git...@sabban.eu>
+Date: Wed Jun 28 10:23:40 2023 +0200
+Subject: Add journalctl for ssh by default
+Origin: https://github.com/crowdsecurity/crowdsec/pull/2316/
+diff --git a/config/acquis.yaml b/config/acquis.yaml
+index cc3631f3..69976b38 100644
+--- a/config/acquis.yaml
++++ b/config/acquis.yaml
+@@ -10,6 +10,12 @@ filenames:
+  - /var/log/syslog
+ labels:
+   type: syslog
++---
++source: journalctl
++journalctl_filter:
++ - "_SYSTEMD_UNIT=ssh.service"
++labels:
++  type: syslog
+ ---
+ filename: /var/log/apache2/*.log
+ labels:
diff -Nru 
crowdsec-1.4.6/debian/patches/0018-non-fatal-errors-for-invalid-datasources.patch
 
crowdsec-1.4.6/debian/patches/0018-non-fatal-errors-for-invalid-datasources.patch
--- 
crowdsec-1.4.6/debian/patches/0018-non-fatal-errors-for-invalid-datasources.patch
   1970-01-01 01:00:00.000000000 +0100
+++ 
crowdsec-1.4.6/debian/patches/0018-non-fatal-errors-for-invalid-datasources.patch
   2023-07-13 17:20:20.000000000 +0200
@@ -0,0 +1,257 @@
+From 93d0beeb94641ee3f33ca78f3cdda229cfd95740 Mon Sep 17 00:00:00 2001
+From: mmetc <92726601+mm...@users.noreply.github.com>
+Date: Tue, 27 Jun 2023 10:46:25 +0200
+Subject: [PATCH] non-fatal error if some datasource can't be run (i.e.
+ journalctl but systemd is missing) (#2310)
+
+This on the other hand, gives a new fatal error when there are no valid 
datasources.
+In the previous version, crowdsec kept running with just a warning if no
+acquisition yaml or dir were specified.
+---
+ cmd/crowdsec/crowdsec.go              | 10 +++---
+ cmd/crowdsec/main.go                  |  4 +++
+ pkg/acquisition/acquisition.go        | 31 ++++++++++++++---
+ pkg/acquisition/acquisition_test.go   |  2 +-
+ tests/bats/01_crowdsec.bats           | 49 +++++++++++++++++++++++----
+ tests/bin/assert-crowdsec-not-running |  2 +-
+ 6 files changed, 80 insertions(+), 18 deletions(-)
+
+Signed-off-by: Cyril Brulebois <cy...@debamax.com>
+
+diff --git a/cmd/crowdsec/crowdsec.go b/cmd/crowdsec/crowdsec.go
+index 84cf0838..a3b095ae 100644
+--- a/cmd/crowdsec/crowdsec.go
++++ b/cmd/crowdsec/crowdsec.go
+@@ -23,22 +23,22 @@ func initCrowdsec(cConfig *csconfig.Config) 
(*parser.Parsers, error) {
+       var err error
+ 
+       // Populate cwhub package tools
+-      if err := cwhub.GetHubIdx(cConfig.Hub); err != nil {
+-              return &parser.Parsers{}, fmt.Errorf("Failed to load hub index 
: %s", err)
++      if err = cwhub.GetHubIdx(cConfig.Hub); err != nil {
++              return &parser.Parsers{}, fmt.Errorf("while loading hub index : 
%s", err)
+       }
+ 
+       // Start loading configs
+       csParsers := newParsers()
+       if csParsers, err = parser.LoadParsers(cConfig, csParsers); err != nil {
+-              return &parser.Parsers{}, fmt.Errorf("Failed to load parsers: 
%s", err)
++              return nil, fmt.Errorf("while loading parsers: %s", err)
+       }
+ 
+       if err := LoadBuckets(cConfig); err != nil {
+-              return &parser.Parsers{}, fmt.Errorf("Failed to load scenarios: 
%s", err)
++              return nil, fmt.Errorf("while loading scenarios: %s", err)
+       }
+ 
+       if err := LoadAcquisition(cConfig); err != nil {
+-              return &parser.Parsers{}, fmt.Errorf("Error while loading 
acquisition config : %s", err)
++              return nil, fmt.Errorf("while loading acquisition config: %s", 
err)
+       }
+       return csParsers, nil
+ }
+diff --git a/cmd/crowdsec/main.go b/cmd/crowdsec/main.go
+index 43eb63ec..a25c372f 100644
+--- a/cmd/crowdsec/main.go
++++ b/cmd/crowdsec/main.go
+@@ -157,6 +157,10 @@ func LoadAcquisition(cConfig *csconfig.Config) error {
+               }
+       }
+ 
++      if len(dataSources) == 0 {
++              return fmt.Errorf("no datasource enabled")
++      }
++
+       return nil
+ }
+ 
+diff --git a/pkg/acquisition/acquisition.go b/pkg/acquisition/acquisition.go
+index 43093a50..2461064d 100644
+--- a/pkg/acquisition/acquisition.go
++++ b/pkg/acquisition/acquisition.go
+@@ -25,6 +25,20 @@ import (
+       tomb "gopkg.in/tomb.v2"
+ )
+ 
++type DataSourceUnavailableError struct {
++      Name string
++      Err error
++}
++
++func (e *DataSourceUnavailableError) Error() string {
++      return fmt.Sprintf("datasource '%s' is not available: %v", e.Name, 
e.Err)
++}
++
++func (e *DataSourceUnavailableError) Unwrap() error {
++      return e.Err
++}
++
++
+ // The interface each datasource must implement
+ type DataSource interface {
+       GetMetrics() []prometheus.Collector                         // Returns 
pointers to metrics that are managed by the module
+@@ -86,8 +100,11 @@ func GetDataSourceIface(dataSourceType string) DataSource {
+       return nil
+ }
+ 
++// DataSourceConfigure creates and returns a DataSource object from a 
configuration,
++// if the configuration is not valid it returns an error.
++// If the datasource can't be run (eg. journalctl not available), it still 
returns an error which
++// can be checked for the appropriate action.
+ func DataSourceConfigure(commonConfig configuration.DataSourceCommonCfg) 
(*DataSource, error) {
+-
+       //we dump it back to []byte, because we want to decode the yaml blob 
twice :
+       //once to DataSourceCommonCfg, and then later to the dedicated type of 
the datasource
+       yamlConfig, err := yaml.Marshal(commonConfig)
+@@ -112,7 +129,7 @@ func DataSourceConfigure(commonConfig 
configuration.DataSourceCommonCfg) (*DataS
+               subLogger := clog.WithFields(customLog)
+               /* check eventual dependencies are satisfied (ie. journald will 
check journalctl availability) */
+               if err := dataSrc.CanRun(); err != nil {
+-                      return nil, errors.Wrapf(err, "datasource %s cannot be 
run", commonConfig.Source)
++                      return nil, &DataSourceUnavailableError{Name: 
commonConfig.Source, Err: err}
+               }
+               /* configure the actual datasource */
+               if err := dataSrc.Configure(yamlConfig, subLogger); err != nil {
+@@ -179,10 +196,11 @@ func LoadAcquisitionFromFile(config 
*csconfig.CrowdsecServiceCfg) ([]DataSource,
+               }
+               dec := yaml.NewDecoder(yamlFile)
+               dec.SetStrict(true)
++              idx := -1
+               for {
+                       var sub configuration.DataSourceCommonCfg
+-                      var idx int
+                       err = dec.Decode(&sub)
++                      idx += 1
+                       if err != nil {
+                               if ! errors.Is(err, io.EOF) {
+                                       return nil, errors.Wrapf(err, "failed 
to yaml decode %s", acquisFile)
+@@ -199,7 +217,6 @@ func LoadAcquisitionFromFile(config 
*csconfig.CrowdsecServiceCfg) ([]DataSource,
+                       if len(sub.Labels) == 0 {
+                               if sub.Source == "" {
+                                       log.Debugf("skipping empty item in %s", 
acquisFile)
+-                                      idx += 1
+                                       continue
+                               }
+                               return nil, fmt.Errorf("missing labels in %s 
(position: %d)", acquisFile, idx)
+@@ -212,10 +229,14 @@ func LoadAcquisitionFromFile(config 
*csconfig.CrowdsecServiceCfg) ([]DataSource,
+                       }
+                       src, err := DataSourceConfigure(sub)
+                       if err != nil {
++                              var dserr *DataSourceUnavailableError
++                              if errors.As(err, &dserr) {
++                                      log.Error(err)
++                                      continue
++                              }
+                               return nil, errors.Wrapf(err, "while 
configuring datasource of type %s from %s (position: %d)", sub.Source, 
acquisFile, idx)
+                       }
+                       sources = append(sources, *src)
+-                      idx += 1
+               }
+       }
+       return sources, nil
+diff --git a/pkg/acquisition/acquisition_test.go 
b/pkg/acquisition/acquisition_test.go
+index a547970a..a96044ca 100644
+--- a/pkg/acquisition/acquisition_test.go
++++ b/pkg/acquisition/acquisition_test.go
+@@ -171,7 +171,7 @@ log_level: debug
+ source: mock_cant_run
+ wowo: ajsajasjas
+ `,
+-                      ExpectedError: "datasource mock_cant_run cannot be run: 
can't run bro",
++                      ExpectedError: "datasource 'mock_cant_run' is not 
available: can't run bro",
+               },
+       }
+ 
+diff --git a/tests/bats/01_crowdsec.bats b/tests/bats/01_crowdsec.bats
+index a60b576d..f8272eb9 100644
+--- a/tests/bats/01_crowdsec.bats
++++ b/tests/bats/01_crowdsec.bats
+@@ -148,9 +148,10 @@ teardown() {
+     rm -f "$ACQUIS_DIR"
+ 
+     config_set '.common.log_media="stdout"'
+-    run -124 --separate-stderr timeout 2s "${CROWDSEC}"
++    run -1 --separate-stderr timeout 2s "${CROWDSEC}"
+     # check warning
+-    assert_stderr_line --partial "no acquisition file found"
++    assert_stderr --partial "no acquisition file found"
++    assert_stderr --partial "crowdsec init: while loading acquisition config: 
no datasource enabled"
+ }
+ 
+ @test "crowdsec (error if acquisition_path and acquisition_dir are not 
defined)" {
+@@ -163,19 +164,55 @@ teardown() {
+     config_set '.crowdsec_service.acquisition_dir=""'
+ 
+     config_set '.common.log_media="stdout"'
+-    run -124 --separate-stderr timeout 2s "${CROWDSEC}"
++    run -1 --separate-stderr timeout 2s "${CROWDSEC}"
+     # check warning
+-    assert_stderr_line --partial "no acquisition_path or acquisition_dir 
specified"
++    assert_stderr --partial "no acquisition_path or acquisition_dir specified"
++    assert_stderr --partial "crowdsec init: while loading acquisition config: 
no datasource enabled"
+ }
+ 
+ @test "crowdsec (no error if acquisition_path is empty string but 
acquisition_dir is not empty)" {
+     ACQUIS_YAML=$(config_get '.crowdsec_service.acquisition_path')
+-    rm -f "$ACQUIS_YAML"
+     config_set '.crowdsec_service.acquisition_path=""'
+ 
+     ACQUIS_DIR=$(config_get '.crowdsec_service.acquisition_dir')
+     mkdir -p "$ACQUIS_DIR"
+-    touch "$ACQUIS_DIR"/foo.yaml
++    mv "$ACQUIS_YAML" "$ACQUIS_DIR"/foo.yaml
+ 
+     run -124 --separate-stderr timeout 2s "${CROWDSEC}"
++
++    # now, if foo.yaml is empty instead, there won't be valid datasources.
++
++    cat /dev/null >"$ACQUIS_DIR"/foo.yaml
++
++    run --separate-stderr -1 timeout 2s "${CROWDSEC}"
++    assert_stderr --partial "crowdsec init: while loading acquisition config: 
no datasource enabled"
+ }
++
++@test "crowdsec (disabled datasources)" {
++    config_set '.common.log_media="stdout"'
++
++    # a datasource cannot run - missing journalctl command
++
++    ACQUIS_DIR=$(config_get '.crowdsec_service.acquisition_dir')
++    mkdir -p "$ACQUIS_DIR"
++    cat >"$ACQUIS_DIR"/foo.yaml <<-EOT
++      source: journalctl
++      journalctl_filter:
++      - "_SYSTEMD_UNIT=ssh.service"
++      labels:
++        type: syslog
++      EOT
++
++    run --separate-stderr -124 timeout 2s env PATH='' "${CROWDSEC}"
++    #shellcheck disable=SC2016
++    assert_stderr --partial 'datasource '\''journalctl'\'' is not available: 
exec: "journalctl": executable file not found in $PATH'
++
++    # if all datasources are disabled, crowdsec should exit
++
++    ACQUIS_YAML=$(config_get '.crowdsec_service.acquisition_path')
++    rm -f "$ACQUIS_YAML"
++    config_set '.crowdsec_service.acquisition_path=""'
++
++    run --separate-stderr -1 timeout 2s env PATH='' "${CROWDSEC}"
++    assert_stderr --partial "crowdsec init: while loading acquisition config: 
no datasource enabled"
++ }
+diff --git a/tests/bin/assert-crowdsec-not-running 
b/tests/bin/assert-crowdsec-not-running
+index c6f381af..d678cb4f 100755
+--- a/tests/bin/assert-crowdsec-not-running
++++ b/tests/bin/assert-crowdsec-not-running
+@@ -1,7 +1,7 @@
+ #!/usr/bin/env bash
+ 
+ is_crowdsec_running() {
+-    PIDS=$(pgrep -x 'crowdsec|crowdsec.test|crowdsec.cover')
++    PIDS=$(pgrep -x 'crowdsec|crowdsec.test|crowdsec.cover' 2>/dev/null)
+ }
+ 
+ # The process can be slow, especially on CI and during test coverage.
+-- 
+2.30.2
+
diff -Nru 
crowdsec-1.4.6/debian/patches/0019-disable-unreliable-test-TestStreaming.patch 
crowdsec-1.4.6/debian/patches/0019-disable-unreliable-test-TestStreaming.patch
--- 
crowdsec-1.4.6/debian/patches/0019-disable-unreliable-test-TestStreaming.patch  
    1970-01-01 01:00:00.000000000 +0100
+++ 
crowdsec-1.4.6/debian/patches/0019-disable-unreliable-test-TestStreaming.patch  
    2023-07-15 11:28:09.000000000 +0200
@@ -0,0 +1,19 @@
+From: Cyril Brulebois <cy...@debamax.com>
+Date: Fri, 14 Jul 2023 20:29:16 +0200
+Subject: Disable buggy test
+
+Adding the 0017 and 0018 patches had the side effect of uncovering
+reliability issues in TestStreaming(). Let's not block the bugfix for
+#1040976 on fixing that test: it's more important for the acquisition
+bugfix to make its way into testing and into stable.
+
+--- a/pkg/acquisition/modules/journalctl/journalctl_test.go
++++ b/pkg/acquisition/modules/journalctl/journalctl_test.go
+@@ -178,6 +178,7 @@ journalctl_filter:
+ }
+ 
+ func TestStreaming(t *testing.T) {
++      t.Skip("unreliable test: 
https://github.com/crowdsecurity/crowdsec/issues/2352";)
+       if runtime.GOOS == "windows" {
+               t.Skip("Skipping test on windows")
+       }
diff -Nru crowdsec-1.4.6/debian/patches/series 
crowdsec-1.4.6/debian/patches/series
--- crowdsec-1.4.6/debian/patches/series        2023-03-20 23:10:51.000000000 
+0100
+++ crowdsec-1.4.6/debian/patches/series        2023-07-15 11:28:09.000000000 
+0200
@@ -10,3 +10,6 @@
 0014-silence-yaml-patching.patch
 0015-silence-not-latest-version.patch
 0016-try-to-make-reproducible-build-work-2119.patch
+0017-fix-default-acquisition.patch
+0018-non-fatal-errors-for-invalid-datasources.patch
+0019-disable-unreliable-test-TestStreaming.patch

--- End Message ---
--- Begin Message ---
Version: 12.1

The upload requested in this bug has been released as part of 12.1.

--- End Message ---

Reply via email to