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

runcmd用户数据执行异常:sendmail规则未写入hosts.allow求助

Troubleshooting runcmd Failure to Write to /etc/hosts.allow

Let’s figure out why your cloud-init runcmd isn’t adding sendmail: ALL to /etc/hosts.allow—especially since it works when you run the steps manually. Here are the most probable culprits and fixes:

1. Quote Parsing Conflicts in sh -c

When you wrap the echo command in double quotes inside sh -c, cloud-init’s YAML parser might be mangling the quotes before the shell gets to execute the command. This is a common gotcha with nested quotes in runcmd arrays.

Fix: Adjust the Quoting

Rewrite the first runcmd entry to use single quotes for the inner echo command (escaped properly for YAML):

[ sh, -c, 'echo '\''sendmail: ALL'\'' >> /etc/hosts.allow' ]

Alternatively, swap the quote types to avoid nesting issues:

[ sh, -c, "echo 'sendmail: ALL' >> /etc/hosts.allow" ]

2. Cloud-init Execution Timing

Cloud-init runs modules in a strict order. If runcmd fires before the filesystem is fully mounted or the /etc/hosts.allow file is available (rare, but possible), the append will fail silently.

Fix: Add a Check & Verify Logs

Modify the command to ensure the file exists before appending:

[ sh, -c, 'if [ -f /etc/hosts.allow ]; then echo "sendmail: ALL" >> /etc/hosts.allow; else echo "/etc/hosts.allow missing" >> /var/log/cloud-init-debug.log; fi' ]

Then check cloud-init’s logs for clues:

grep -E "hosts.allow|runcmd" /var/log/cloud-init-output.log

3. Unexpected File Restrictions

Even though runcmd runs as root, /etc/hosts.allow might have an immutable flag set (via chattr) or restrictive ACLs blocking writes.

Fix: Clear Immutable Flags First

Add a quick pre-step to remove the immutable flag if it exists:

[ sh, -c, 'chattr -i /etc/hosts.allow 2>/dev/null; echo "sendmail: ALL" >> /etc/hosts.allow' ]

4. Better Alternative: Use write_files Module

Cloud-init’s write_files module is designed for file modifications and is more reliable than runcmd for appending content. It handles file locking and existence checks natively.

Updated Configuration

Replace your first runcmd entry with this write_files block:

write_files:
  - append: true
    path: /etc/hosts.allow
    content: |
      sendmail: ALL
runcmd:
  - [ sh, -c, 'systemctl restart sendmail' ]
  - [ sh, -c, 'echo "Subject: Instance Deployed" | sendmail user@example.com' ]

Note: I fixed the email address in your sendmail command—there was an extra leading / that would have caused delivery failures.

Debugging Steps to Confirm

After deploying the instance:

  1. Check if the line was added:
    grep "sendmail: ALL" /etc/hosts.allow
    
  2. Review cloud-init logs for errors:
    cat /var/log/cloud-init.log | grep -i error
    

内容的提问来源于stack exchange,提问作者Aru Dubey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:45:29