You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Puppet部署Let's Encrypt证书失败致Nginx启动异常求助

问题:Puppet Agent执行时证书文件缺失导致Nginx启动失败

错误现象

执行puppet agent -t --no-noop时出现以下错误:

Error: Could not set 'file' on ensure: No such file or directory @ rb_sysopen - /etc/letsencrypt/live/test.domain.com/cert.pem (file: /etc/puppetlabs/code/environments/production/site/profiles/manifests/letsencrypt.pp, line: 27)
Error: Could not set 'file' on ensure: No such file or directory @ rb_sysopen - /etc/letsencrypt/live/test.domain.com/cert.pem (file: /etc/puppetlabs/code/environments/production/site/profiles/manifests/letsencrypt.pp, line: 27)
Wrapped exception:
No such file or directory @ rb_sysopen - /etc/letsencrypt/live/test.domain.com/cert.pem
Error: /Stage[main]/Profiles::Letsencrypt/File[/etc/letsencrypt/live.test.evolvedbinary.com/cert.pem]/ensure: change from 'absent' to 'file' failed: Could not set 'file' on ensure: No such file or directory @ rb_sysopen - /etc/letsencrypt/live/test.domain.com/cert.pem (file: /etc/puppetlabs/code/environments/production/site/profiles/manifests/letsencrypt.pp, line: 27)

该错误导致Nginx启动失败,日志如下:

Error: Systemd start for nginx failed!
journalctl log for nginx:
-- Logs begin at Fri 2023-08-18 12:11:49 BST, end at Thu 2023-09-07 12:08:25 BST. --
Sep 07 12:08:25 test-web systemd[1]: Starting nginx - high performance web server...
Sep 07 12:08:25 test-web nginx[312617]: nginx: [emerg] cannot load certificate \"/etc/letsencrypt/live/test.domain.com/cert.pem\": BIO_new_file() failed

排查过程

  • 确认/etc/letsencrypt/live/test.domain.com/cert.pem文件未生成是核心问题
  • 在Puppet的letsencrypt.pp中给cert.pem的file资源添加force => true参数,问题未解决
  • 在Agent节点手动用vim创建空白cert.pem文件后,执行Puppet命令仍报错

相关配置文件

letsencrypt.pp

class profiles::letsencrypt {

package { 'cron':
  ensure => installed
}

class { 'letsencrypt':
  require => Package['cron']
}

file { '/etc/letsencrypt/options-ssl-nginx.conf':
  ensure => file,
}

file {'/etc/letsencrypt/ssl-dhparams.pem':
  ensure => file,
}

file {'/etc/letsencrypt/live':
  ensure => directory, 
} 

file {'/etc/letsencrypt/live/test.domain.com':
  ensure => directory,
}

file {'/etc/letsencrypt/live/test.domain.com/cert.pem':
  ensure => file,
}

include 'letsencrypt'
include 'letsencrypt::plugin::dns_cloudflare'
# include 'letsencrypt::plugin::nginx'

  letsencrypt::certonly { '*.test.domain.com':
    domains              => ['*.test.domain.com'],
    plugin               => 'dns-cloudflare',
    manage_cron          => true,
    cron_hour            => [0,12],
    cron_minute          => '30',
    cron_before_command  => 'service nginx stop',
    cron_success_command => '/bin/systemctl reload nginx.service',
    #suppress_cron_output => true,
    require              => Class['nginx'],
  }
} 

test-web.domain.com.yaml

---
classes:
   - roles::www

# UFW Rules
ufw::rules:
  'Allow HTTP':
    action: allow
    to_ports_app: 80
    proto: tcp
  'Allow HTTPS':
    action: allow
    to_ports_app: 443
    proto: tcp

# nginx rules
nginx::nginx_servers:
  'www.test.domain.com':
    server_name: [
      '*.test.domain.com',
      'test.domain.com',
    ]
    ipv6_enable: true
    ssl: true
    http2: 'on'
    ssl_redirect: true
    ssl_cert: '/etc/letsencrypt/live/test.domain.com/cert.pem'
    ssl_key: '/etc/letsencrypt/live/test.domain.com/privkey.pem'
    www_root: '/var/www/www.test.domain.com'
    server_cfg_ssl_append:
      include: '/etc/letsencrypt/options-ssl-nginx.conf'
      ssl_dhparam: '/etc/letsencrypt/ssl-dhparams.pem'
# letsencrypt
letsencrypt::email: 'sysops@domain.com'
letsencrypt::plugin::dns_cloudflare::email: 'user.@email.com'

解决方案

  • 删除手动创建证书的Puppet资源:移除letsencrypt.pp中file {'/etc/letsencrypt/live/test.domain.com/cert.pem': ensure => file,}这一段。证书应由letsencrypt::certonly自动生成,手动创建空文件会干扰证书生成流程,还可能引发权限问题。

  • 修复循环依赖问题:当前letsencrypt::certonly依赖Nginx,但Nginx配置又依赖证书,形成循环。调整依赖关系,让Nginx服务器配置依赖证书生成完成:
    在Puppet的Nginx服务器定义中添加require => Letsencrypt::Certonly['*.test.domain.com'],确保证书生成后再配置启动Nginx。

  • 验证Cloudflare插件配置:确认Cloudflare的API密钥已正确配置(需在Hiera中添加letsencrypt::plugin::dns_cloudflare::api_key: '你的API密钥'),并确保凭据文件权限为600、属主为root,DNS验证失败会直接导致证书无法生成。

  • 手动触发证书生成(临时修复):在Agent节点执行以下命令手动生成证书,验证流程是否正常:

    certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d *.test.domain.com
    
  • 清理重复的Letsencrypt声明:letsencrypt.pp中同时使用了class { 'letsencrypt': }和include 'letsencrypt',保留其中一种即可,推荐保留class { 'letsencrypt': }来统一管理参数,避免重复声明冲突。

内容的提问来源于stack exchange,提问作者Callum McCrorie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:25:55