How-to create individual Diffie-Hellman (DH) 2048 bit keys for nginx and nginx_apache

zEitEr

Super Moderator
Joined
Apr 11, 2005
Messages
15,143
Location
GMT +7.00
HOW TO CREATE INDIVIDUAL Diffie-Hellman (DH) keys FOR EVERY DOMAIN


UNLESS YOU KNOW WHAT YOU DO PLEASE DO NOT FOLLOW THIS HOW-TO
THE HOW-TO IS INCOMPLETE AS OF YET! IT DOES NOT CREATE KEYS FOR NEWLY ADDED DOMAINS
WHICH MIGHT BE ADDED AFTER YOU APPLIED THIS SOLUTION! YOU NEED USE POST SCRIPTS!
FOLLOW
POST #3 FOR AN EASY WAY TO SOLVE AN ISSUE WITH LOGJAM ATTACK!


Logjam Attack discussion http://forum.directadmin.com/showthread.php?t=51449

As a temp solution you may use this guide for NGINX+APACHE, NGINX:

1. Create an executable file

Code:
touch /root/create_ssl_dhparam_all.sh
chmod 700 /root/create_ssl_dhparam_all.sh

2. Put the following content into it

Code:
#!/bin/bash##
## Diffie-Hellman (DH) key creator for Directadmin, version 0.3
## by Alex S Grebenschikov (www.plugins-da.net)
##
#----------------------------------------------------------------------
# Created at: Thu May 21 14:25:00 NOVT 2015
# Last modified: Thu May 21 14:25:00 NOVT 2015
#----------------------------------------------------------------------
# Configure section:


#----------------------------------------------------------------------
#
# main()


OPENSSL_CMD=`which openssl`


for user in `ls -1 /usr/local/directadmin/data/users`;
do
    echo "[`date`] + Started with user ${user}";
    for domain in `cat /usr/local/directadmin/data/users/${user}/domains.list`;
    do
    {
        echo "[`date`] + + Started with domain ${domain} of user ${user}";
        ssl=`grep ^ssl= /usr/local/directadmin/data/users/${user}/domains/${domain}.conf | cut -d\= -f2`
        creator=`grep ^creator= /usr/local/directadmin/data/users/${user}/user.conf | cut -d\= -f2`
        suspended=`grep ^suspended= /usr/local/directadmin/data/users/${user}/domains/${domain}.conf | cut -d\= -f2`
        echo "[`date`] + + User's ${user} creator ${creator}";
        echo "[`date`] + + Domain ${domain} is suspended ${suspended}";
        if [ "${ssl}" == "OFF" ];
        then
        {
            echo "[`date`] + + - SSL support for domain ${domain} is disabled [OFF]";
        }
        else
        {
            echo "[`date`] + + + SSL support for domain ${domain} is enabled [ON]";
            dhf="/usr/local/directadmin/data/users/${user}/domains/${domain}.dh_pem";
            sdhf="/usr/local/directadmin/data/users/${creator}/domains/${domain}.dh_pem";
            if [ ! -f "${dhf}" ];
            then
            {
                echo "[`date`] + + + + File ${dhf} does not exist! Generating it..."
                ${OPENSSL_CMD} dhparam -out ${dhf} 2048;
                ln -s ${dhf} ${sdhf};
            }
            else
            {
                if [ "${suspended}" == "yes" ];
                then
                    if [ ! -f "${sdhf}" ];
                    then
                        echo "[`date`] + + + + Creating symlink ${sdhf}!";
                        ln -s ${dhf} ${sdhf};
                    else
                        echo "[`date`] + + + - Files ${dhf} and ${sdhf} exist! Skipping it...";
                    fi;
                else
                    echo "[`date`] + + + - File ${dhf} exists! Skipping it...";
                fi;
            }
            fi;
        }
        fi;
        echo "[`date`] + - Finished with domain ${domain} of user ${user}";
    }
    done;
    echo "[`date`] - Finished with user ${user}";
done;


exit 0;

run the script /root/create_ssl_dhparam_all.sh

That will take time to create all the keys.

3. Update nginx templates

Code:
mkdir /usr/local/directadmin/data/templates/custom
cd /usr/local/directadmin/data/templates/custom
cp ../nginx_server_secure.conf .
cp ../nginx_server_secure_sub.conf .

4. Add the lines
Code:
|$/usr/local/bin/php
<?php
    $dh_key="/usr/local/directadmin/data/users/|USER|/domains/|DOMAIN|.dh_pem";
    if (is_file($dh_key))
    {
        echo "ssl_dhparam $dh_key;";
    }
?>
DONE|

right after ssl_certificate_key to the both templates.

Save. Here we add a PHP check whether or not DH key exists.

5. Update nginx.conf

Code:
cd /usr/local/directadmin/custombuild/
./build rewrite_confs
 
Last edited:
If an user account is suspended than the token |USER| will be replaced by a reseller name (creator), instead of username.
In such a case you might see an error:

Code:
nginx: [emerg] BIO_new_file("/usr/local/directadmin/data/users/admin/domains/domain.com.dh_pem") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/usr/local/directadmin/data/users/admin/domains/domain.com.dh_pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)nginx: configuration file /etc/nginx/nginx.conf test failed

then you might create a symlink for it:

Code:
ln -s  /usr/local/directadmin/data/users/[B]USER[/B]/domains/[B]DOMAIN[/B].dh_pem /usr/local/directadmin/data/users/[B]CREATOR[/B]/domains/[B]DOMAIN[/B].dh_pem

replace

USER, DOMAIN, CREATOR with your real data.
 
As a simpler solution or as an addition you can use this:

Code:
openssl dhparam -out /etc/nginx/ssl.crt/server.dh_pem 2048;
echo "ssl_dhparam /etc/nginx/ssl.crt/server.dh_pem;" >> /etc/nginx/nginx-includes.conf
/etc/init.d/nginx restart

or even

Code:
openssl dhparam -out /etc/nginx/ssl.crt/server.dh_pem 4096;
echo "ssl_dhparam /etc/nginx/ssl.crt/server.dh_pem;" >> /etc/nginx/nginx-includes.conf
/etc/init.d/nginx restart


This is going to take a long time ;)
 
A+ thanks :) Luckily the long time took only a few minutes :D

I needed this for my nginx_apache, but my apache setup which I haven't touched for a while doesn't seem to be affected.
 
I have followed the steps, but have an issue with step '5. Update nginx.conf'
With ./build rewrite_confs somehow my mod_ruid2 configuration is gone.
 
I have followed the steps, but have an issue with step '5. Update nginx.conf'
With ./build rewrite_confs somehow my mod_ruid2 configuration is gone.

This might happen if you don't use CustomBuild 2 support for mod_ruid2, but run a custom installation of mod_ruid2.
Open /usr/local/directadmin/custombuild/options.conf and make sure mod_ruid2 is enabled there. Then run

Code:
./build apache
 
This server was still running with custombuild 1. Didn't realized this before, because the others has already CB2. After updating to custombuild 2 the issue with removing the mod_ruid2 configuration is solved.
 
The step #4 was updated with a PHP check of whether or not DH key exists. The check is done only when virtual host gets rewritten. Example, you add a new domain, change its name, enable/disable SSL for a domain.

The how-to misses a step of creating a DH key for newly added domain. Thus if you add a new domain a key won't be generated for it. To get it fixed and DF key created for newly added domain you should use: /usr/local/directadmin/scripts/custom/domain_create_post.sh

In that script add the following code:


Code:
#!/bin/sh
DH="/usr/local/directadmin/data/users/${username}/domains/${domain}.dh_pem";
openssl dhparam -out ${DH} 2048;
echo "action=rewrite&value=nginx&user=${username}" >> /usr/local/directadmin/data/task.queue

WARNING: It was not tested much. Though the code itself is working. Bun when executing it with directadmin on a new domain creation it might end with "Your connection has timed out" error. Thus you need to fork a background process.



Run this:

Code:
chmod 700 [COLOR=#000000][FONT=courier new]/usr/local/directadmin/scripts/custom/domain_create_post.sh
[/FONT][/COLOR]chown diradmin:diradmin [COLOR=#000000][FONT=courier new]/usr/local/directadmin/scripts/custom/domain_create_post.sh
[/FONT][/COLOR]
 
[h=2]Diffie-Hellman (DH) 2048 bit keys for nginx are already in custombuild and directadmin templates for nginx. Aren't they added into Apache?[/h]
Try to

Code:
/usr/local/directadmin/custombuild
./build update
./build apache
./build rewrite_confs

Does it create the key for apache now?
 
This is superb! Thanks for the post! I have been having a hard time doing this but you made it seem so simple! A++++!
 
Back
Top