API call for DKIM deployment

Discussion in 'General' started by variable99, Feb 2, 2024.

  1. variable99

    variable99 Member

    Today is the day when I decided to implement email management into my system via ISPC API. Yes, a real headache :) ...
    Now, at first step already seeing a problem: how to generate DKIM key for newly added mail domain via API?
    I found this file, which is responsible for DKIM generation and it works only by manually clicking button in ISPC.
    I don't see any other way here, only copy/paste this file content into custom API file and modify "mail_domain_add" API call that with each domain DKIM would be generated. Am I missing something?
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    Just create a key using openssl command within your script and then add it to ISPConfig using mail_domain_add. No need to use any ISPConfig ajax scripts for that.
     
  3. variable99

    variable99 Member

    So no files are generated? Only DB records? I see that I should also update DNS records, but that's ok.
    I will try to edit this piece of code to create DKIM in custom API call:


    PHP:
    $app->system->exec_safe('echo ?|openssl rsa -pubout -outform PEM 2> /dev/null'$dkim_private);
    $pubkey $app->system->last_exec_out();
    foreach(
    $pubkey as $values$dkim_public=$dkim_public.$values."\n";
    $selector $dkim_selector;

    $dns_record=str_replace(array('-----BEGIN PUBLIC KEY-----','-----END PUBLIC KEY-----',"\r","\n"),'',$dkim_public);
    $dns_record str_replace(array("\r\n""\n""\r"),'',$dns_record);
    $dkim_private=json_encode($dkim_private);
    $dkim_private=substr($dkim_private1, -1);
    $dkim_public=json_encode($dkim_public);
    $dkim_public=substr($dkim_public1, -1);

       
    $json '{';
       
    $json .= '"dkim_private":"'.$dkim_private.'"';
       
    $json .= ',"dkim_public":"'.$dkim_public.'"';
       
    $json .= ',"dkim_selector":"'.$selector.'"';
       
    $json .= ',"dns_record":"'.$dns_record.'"';
       
    $json .= ',"domain":"'.$domain.'"';
       
    $json .= '}';
     
  4. till

    till Super Moderator Staff Member ISPConfig Developer

    No, the API expects to receive the DKIM key in the $params array.
     
    variable99 likes this.
  5. variable99

    variable99 Member

    For future, this is DKIM keys generating code:
    PHP:
    //Set these to match your domain and chosen DKIM selector
            
    $domain 'example2.com';
            
    $selector 'default';

            
    //Private key filename for this selector
            
    $privatekeyfile $f3->TEMP 'dkim/' $domain '_' $selector '_dkim_private.pem';
            
    //Public key filename for this selector
            
    $publickeyfile $f3->TEMP 'dkim/' $domain '_' $selector '_dkim_public.pem';

            if (
    file_exists($privatekeyfile)) {
                echo 
    "Using existing keys - if you want to generate new keys, delete old key files first." PHP_EOL;
                
    $privatekey file_get_contents($privatekeyfile);
                
    $publickey file_get_contents($publickeyfile);
            } else {
                
    //Create a 2048-bit RSA key with an SHA256 digest
                
    $pk openssl_pkey_new(
                    [
                        
    'digest_alg' => 'sha256',
                        
    'private_key_bits' => 2048,
                        
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
                    ]
                );
                
    //Save private key
                
    openssl_pkey_export_to_file($pk$privatekeyfile);
                
    //Save public key
                
    $pubKey openssl_pkey_get_details($pk);
                
    $publickey $pubKey['key'];
                
    file_put_contents($publickeyfile$publickey);
                
    $privatekey file_get_contents($privatekeyfile);
            }
            echo 
    "Private key (keep this private!):" PHP_EOL $privatekey PHP_EOL;
            echo 
    "Public key:" PHP_EOL $publickey;

            
    //Prepare public key for DNS, e.g.
            //phpmailer._domainkey.example.com IN TXT "v=DKIM1; h=sha256; t=s; p=" "MIIBIjANBg...oXlwIDAQAB"...
            
    $dnskey "$selector._domainkey.$domain IN TXT";
            
    $dnsvalue '"v=DKIM1; h=sha256; t=s; p=" ';
            
    //Some DNS servers don't like ;(semi colon) chars unless backslash-escaped
            
    $dnsvalue2 '"v=DKIM1\; h=sha256\; t=s\; p=" ';

            
    //Strip and split the key into smaller parts and format for DNS
            //Many DNS systems don't like long TXT entries
            //but are OK if it's split into 255-char chunks
            //Remove PEM wrapper
            
    $publickey preg_replace('/^-+.*?-+$/m'''$publickey);
            
    //Strip line breaks
            
    $publickey str_replace(["\r""\n"], ''$publickey);
            
    //Split into chunks
            
    $keyparts str_split($publickey253); //Becomes 255 when quotes are included
            //Quote each chunk
            
    foreach ($keyparts as $keypart) {
                
    $dnsvalue .= '"' trim($keypart) . '" ';
                
    $dnsvalue2 .= '"' trim($keypart) . '" ';
            }
            echo 
    PHP_EOL "DNS key:" PHP_EOL trim($dnskey);
            echo 
    PHP_EOL "DNS value:" PHP_EOL trim($dnsvalue);
            echo 
    PHP_EOL "DNS value (with escaping):" PHP_EOL trim($dnsvalue2);
     

Share This Page