Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statically link (new) libcurl into clamav for use on CentOS 7? #199

Closed
goshansp opened this issue Jul 12, 2021 · 6 comments
Closed

Statically link (new) libcurl into clamav for use on CentOS 7? #199

goshansp opened this issue Jul 12, 2021 · 6 comments

Comments

@goshansp
Copy link
Contributor

goshansp commented Jul 12, 2021

Situation

Red Hat Enterprise Linux (RHEL) and CentOS 7 are using Libcurl=7.29. Therefore ClamAV must be using --stream as for --fdpass the curl version is required to be at least 7.45. File streaming --stream is suspected to have a significant performance disadvantage when compared to --fdpass. This impacts performance because files will be streamed from clamonacc to clamd instead of leveraging the highly efficient --fdpass mechanism.

Option 1: Neglecting Impact

  • Is this really an issue or can the performance impact using --stream be neglected?

Option 2: Compile a later Libcurl into binaries?

  • Can a higher libcurl be compiled into ClamAV? If yes, what would be the Compileflags / Requirements?

Option 3: Loosen ClamAV Libcurl Version Constraints

  • Can ClamAV be made compatible with Libcurl 7.29? This would be favorable as RHEL/CentOS7 won't EOL for corporate customers until June 30, 2026.

Any advice will be appreciated as most our customers roll on RHEL7/Libcurl=7.29 and will be doing so for the coming years - Thank you!

@micahsnyder
Copy link
Contributor

Option 1: is pretty simple to test using ClamDScan with --fdpass vs --stream for a largish directory. I do believe --stream is much slower, but it may be tolerable, depending on what directories you need to watch.

Option 2: would require building libcurl as a static library. I'm not certain if its dependencies (there are a lot of dependency choices, but most likely: openssl, nghttp2(?), libc-ares(?), libz, libssh2) need to be static as well. I suspect not, though they must be linked into libclamav.so instead of libcurl.so. I suspect the build systems will have trouble forwarding those dependencies. But this would be the best of the 3 options. I think this is probably doable, just... needs some investigation.

Option 3 (the title of this issue): cannot be done. Mickey has looked at it several times and we've loosened the requirements as much as possible. The fdpass feature is relying on a libcurl API that simply doesn't exist in the older version.

@micahsnyder micahsnyder changed the title Enable --fdpass for Libcurl=7.29 Statically link (new) libcurl into clamav for use on CentOS 7? Jul 16, 2021
@micahsnyder
Copy link
Contributor

I renamed your ticket since the original name was for Option 3, which we can't do.

@goshansp
Copy link
Contributor Author

Testing clamdscan on Centos8 --stream seems to take about 15-20% longer compared to --fdpass. This result was obtained against /var/cache and /usr using TCPSocket. Static linking seems to offer many benefits and would also allow usage of LocalSocket.

@micahsnyder
Copy link
Contributor

micahsnyder commented Jul 22, 2021

Per our conversation yesterday, we found that if you build libcurl as a static library using CMake, then you can build ClamAV (0.104+, also using CMake) and instruct it to use libcurl's CURLConfig.cmake "exported targets" file, rather than using CMake's "FindCURL.cmake" module. You don't have to install libcurl to a system directory, you can install it wherever since it is a static library.

Here are the instructions we came up with...

Start with these instructions to get the clamav pre-requisites. You can skip the libcurl-devel package. Download
(or git clone) the source for libcurl and for clamav.

To build libcurl statically with -fPIC enabled (so it can be linked into libfreshclam.so), cd into your curl source directory and then run:

mkdir build && cd build
cmake .. \
    -D CMAKE_BUILD_TYPE=Release \
    -D CMAKE_POSITION_INDEPENDENT_CODE=ON \
    -D CMAKE_USE_OPENSSL=ON \
    -D CMAKE_INSTALL_PREFIX="`$HOME`/curl-install" \
    -D BUILD_SHARED_LIBS=OFF
make && make install

To build clamav with the static libcurl, the notable change is adding -D CMAKE_FIND_PACKAGE_PREFER_CONFIG=TRUE along with -D CMAKE_PREFIX_PATH=/some/path to point CMake at the directory where it will find your new Curl install, containing lib/cmake/CURLConfig.cmake file. So cd into your clamav source directory and then run:

mkdir build && cd build
cmake .. \
    -D CMAKE_FIND_PACKAGE_PREFER_CONFIG=TRUE \
    -D CMAKE_PREFIX_PATH=`$HOME`/curl-install 
make && make install

Note: You may also want to add these options to install it in the same paths used by other Linux distributions:

   -D CMAKE_BUILD_TYPE=Release \
   -D CMAKE_INSTALL_PREFIX=/usr \
   -D CMAKE_INSTALL_LIBDIR=/usr/lib \
   -D APP_CONFIG_DIRECTORY=/etc/clamav \
   -D DATABASE_DIRECTORY=/var/lib/clamav \

Thanks @goshansp for doing the legwork on this to test all of this. Please correct me if I got any of the above wrong. I only did very light testing.

@micahsnyder
Copy link
Contributor

@goshansp ok if I close this issue since we found a solution?
Do you think we should document this somewhere? I imagine we could add a page somewhere on docs.clamav.net or maybe a subsection in INSTALL.md.

@goshansp
Copy link
Contributor Author

The information above has been extremely helpful and using --fdpass under RHEL7 has shown the best results we've ever seen. We'll test this further within the coming weeks. The RPM creation has been automated in https://gitlab.com/goshansp/ansible-role-clamav/-/blob/master/tasks/packaging.yml and we hope to push it to the official RPM packaging at a later stage. Thanks so much to the whole team for the dedication to make it work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants