kylefarris / clamscan

A robust ClamAV virus scanning library supporting scanning files, directories, and streams with local sockets, local/remote TCP, and local clamscan/clamdscan binaries (with failover).
MIT License
230 stars 68 forks source link

Socket times out when remote scanning EICAR test file #103

Closed davecozens closed 5 months ago

davecozens commented 2 years ago

Whenever I try to test a virus positive EICAR test file I get a socket timeout. Virus negative files work fine.

    removeInfected: false,
    debugMode: true,
    scanRecursively: false,
    clamdscan: {
        host: CLAM_AV_IP,
        port: CLAM_AV_PORT,
        localFallback: false,
    },
    preference: 'clamdscan',
};
const ClamScan = new NodeClam().init(config);
ClamScan.then(async clamscan => {
    try {
        let filename = './eicar.com.txt'
        const {isInfected, file, viruses} = await clamscan.isInfected(filename);
        if (isInfected) console.log(`${file} is infected with ${viruses}!`);
    } catch (err) {
        // Handle any errors raised by the code in the try block
    }
}).catch(err => {
    // Handle errors that may have occurred during initialization
});

I get the following output:

node-clam: Provided stream is readable.
node-clam: Attempting to establish socket/TCP connection for "scanStream"
node-clam: using remote server: n.n.n.n:3310
passed stream
node-clam: Received final data from stream.
node-clam: The input stream has dried up.
node-clam: Socket/Host connection failed: Error: read ETIMEDOUT
    at TCP.onStreamRead (internal/stream_base_commons.js:205:27) {
  errno: 'ETIMEDOUT',
  code: 'ETIMEDOUT',
  syscall: 'read'
}
node-clam: Error emitted from ClamAV socket:  Error: read ETIMEDOUT
    at TCP.onStreamRead (internal/stream_base_commons.js:205:27) {
  errno: 'ETIMEDOUT',
  code: 'ETIMEDOUT',
  syscall: 'read'
}
node-clam: Socket/Host connection closed.
node-clam: ClamAV socket has been closed! true

Negative file gets the following output from the same server

node-clam: Received output from ClamAV Socket.
node-clam: ClamAV is done scanning.
node-clam: Raw Response:  stream: OK 
stream: OK
node-clam: File is OK!
node-clam: Socket/Host connection closed.
node-clam: ClamAV socket has been closed! false
kylefarris commented 2 years ago

Can you clone the repo directly, CD to it, and then npm i, and then run npm run test? Do all the tests pass?

Kyle

davecozens commented 2 years ago

They don't. I'm using node v16.

npm i

up to date, audited 381 packages in 1s

61 packages are looking for funding
  run `npm fund` for details

1 critical severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
dcozens@ALG3030 clamscan % npm run test

> clamscan@2.1.2 test
> make test

up to date, audited 381 packages in 1s

61 packages are looking for funding
  run `npm fund` for details

1 critical severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

  NodeClam Module
    ✔ should return an object
    ✔ should not be initialized immediately

  Initialized NodeClam module
    1) should have certain config properties defined
    2) should have the proper global default values set
    3) should have the proper clamscan default values set
    4) should have the proper clamdscan default values set
    ✔ should accept an options array and merge them with the object defaults
    ✔ should failover to alternate scanner if preferred scanner is inactive
    ✔ should fail if an invalid scanner preference is supplied when socket or host is not specified and localFallback is not false
Reason:  invalid scanner: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock' Error: connect ENOENT /var/run/clamd.scan/clamd.sock
Unhandled Rejection reason: [AssertionError: invalid scanner: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock'] {
  showDiff: true,
  actual: 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock',
  expected: 'Error',
  operator: 'notStrictEqual'
}
Reason:  invalid scanner: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock' Error: connect ENOENT /var/run/clamd.scan/clamd.sock
Unhandled Rejection reason: [AssertionError: invalid scanner: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock'] {
  showDiff: true,
  actual: 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock',
  expected: 'Error',
  operator: 'notStrictEqual'
}
    ✔ should fail to load if no active & valid scanner is found and socket is not available
    ✔ should fail to load if quarantine path (if specified) does not exist or is not writable and socket is not available
Reason:  good quarantine path: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock' Error: connect ENOENT /var/run/clamd.scan/clamd.sock
Unhandled Rejection reason: [AssertionError: good quarantine path: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock'] {
  showDiff: true,
  actual: 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock',
  expected: 'Error',
  operator: 'notStrictEqual'
}
Reason:  good quarantine path: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock' Error: connect ENOENT /var/run/clamd.scan/clamd.sock
Unhandled Rejection reason: [AssertionError: good quarantine path: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock'] {
  showDiff: true,
  actual: 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock',
  expected: 'Error',
  operator: 'notStrictEqual'
}
    5) should set definition database (clamscan) to null if specified db is not found
    6) should set scanLog to null if specified scanLog is not found
Reason:  expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock' Error: connect ENOENT /var/run/clamd.scan/clamd.sock
Unhandled Rejection reason: [AssertionError: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock'] {
  showDiff: true,
  actual: 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock',
  expected: 'Error',
  operator: 'notStrictEqual'
}
Reason:  expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock' Error: connect ENOENT /var/run/clamd.scan/clamd.sock
Unhandled Rejection reason: [AssertionError: expected promise not to be rejected with 'Error' but it was rejected with 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock'] {
  showDiff: true,
  actual: 'Error: connect ENOENT /var/run/clamd.scan/clamd.sock',
  expected: 'Error',
  operator: 'notStrictEqual'
}
    7) should be able have configuration settings changed after instantiation
    8) should initialize successfully with a custom config file, even if the default config file does not exist

  _buildClamFlags
    9) "before each" hook for "should build an array"

  getVersion
    10) "before each" hook for "should exist"

  _initSocket
    11) "before each" hook for "should exist"

  _ping
    12) "before each" hook for "should exist"

  isInfected
    13) "before each" hook for "should exist"

  scanFile
    14) "before each" hook for "should exist"

  scanFiles
    15) "before each" hook for "should exist"

  scanDir
    16) "before all" hook for "should exist"

  scanStream
    17) "before all" hook for "should exist"

  passthrough
    18) "before all" hook for "should exist"

  7 passing (40ms)
  18 failing

  1) Initialized NodeClam module
       should have certain config properties defined:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  2) Initialized NodeClam module
       should have the proper global default values set:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  3) Initialized NodeClam module
       should have the proper clamscan default values set:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  4) Initialized NodeClam module
       should have the proper clamdscan default values set:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  5) Initialized NodeClam module
       should set definition database (clamscan) to null if specified db is not found:
     Error: No valid & active virus scanning binaries are active and available and no host/socket option provided!
      at /Users/dcozens/sfg20/clamscan/index.js:241:41

  6) Initialized NodeClam module
       should set scanLog to null if specified scanLog is not found:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  7) Initialized NodeClam module
       should be able have configuration settings changed after instantiation:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  8) Initialized NodeClam module
       should initialize successfully with a custom config file, even if the default config file does not exist:
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  9) _buildClamFlags
       "before each" hook for "should build an array":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  10) getVersion
       "before each" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  11) _initSocket
       "before each" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  12) _ping
       "before each" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  13) isInfected
       "before each" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  14) scanFile
       "before each" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  15) scanFiles
       "before each" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  16) scanDir
       "before all" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  17) scanStream
       "before all" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

  18) passthrough
       "before all" hook for "should exist":
     Error: connect ENOENT /var/run/clamd.scan/clamd.sock
      at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

make: *** [test] Error 18
kylefarris commented 2 years ago

Those errors seem to indicate a misconfiguration of your clamd host or possibly a permissions or SELinux issue. Are you able to scan files using clamdscan on the command line? For example clamdscan someFileName?

davecozens commented 2 years ago

It's deployed to AWS Fargate from Docker image tquinnelly/clamav-alpine:latest so I don't have command line access.

But it's odd that a regular text file scan returns OK, it's just the EICAR test file that throws the error... There's also nothing in the logs

kylefarris commented 2 years ago

Yeah man, I took a look through https://github.com/tquizzle/clamav-alpine and I just don't know enough about that setup and without anyway to test it outside of the use of the package, it makes it very difficult to narrow down the cause.

With that being said, the package is running and passing tests on my Linux and MacOS machines (non-Docker) without a problem.

davecozens commented 2 years ago

Would you recommend another docker image? D

On Mon, Aug 1, 2022 at 3:27 PM Kyle Farris @.***> wrote:

Yeah man, I took a look through https://github.com/tquizzle/clamav-alpine and I just don't know enough about that setup and without anyway to test it outside of the use of the package, it makes it very difficult to narrow down the cause.

With that being said, the package is running and passing tests on my Linux and MacOS machines (non-Docker) without a problem.

— Reply to this email directly, view it on GitHub https://github.com/kylefarris/clamscan/issues/103#issuecomment-1201280402, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2Y23AUVZ4IT4DPY7TENRTVW7NG7ANCNFSM55APLMSQ . You are receiving this because you authored the thread.Message ID: @.***>

kylefarris commented 2 years ago

I don't really use Docker so, unfortunately, I don't.