@@ -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 ( '../global/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,70 @@ 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 ( ', ' ) } ` ) ;
790+
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 ;
781794
782- let tokenLoc = '~/cloudflare-token' ;
783- let storeKey = 'echo "dns_cloudflare_api_token = ' + apiToken + '" > ' + tokenLoc ;
795+ // Whether the plugin has a --<name>-credentials argument
796+ const has_config_arg = certificate . meta . dns_provider !== 'route53' ;
784797
785- let cmd =
786- storeKey + ' && ' +
798+ let main_cmd =
787799 certbot_command + ' certonly --non-interactive ' +
788800 '--cert-name "npm-' + certificate . id + '" ' +
789801 '--agree-tos ' +
790802 '--email "' + certificate . meta . letsencrypt_email + '" ' +
791803 '--domains "' + certificate . domain_names . join ( ',' ) + '" ' +
792- '--dns-cloudflare --dns-cloudflare-credentials ' + tokenLoc +
793- ( le_staging ? ' --staging' : '' )
794- + ' && rm ' + tokenLoc ;
804+ '--authenticator ' + dns_plugin . full_plugin_name + ' ' +
805+ (
806+ has_config_arg
807+ ? '--' + dns_plugin . full_plugin_name + '-credentials "' + credentials_loc + '"'
808+ : ''
809+ ) +
810+ (
811+ certificate . meta . propagation_seconds !== undefined
812+ ? ' --' + dns_plugin . full_plugin_name + '-propagation-seconds ' + certificate . meta . propagation_seconds
813+ : ''
814+ ) +
815+ ( le_staging ? ' --staging' : '' ) ;
816+
817+ // Prepend the path to the credentials file as an environment variable
818+ if ( certificate . meta . dns_provider === 'route53' ) {
819+ main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd ;
820+ }
821+
822+ const teardown_cmd = `rm '${ credentials_loc } '` ;
795823
796824 if ( debug_mode ) {
797- logger . info ( 'Command:' , cmd ) ;
825+ logger . info ( 'Command:' , ` ${ credentials_cmd } && ${ prepare_cmd } && ${ main_cmd } && ${ teardown_cmd } ` ) ;
798826 }
799827
800- return utils . exec ( cmd ) . then ( ( result ) => {
801- logger . info ( result ) ;
802- return result ;
803- } ) ;
828+ return utils . exec ( credentials_cmd )
829+ . then ( ( ) => {
830+ return utils . exec ( prepare_cmd )
831+ . then ( ( ) => {
832+ return utils . exec ( main_cmd )
833+ . then ( async ( result ) => {
834+ await utils . exec ( teardown_cmd ) ;
835+ logger . info ( result ) ;
836+ return result ;
837+ } ) ;
838+ } ) ;
839+ } ) ;
804840 } ,
805841
806842
@@ -817,7 +853,7 @@ const internalCertificate = {
817853 } )
818854 . then ( ( certificate ) => {
819855 if ( certificate . provider === 'letsencrypt' ) {
820- let renewMethod = certificate . meta . cloudflare_use ? internalCertificate . renewLetsEncryptCloudFlareSsl : internalCertificate . renewLetsEncryptSsl ;
856+ let renewMethod = certificate . meta . dns_challenge ? internalCertificate . renewLetsEncryptSslWithDnsChallenge : internalCertificate . renewLetsEncryptSsl ;
821857
822858 return renewMethod ( certificate )
823859 . then ( ( ) => {
@@ -877,22 +913,47 @@ const internalCertificate = {
877913 * @param {Object } certificate the certificate row
878914 * @returns {Promise }
879915 */
880- renewLetsEncryptCloudFlareSsl : ( certificate ) => {
881- logger . info ( 'Renewing Let\'sEncrypt certificates for Cert #' + certificate . id + ': ' + certificate . domain_names . join ( ', ' ) ) ;
916+ renewLetsEncryptSslWithDnsChallenge : ( certificate ) => {
917+ const dns_plugin = dns_plugins [ certificate . meta . dns_provider ] ;
882918
883- let cmd = certbot_command + ' renew --non-interactive ' +
919+ if ( ! dns_plugin ) {
920+ throw Error ( `Unknown DNS provider '${ certificate . meta . dns_provider } '` ) ;
921+ }
922+
923+ logger . info ( `Renewing Let'sEncrypt certificates via ${ dns_plugin . display_name } for Cert #${ certificate . id } : ${ certificate . domain_names . join ( ', ' ) } ` ) ;
924+
925+ const credentials_loc = '/etc/letsencrypt/credentials-' + certificate . id ;
926+ const credentials_cmd = 'echo \'' + certificate . meta . dns_provider_credentials . replace ( '\'' , '\\\'' ) + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'' ;
927+ const prepare_cmd = 'pip3 install ' + dns_plugin . package_name + '==' + dns_plugin . package_version ;
928+
929+ let main_cmd =
930+ certbot_command + ' renew --non-interactive ' +
884931 '--cert-name "npm-' + certificate . id + '" ' +
885- '--disable-hook-validation ' +
886- ( le_staging ? '--staging' : '' ) ;
932+ '--disable-hook-validation' +
933+ ( le_staging ? ' --staging' : '' ) ;
934+
935+ // Prepend the path to the credentials file as an environment variable
936+ if ( certificate . meta . dns_provider === 'route53' ) {
937+ main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd ;
938+ }
939+
940+ const teardown_cmd = `rm '${ credentials_loc } '` ;
887941
888942 if ( debug_mode ) {
889- logger . info ( 'Command:' , cmd ) ;
943+ logger . info ( 'Command:' , ` ${ credentials_cmd } && ${ prepare_cmd } && ${ main_cmd } && ${ teardown_cmd } ` ) ;
890944 }
891945
892- return utils . exec ( cmd )
893- . then ( ( result ) => {
894- logger . info ( result ) ;
895- return result ;
946+ return utils . exec ( credentials_cmd )
947+ . then ( ( ) => {
948+ return utils . exec ( prepare_cmd )
949+ . then ( ( ) => {
950+ return utils . exec ( main_cmd )
951+ . then ( async ( result ) => {
952+ await utils . exec ( teardown_cmd ) ;
953+ logger . info ( result ) ;
954+ return result ;
955+ } ) ;
956+ } ) ;
896957 } ) ;
897958 } ,
898959
0 commit comments