Tag Archives: centos

Certbot: auto-renew LetsEncrypt certificate on cron

Certificates renewal can be difficult to automate leading to errors that will mark the website as “Insecure”.

Here’s how to automate certificate renewal on CentOS 7 with nginx as webserver:

su -
(root password)
crontab -e

And then add to the crontab these lines pressing A to edit:

37 02 * * * /usr/local/sbin/certbot-auto renew
39 02 * * * /usr/bin/systemctl reload nginx

Every day at 02.37 the certificate will be asked for renewal. Two minutes later nginx will be restarted.

After you’ve typed these lines, type:


To write and quit. You’ll get this message:

crontab: installing new crontab

Other Linux distributions

If you’re using a different Linux OS you can locate certbot-auto using the following command:

whereis certbot-auto

And then you can use it on the crontab.

You’ve also to use the alternative of systemctl for your system to refresh the certificates on the webserver.

If you’ve to do get your first certificate, here you can get more information about how to install free Let’s Encrypt certificates on nginx.

When auto-renew certificates

Since certificates lasts for about three months, you can tell crontab to run this every week instead every day.

To do so, change the lines on crontab like this:

37 02 * * 0 /usr/local/sbin/certbot-auto renew
39 02 * * 0 /usr/bin/systemctl reload nginx

Adding the 0 on the 5th position will tell crontab to run the command every Sunday at 2 AM (2nd position) and 37 minutes (1st position).

If you find this syntax difficult you can use crontab.guru to easily generate the crontab.


Autolaunch a command and restart it on quit on CentOS

I’ve a django-admin command running as a server thanks to gevent. I want this server to run on boot and autorestart on quit.  StackOverflow give me a hint: use Supervisor.

On a Centos 5 distro:

# find supervisor for your distro...
yum search supervisor
# ...and install it
yum install supervisor.noarch
nano /etc/supervisord.conf

At the end of the file, add a new program:

command=/usr/bin/env python26 /usr/local/etc/django-apps/foo/manage.py tcpapi 4114
priority=999                ; the relative start priority (default 999)
autostart=true              ; start at supervisord start (default: true)
autorestart=true            ; retstart at unexpected quit (default: true)
; startsecs=-1                ; number of secs prog must stay running (def. 10)
; startretries=3              ; max # of serial start failures (default 3)
exitcodes=0,2               ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT             ; signal used to kill process (default TERM)
; stopwaitsecs=10             ; max num secs to wait before SIGKILL (default 10)
; user=root                   ; setuid to this UNIX account to run the program
log_stdout=true             ; if true, log program stdout (default true)
log_stderr=true             ; if true, log program stderr (def false)
logfile=/var/log/myfunnydjangocommand.log    ; child log path, use NONE for none; default AUTO
logfile_maxbytes=1MB        ; max # logfile bytes b4 rotation (default 50MB)
logfile_backups=10          ; # of logfile backups (default 10)

Then, start supervisord.

service supervisord start

Take a look to supervisord log file:

less +G /var/log/supervisor/supervisord.log

You’ll see something like this:

2013-06-07 11:54:16,559 CRIT Supervisor running as root (no user in config file)
2013-06-07 11:54:16,576 INFO /var/tmp/supervisor.sock:Medusa (V1.1.1.1) started at Fri Jun  7 11:54:16 2013
        Hostname: <unix domain socket>
2013-06-07 11:54:16,645 CRIT Running without any HTTP authentication checking
2013-06-07 11:54:16,654 INFO daemonizing the process
2013-06-07 11:54:16,657 INFO supervisord started with pid 19316
2013-06-07 11:54:16,666 INFO spawned: 'myfunnydjangocommand' with pid 19318
2013-06-07 11:54:17,670 INFO success: myfunnydjangocommand entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

Read documentation about the configuration options but keep in mind your Supervisor version. I don’t use supervisorctl because of this bug, if you get an error simply go with service supervisord… but if you have a newer version this should be already fixed.

Note: myfunnydjangocommand.log doesn’t contain anything useful in my experience but maybe it’s related how I write the output since I’ve written it to use interactively, outputting lines directly to the user. I’ll update this post if I find how to solve this issue.

Apache CentOS 6 cannot send email and Drupal get HTTP request status fails

I’m installing a Pressflow 6 on a new machine running CentOS 6. I’m using Apache MPM Worker with FastCGI. Then I get the classical e-mail error:

Unable to send e-mail. Please contact the site administrator if the problem persists.

Then I try to use sendmail:

sendmail -v yourmail@example.com < testmail

Where testmail is a file containing these lines:

Subject: test mail Ozu
Yasujiro Ozu
[blank line here]

And i get the message. PHP cannot send email through apache!

Trying a simple php script to send mail like drupal core do I got this error:

sendmail: fatal: chdir /var/spool/postfix: Permission denied

Then I check this variable following this awesome post:

# /usr/sbin/getsebool httpd_can_sendmail
httpd_can_sendmail --> off

Enable httpd_can_sendmail solve this issue:

setsebool -P httpd_can_sendmail 1

And wait. It will be a long wait using the -P option. And then PHP and Drupal can send mail.

Then check again the variable:

# /usr/sbin/getsebool httpd_can_sendmail
httpd_can_sendmail --> on

Now httpd can send mail. Try your script again.

The SMTP Authentication Support module is not working. This is another of these variables, the same that causes Drupal to show the “HTTP request status fails” message.

setsebool -P httpd_can_network_connect 1

And wait again. Both the SMTP module and the base Drupal networking are now working and Status report is all green.