Tag Archives: redhat

OpenSSL v 1.0.2: building / compiling from source (Linux / CentOS / Red Hat)

As a precursor of installing a web server such as Apache (http version 2.4.10) and to avail of certain features as in able to configure the certificate chain on a certificate basis, we need to update to this version.

An earlier post detailed the steps to compile the OpenSSL v1.0.1 series and this one would cover the next version. The steps remain the same however the earlier post is more detailed.

  1. Run “config”
  2. Run “make”
  3. Run “make test”
  4. Run “make install”

A little more granularity:


$ ./config shared --prefix=/installs/openssl-1.0.2

Here: I have specified the installation folder to be explicit. You could point it to any other location or go with the default “/usr/local/ssl”. Note that if you would like to compile in the ECC Optimizations (ECC accelerator) refer to my earlier post.


$ make
$ make test
$ make install

You might face build issues as in “gcc” not being available or an incorrect version. Try “yum update gcc”.

The final step is to set the environment as in:


export LD_LIBRARY_PATH=/installs/openssl-1.0.2/lib:$LD_LIBRARY_PATH
export PATH=/installs/openssl-1.0.2/bin:$PATH

Nginx 1.2.x and install Elliptic Curve Crytpography (ECC) support – installation on Linux (.configure options and build for SSL / TLS support and enable HTTPS)

As of writing this and as far as I know, the pre-compiled binaries for nginx for various platforms (RedHat / CentOS or another linux variant) do not come with ECC support so you would not be able to utilize ECC based certificates (ECDHE key exchange or ECDSA  authentication). The solution is to compile the Nginx source code with an OpenSSL version that has ECC support such as OpenSSL 1.0.1c or 1.0.1e. As of writing, 1.0.1c has a vulnerability (please see the OpenSSL web site for more details) and 1.0.1e is the recommended version.

When comparing with Apache HTTPD web server compilation, I found building Nginx to be simpler based on the fact that one needs to specify the OpenSSL source and Nginx build process takes care of building and linking to it. If you are only interested in building OpenSSL from source with ECC support then refer to this post.

After downloading Nginx source, run the following to check the options for configure:

./configure --help

This will list out all options that determine what modules to enable or disable, locations of dependencies such as OpenSSL if they are not in the obvious locations.

Since we have downloaded the OpenSSL source (1.0.1x) to support ECC into a different folder, we need to specify that so the configure option becomes:

./configure --prefix=/app/installs/nginx --with-http_ssl_module --with-openssl=/app/source/openssl/openssl-1.0.1c

This implies that nginx will be installed at “/app/installs/nginx” with the module to add SSL / TLS support and the location of the OpenSSL source is specified as well (this is where the OpenSSL source was extracted).

Thereafter run the following commands:

make

Switch to root if not already so and

make install

Uncomment the HTTPS / SSL sections from the Nginx configuration file and specify the certificates and you are all set.

To check the options for the nginx command line:

nginx --help

To start nginx:

nginx

If you get errors about PCRE at the configure stage or later (error messages replicated below) and if you have previously installed it, update the LD_LIBRARY_PATH environment variable to include the library but if you do not have it installed, there is a section on this blog on installing PCRE. All one has to do is to download the source and simply install that. Another approach is to install the PCRE development libraries. Both approaches are outlined below.

Error Message 1 (at configure time):


./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre= option.

Error Message 2 (later at run time):


nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

Solution 1:

While configuring nginx, one can specify the location of the source of PCRE source (8.3.1 is the version that I used and can be downloaded from the PCRE website) at the configure step:

./configure ..... ..... ... --with-pcre=/app/source/pcre/pcre-8.31

And repeat the “make, make install” steps as outlined earlier.

Solution 2:

Alternatively if PCRE is already installed then simply point to it (you would need the development libraries):

$ yum search pcre
Matched: pcre ==
opensips-regex.x86_64 : RegExp via PCRE library
pcre.i386 : Perl-compatible regular expression library
pcre.x86_64 : Perl-compatible regular expression library
pcre-devel.i386 : Development files for pcre
pcre-devel.x86_64 : Development files for pcre

Then install the development version:

$ yum install pcre-devel

Time to reconfigure and install Nginx:


$ ./configure ...... [same arguments as above]

A successful “./configure” would have something akin to this output:

$ ./configure .........
checking for OS
+ Linux 2.6.18-128.1.6.el5 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 4.1.2 20080704 (Red Hat 4.1.2-44)
checking for gcc -pipe switch ... found
checking for gcc builtin atomic operations ... found
checking for C99 variadic macros ... found
checking for gcc variadic macros ... found
checking for unistd.h ... found
checking for inttypes.h ... found
checking for limits.h ... found
checking for sys/filio.h ... not found
checking for sys/param.h ... found
checking for sys/mount.h ... found
checking for sys/statvfs.h ... found
checking for crypt.h ... found
checking for Linux specific features
checking for epoll ... found
checking for sendfile() ... found
checking for sendfile64() ... found
checking for sys/prctl.h ... found
checking for prctl(PR_SET_DUMPABLE) ... found
checking for sched_setaffinity() ... found
checking for crypt_r() ... found
checking for sys/vfs.h ... found
checking for nobody group ... found
checking for poll() ... found
checking for /dev/poll ... not found
checking for kqueue ... not found
checking for crypt() ... not found
checking for crypt() in libcrypt ... found
checking for F_READAHEAD ... not found
checking for posix_fadvise() ... found
checking for O_DIRECT ... found
checking for F_NOCACHE ... not found
checking for directio() ... not found
checking for statfs() ... found
checking for statvfs() ... found
checking for dlopen() ... not found
checking for dlopen() in libdl ... found
checking for sched_yield() ... found
checking for SO_SETFIB ... not found
checking for SO_ACCEPTFILTER ... not found
checking for TCP_DEFER_ACCEPT ... found
checking for TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT ... found
checking for TCP_INFO ... not found
checking for accept4() ... not found
checking for int size ... 4 bytes
checking for long size ... 8 bytes
checking for long long size ... 8 bytes
checking for void * size ... 8 bytes
checking for uint64_t ... found
checking for sig_atomic_t ... found
checking for sig_atomic_t size ... 4 bytes
checking for socklen_t ... found
checking for in_addr_t ... found
checking for in_port_t ... found
checking for rlim_t ... found
checking for uintptr_t ... uintptr_t found
checking for system byte ordering ... little endian
checking for size_t size ... 8 bytes
checking for off_t size ... 8 bytes
checking for time_t size ... 8 bytes
checking for setproctitle() ... not found
checking for pread() ... found
checking for pwrite() ... found
checking for sys_nerr ... found
checking for localtime_r() ... found
checking for posix_memalign() ... found
checking for memalign() ... found
checking for mmap(MAP_ANON|MAP_SHARED) ... found
checking for mmap("/dev/zero", MAP_SHARED) ... found
checking for System V shared memory ... found
checking for POSIX semaphores ... not found
checking for POSIX semaphores in libpthread ... found
checking for struct msghdr.msg_control ... found
checking for ioctl(FIONBIO) ... found
checking for struct tm.tm_gmtoff ... found
checking for struct dirent.d_namlen ... not found
checking for struct dirent.d_type ... found
checking for sysconf(_SC_NPROCESSORS_ONLN) ... found
checking for openat(), fstatat() ... found
checking for getaddrinfo() ... found
checking for PCRE library ... found
checking for PCRE JIT support ... not found
checking for OpenSSL library ... found
checking for zlib library ... found
creating objs/Makefile

Configuration summary
+ using system PCRE library
+ using system OpenSSL library [or the source location]
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library

nginx path prefix: “/app/…..”
nginx binary file: “/app/….”
nginx configuration prefix: “/app/…..”
nginx configuration file: “/app/…..”
nginx pid file: “/app/…/nginx.pid”
nginx error log file: “/app/…./logs/error.log”
nginx http access log file: “/app/…../logs/access.log”
nginx http client request body temporary files: “client_body_temp”
nginx http proxy temporary files: “proxy_temp”
nginx http fastcgi temporary files: “fastcgi_temp”
nginx http uwsgi temporary files: “uwsgi_temp”
nginx http scgi temporary files: “scgi_temp”

And then proceed with the make and make install.

Apache httpd 2.2.22 (or 2.4.x) and OpenSSL 1.x.x (RHEL or CentOS Linux) – build / compile / install Apache Web Server and OpenSSL with ECC (Elliptic Curve Cryptography) Accelarator on Linux (CentOS Red Hat)

The stack:

  1. Apache httpd (web server) version 2.2.22
  2. OpenSSL 1.x.x. (1.0.1c)
  3. RedHat Enterprise Linux 5.8 (rhel), CentOS or any flavor of Linux.

The goal:

To upgrade the OpenSSL library from 0.8.x to 1.x.x. The reason for the upgrade is the DSA algorithm support required in terms of installing a server certificate that is signed through the use of DSA 2048_256 CA key. Also to build and provide Elliptic Curve Cryptography (ECC) support with optimizations.

Problems:

These are the problems or issues that had to be resolved in order to achieve the goal:

  1. OpenSSL 1.x.x. rpm not available. Therefore we needed to download the source and build it. And then it had to be installed in a location as not to overwrite the existing OpenSSL installation. Please note: the RedHat and CentOS linux (not to mention the other variants of linux) have a huge number of packages (I counted 500) that have dependencies directly or indirectly to OpenSSL. Consequently it is easier not to overwrite the OpenSSL installation with the later version; or remove the older version and install the later version.In a production system, you might want to do an “upgrade” but that is beyond the scope of this document.
  2. Apache 2.2.22 rpm not available (at least in the repository that we access). Consequently we would be downloading the source and building it as well.

Build and install process

This section details the effort and steps undertaken to install both OpenSSL and Apache httpd. We being with OpenSSL, install that and move on to Apache httpd.

OpenSSL

Download the source and save it. Thereafter you have two options:

  1. Do you want to httpd to link statically to the generated static OpenSSL libararies (.a extension)?
  2. or dynamically to a shared library (.so)?

Although I found that the approach in bullet 1 led to the goal being easier to accomplish as there were issues in Apache httpd able to load the correct OpenSSL version with approach 2. This resulted in a lot of debugging to get it to work (the issue turned out to be the LDAP support that I was compiling with). However, in this document I will detail the second approach.

At the shell:

Now we check the installation to confirm the presence of shared libraries (.so files).

The creation of “libcrypto.so” and “libssl.so” is confirmed.

Optional Support for 64-bit optimized implementations of EC (Elliptic Curves)

To add support for 64-bit optimized implementations for NIST-P224, NIST-P256, NIST-P521, provide “enable-ec_nistp_64_gcc_128″ on the “configure” command line.

Reference: http://www.apachehaus.com/ossl101.txt

Apache httpd

We set the LD_LIBRARY_PATH to “/usr/local/ssl/lib” so as to make sure that the Apache httpd installation picks up the right libraries viz the right version – the version that has been installed as a result of following the steps in the preceding section.

export LD_LIBRARY_PATH=/usr/local/ssl/lib

We are assuming that a prior Apache Web Server version is not installed on the system. If it is then you could easily remove it if it is package managed.

To install Apache httpd, the following steps are to be followed (the proceeding texts details the arguments to configure):

If there are any errors or need to change the options to configure after having run it once, “make clean” and “make distclean” need to be run as well preceeding running of configure with the latest options.

If you need to statically link OpenSSL with Apache httpd, then one can configure httpd with the following (the following is a configure command to build Apache httpd with SSL support through the the mod_ssl module):

 

./configure --prefix=/app/install/myinstalls/httpd --enable-ssl --enable-rewrite --with-ssl=/usr/local/ssl

 

However, we would be dynamically linking to OpenSSL and therefore the configure command would be:

 

./configure --prefix=/app/install/myinstalls/httpd --enable-mods-shared="all ssl deflate disk-cache expires headers info cache proxy proxy-ajp proxy-balancer proxy-connect proxy-ftp proxy-http rewrite" --with-ssl=/usr/local/ssl

 

Please note that I have added support for a whole lot of modules as well. Another interesting piece to note is that ldap support is missing as is not the case with the following configure and options:

 

./configure --prefix=/app/installs/httpd --enable-mods-shared="all ssl authn-dbm authz-dbm auth-digest deflate disk-cache expires headers info isapi ldap cache proxy proxy-ajp proxy-balancer proxy-connect proxy-ftp proxy-http rewrite unique-id usertrack vhost-alias authn_alias mem_cache file_cache authnz_ldap charset_lite dav_lock disk_cache" --with-ldap

 

The reason for the missing ldap support is that having built Apache httpd for ldap support as in the above, the error_log has an entry pointing to the earlier version of OpenSSL and not the one that we compiled and installed as in the previous section:

 

[Sat Sep 01 00:48:16 2012] [notice] Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/[EARLIER VERSION] DAV/2 configured -- resuming normal operations

 

Consequently, to enable the right version to be printed, we had to forsake LDAPsupport and the right version of OpenSSL was associated with the mod_ssl module as in:

 

[Sat Sep 01 00:48:16 2012] [notice] Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/1.0.1c DAV/2 configured -- resuming normal operations

 

So in synopsis, these are the steps to build Apache httpd and dynamically link it with OpenSSL 1.x.x:

 

./configure --prefix=/app/install/myinstalls/httpd --enable-mods-shared="all ssl deflate disk-cache expires headers info cache proxy proxy-ajp proxy-balancer proxy-connect proxy-ftp proxy-http rewrite" --with-ssl=/usr/local/ssl

make

make install

 

If as a result of performing the steps delineated above, an error of this type is spewed:

 

:/usr/bin/ld: /usr/local/ssl/lib/libssl.a(s2_srvr.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with fPIC

 

The implication is that OpenSSL was not compiled to generate shared libraries. Please see the OpenSSL section above for details on how to achieve that.

Thereafter one could test that the mod_ssl module is linking to the correct OpenSSL libraries through the use of the “ldd” command:

Some of the alphanumeric details enclosed in the parenthesis are replace with “…” for brevity.

References:

  1. http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html