@@ -13,6 +13,7 @@ const internalNginx = require('./nginx');
1313const internalHost = require ( './host' ) ;
1414const certbot_command = '/usr/bin/certbot' ;
1515const le_config = '/etc/letsencrypt.ini' ;
16+ const dns_plugins = require ( '../../utils/certbot-dns-plugins' )
1617
1718function omissions ( ) {
1819 return [ 'is_deleted' ] ;
@@ -141,11 +142,11 @@ const internalCertificate = {
141142 } ) ;
142143 } )
143144 . then ( ( in_use_result ) => {
144- // Is CloudFlare, no config needed, so skip 3 and 5.
145- if ( data . meta . cloudflare_use ) {
145+ // With DNS challenge no config is needed, so skip 3 and 5.
146+ if ( certificate . meta . dns_challenge ) {
146147 return internalNginx . reload ( ) . then ( ( ) => {
147148 // 4. Request cert
148- return internalCertificate . requestLetsEncryptCloudFlareDnsSsl ( certificate , data . meta . cloudflare_token ) ;
149+ return internalCertificate . requestLetsEncryptSslWithDnsChallenge ( certificate ) ;
149150 } )
150151 . then ( internalNginx . reload )
151152 . then ( ( ) => {
@@ -772,35 +773,58 @@ const internalCertificate = {
772773 } ,
773774
774775 /**
775- * @param {Object } certificate the certificate row
776- * @param {String } apiToken the cloudflare api token
776+ * @param {Object } certificate the certificate row
777+ * @param {String } dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
778+ * @param {String | null } credentials the content of this providers credentials file
779+ * @param {String } propagation_seconds the cloudflare api token
777780 * @returns {Promise }
778781 */
779- requestLetsEncryptCloudFlareDnsSsl : ( certificate , apiToken ) => {
780- logger . info ( 'Requesting Let\'sEncrypt certificates via Cloudflare DNS for Cert #' + certificate . id + ': ' + certificate . domain_names . join ( ', ' ) ) ;
782+ requestLetsEncryptSslWithDnsChallenge : ( certificate ) => {
783+ const dns_plugin = dns_plugins [ certificate . meta . dns_provider ] ;
784+
785+ if ( ! dns_plugin ) {
786+ throw Error ( `Unknown DNS provider '${ certificate . meta . dns_provider } '` )
787+ }
788+
789+ logger . info ( `Requesting Let'sEncrypt certificates via ${ dns_plugin . display_name } for Cert #${ certificate . id } : ${ certificate . domain_names . join ( ', ' ) } ` ) ;
781790
782- let tokenLoc = '~/cloudflare-token' ;
783- let storeKey = 'echo "dns_cloudflare_api_token = ' + apiToken + '" > ' + tokenLoc ;
791+ const credentials_loc = `/etc/letsencrypt/credentials-${ certificate . id } ` ;
792+ const credentials_cmd = `echo '${ certificate . meta . dns_provider_credentials . replace ( "'" , "\'" ) } ' > '${ credentials_loc } ' && chmod 600 '${ credentials_loc } '` ;
793+ const prepare_cmd = 'pip3 install ' + dns_plugin . package_name + '==' + dns_plugin . package_version ;
784794
785- let cmd =
786- storeKey + ' && ' +
795+ const main_cmd =
787796 certbot_command + ' certonly --non-interactive ' +
788797 '--cert-name "npm-' + certificate . id + '" ' +
789798 '--agree-tos ' +
790799 '--email "' + certificate . meta . letsencrypt_email + '" ' +
791800 '--domains "' + certificate . domain_names . join ( ',' ) + '" ' +
792- '--dns-cloudflare --dns-cloudflare-credentials ' + tokenLoc +
793- ( le_staging ? ' --staging' : '' )
794- + ' && rm ' + tokenLoc ;
801+ '--authenticator ' + dns_plugin . full_plugin_name + ' ' +
802+ '--' + dns_plugin . full_plugin_name + '-credentials "' + credentials_loc + '"' +
803+ (
804+ certificate . meta . propagation_seconds !== undefined
805+ ? ' --' + dns_plugin . full_plugin_name + '-propagation-seconds ' + certificate . meta . propagation_seconds
806+ : ''
807+ ) +
808+ ( le_staging ? ' --staging' : '' ) ;
809+
810+ const teardown_cmd = `rm '${ credentials_loc } '` ;
795811
796812 if ( debug_mode ) {
797- logger . info ( 'Command:' , cmd ) ;
813+ logger . info ( 'Command:' , ` ${ credentials_cmd } && ${ prepare_cmd } && ${ main_cmd } && ${ teardown_cmd } ` ) ;
798814 }
799815
800- return utils . exec ( cmd ) . then ( ( result ) => {
801- logger . info ( result ) ;
802- return result ;
803- } ) ;
816+ return utils . exec ( credentials_cmd )
817+ . then ( ( ) => {
818+ return utils . exec ( prepare_cmd )
819+ . then ( ( ) => {
820+ return utils . exec ( main_cmd )
821+ . then ( async ( result ) => {
822+ await utils . exec ( teardown_cmd ) ;
823+ logger . info ( result ) ;
824+ return result ;
825+ } ) ;
826+ } ) ;
827+ } ) ;
804828 } ,
805829
806830
@@ -817,7 +841,7 @@ const internalCertificate = {
817841 } )
818842 . then ( ( certificate ) => {
819843 if ( certificate . provider === 'letsencrypt' ) {
820- let renewMethod = certificate . meta . cloudflare_use ? internalCertificate . renewLetsEncryptCloudFlareSsl : internalCertificate . renewLetsEncryptSsl ;
844+ let renewMethod = certificate . meta . dns_challenge ? internalCertificate . renewLetsEncryptSslWithDnsChallenge : internalCertificate . renewLetsEncryptSsl ;
821845
822846 return renewMethod ( certificate )
823847 . then ( ( ) => {
@@ -877,22 +901,42 @@ const internalCertificate = {
877901 * @param {Object } certificate the certificate row
878902 * @returns {Promise }
879903 */
880- renewLetsEncryptCloudFlareSsl : ( certificate ) => {
881- logger . info ( 'Renewing Let\'sEncrypt certificates for Cert #' + certificate . id + ': ' + certificate . domain_names . join ( ', ' ) ) ;
904+ renewLetsEncryptSslWithDnsChallenge : ( certificate ) => {
905+ const dns_plugin = dns_plugins [ certificate . meta . dns_provider ] ;
882906
883- let cmd = certbot_command + ' renew --non-interactive ' +
907+ if ( ! dns_plugin ) {
908+ throw Error ( `Unknown DNS provider '${ certificate . meta . dns_provider } '` )
909+ }
910+
911+ logger . info ( `Renewing Let'sEncrypt certificates via ${ dns_plugin . display_name } for Cert #${ certificate . id } : ${ certificate . domain_names . join ( ', ' ) } ` ) ;
912+
913+ const credentials_loc = `/etc/letsencrypt/credentials-${ certificate . id } ` ;
914+ const credentials_cmd = `echo '${ certificate . meta . dns_provider_credentials . replace ( "'" , "\'" ) } ' > '${ credentials_loc } ' && chmod 600 '${ credentials_loc } '` ;
915+ const prepare_cmd = 'pip3 install ' + dns_plugin . package_name + '==' + dns_plugin . package_version ;
916+
917+ const main_cmd =
918+ certbot_command + ' renew --non-interactive ' +
884919 '--cert-name "npm-' + certificate . id + '" ' +
885- '--disable-hook-validation ' +
886- ( le_staging ? '--staging' : '' ) ;
920+ '--disable-hook-validation' +
921+ ( le_staging ? ' --staging' : '' ) ;
922+
923+ const teardown_cmd = `rm '${ credentials_loc } '` ;
887924
888925 if ( debug_mode ) {
889- logger . info ( 'Command:' , cmd ) ;
926+ logger . info ( 'Command:' , ` ${ credentials_cmd } && ${ prepare_cmd } && ${ main_cmd } && ${ teardown_cmd } ` ) ;
890927 }
891928
892- return utils . exec ( cmd )
893- . then ( ( result ) => {
894- logger . info ( result ) ;
895- return result ;
929+ return utils . exec ( credentials_cmd )
930+ . then ( ( ) => {
931+ return utils . exec ( prepare_cmd )
932+ . then ( ( ) => {
933+ return utils . exec ( main_cmd )
934+ . then ( async ( result ) => {
935+ await utils . exec ( teardown_cmd ) ;
936+ logger . info ( result ) ;
937+ return result ;
938+ } ) ;
939+ } ) ;
896940 } ) ;
897941 } ,
898942
0 commit comments