Using Let’s Encrypt with getssl and minimal root usage #letsencrypt

Let's Encrypt is an amazing initiative to have X.509 certificates for your website, or even your email servers, but most instructions just tell you to run (some more some less) complicated programs as root in order to run the periodic certificate renewal workflows, and that is sub-optimal as it substantially increases the number of attack vectors your already exposed system is susceptible to.

This article is just a way to enjoy the benefits of Let’s Encrypt while minimizing the need for root privileges in your system,and thus keeping it reasonably secure, and this example is doing it with getssl (don’t be scared it hasn’t changed much for some time, they’re working on the new APIv2 support).

It’s taking in account a typical CentOS/Red Hat 7 server, your mileage might vary with other systems but it should mostly be the same.

You can start setting up your environment by adding a non privileged user, let’s say… acme… who will run the renewal workflow:

# useradd acme

Then you can proceed to installing getssl and setting up directories for your files:

# curl https://raw.githubusercontent.com/srvrco/getssl/master/getssl > /usr/local/bin/getssl
# chmod 0755 /usr/local/bin/getssl
# mkdir -p /etc/letsencrypt/acme/ssl.{crt,key,pem}
# chown -R acme:acme /etc/letsencrypt/acme
# chmod -R 0755 /etc/letsencrypt
# chmod 0750 /etc/letsencrypt/acme/ssl.{key,pem}
# mkdir -p /var/www/html/letsencrypt/.well-known/acme-challenge
# chown letsencrypt:letsencrypt /var/www/html/letsencrypt/.well-known/acme-challenge
# echo 'letsencrypt yourhostname=NOPASSWD: /usr/bin/systemctl restart httpd' >> /etc/sudoers.d/letsencrypt

That last line adding a sudo rule is part of the magic and the single root command that is executed.  You can also make it restart Postfix, Dovecot, or any other service you use a certificate and that needs restarting in order to take the new certificate.

In order to let you read it all from this article, I’ll borrow the example’s from getssl’s github page and then add in my own suggestions.

Now you want to prepare the environment (as the user acme) for your domain:

getssl -c yourdomain.com

This will create a ~/.getssl/yourdomain.com directory, the main files you want are called getssl.cfg, there’s a global file on ~/.getssl/getssl.cfg and then more specific files per domain, ~/.getssl/yourdomain.com/getssl.cfg

In the main file, ~/.getssl/getssl.cfg, you’ll need to set up the values accordingly to your needs (I won’t dive into how to get an account), but  for this setup you’ll want to change the following:

RELOAD_CMD="/usr/bin/sudo systemctl restart httpd"
ACL=('/var/www/html/letsencrypt/.well-known/acme-challenge')
CA_CERT_LOCATION="/etc/letsencrypt/acme/ssl.crt/lets-encrypt-x3-cross-signed.pem
RENEW_ALLOW="30"

And that RELOAD_CMD right there is part of the magic…

Now edit  ~/.getssl/yourdomain.com/getssl.cfg and change the following:

DOMAIN_CERT_LOCATION="/etc/letsencrypt/acme/ssl.crt/yourdomain.com.crt"
DOMAIN_KEY_LOCATION="/etc/letsencrypt/acme/ssl.key/yourdomain.com.key"

Now all you need is to set up a cron job:

45 6 * * * /home/letsencrypt/getssl -u -a -q

And finally you configure Apache httpd to use the files paths for the CERTificate and its KEY:

(...)
SSLCertificateFile /etc/letsencrypt/acme/ssl.crt/blog.1407.org.crt
SSLCertificateKeyFile /etc/letsencrypt/acme/ssl.key/blog.1407.org.key
SSLCertificateChainFile /etc/letsencrypt/acme/ssl.crt/lets-encrypt-x3-cross-signed.pem
Alias /.well-known/acme-challenge /var/www/html/letsencrypt/.well-known/acme-challenge
(...)

And you’re done: the cron job will run every day, and when you reach the 30 days to renew threshold your certificate will be renewed with minimal root usage.

 

Não, #Lidl e #SilverCrest, depois de vender vocês não mandam…

Caros Lidl e SilverCrest,

Gostei muito dos auscultadores que comprei esta semana na vossa loja mas fiquei a-bis-ma-do com a vossa falta de vergonha e muita lata:

Condições de utilização

«Os auscultadores só podem ser utilizados para uso privado, e não com fins industriais ou comerciais

O quê? Mas a que propósito se acham sequer com coragem de declarar isto? É vergonhoso que achem isto correto!

Depois desta falta de vergonha, ainda têm a distinta lata de terminar com a seguinte frase ao virar a página, na mesma secção:

«Deve respeitar as leis e os regulamentos nacionais do país de utilização.»

Olha, ninguém quererá mesmo saber disto, eu por mim estou só a dar um desabafo e vocês, Lidl e SilverCrest, seguramente nem querem saber.

A verdade é que eu estou satisfeito com o produto e vocês ficaram satisfeitos com o dinheiro.

Só não dou o devido uso a este papel porque prefiro algo muito mais fofinho, está bem? 🙂

I retired some pants, thanks to #keto

After having passed yesterday feeling always very worried my pants would fall off, I did a most needed check on pant sizes.

7 were retired for being too big to use, even with a belt
4 I can still use, with a belt
2 perfect fits (and boy did I miss these two 501’s)
3 that are still a bit too tight to feel comfortable

This means I should consider buying a few transitional cheap pants in a couple of months,  on the sales period.

All this I achieved by keeping myself quite faithful to a ketogenic diet.

No more staples!

I was told in follow-up that I’d be having some of the staples removed today, but things looked so good that all of them were removed!

image
Staples, after removal

In a few days, the remaining stitches will also be removed.

Got rid of a plugin!

In WordPress , it’s not so much the CMS or PHP that’s usually the problem but most frequently plugins.

So whenever one can get rid of a plugin, it’s always a cause for celebration.

Yay, for I now use WordPress’s native galleries!

I’ve had surgery #hospitalporn

Back in May 29th I woke up fresh, well humoured, proceeded to have a shower and just afterwards, as I dried myself, in a matter of naught but a couple of seconds I thought an explosion had gone off in my head, the strongest headache I ever felt fired up and left me unable to do anything, having to wake up my family to take me to the big H, fearing the worse (stroke, or something worse entirely).

This post will have some gore imagery but it won’t be automatically displayed, you’ll have to click the images in order to view them. It was so traumatic to me that I need to do this as a sort of catharsis.

WARNING: it is long, and it’s mean, and VIEWER DISCRETION IS ADVISED.

Continue reading “I’ve had surgery #hospitalporn”

Simple experiment with systemd-networkd and systemd-resolved

In my previous post, I wrote about how simple it was to create containers with systemd-nspawn.

But what if you wanted to expose to the outside network to a container? The rest of the world can’t add mymachines to /etc/nsswitch.conf and expect it to work, right?

And what if you were trying to reduce the installed dependencies in an operating system using systemd?

Enter systemd-networkd and systemd-resolved

Firstly, this Fedora 25 host is a kvm guest so I added a new network interface for “service” were I created the bridge (yes, with nmcli, why not learn it as well on the way?)

nmcli con add type bridge con-name Containers ifname Containers
nmcli con add type ethernet con-name br-slave-1 ifname ens8 master Containers
nmcli con up Containers

Then, in container test, I configured a rule to use DHCP (and left in a modicum of a template for static addresses, no… that’s not my network) and replaced /etc/resolve.conf with a symlink to the file systemd-resolved manages:

cat <<EOF > /etc/systemd/network/20-default.network
[Match]
Name=host0

[Network]
DHCP=yes
# or swap the above line by the lines below:
#Address=192.168.10.100/24
#Gateway=192.168.10.1
#DNS=8.8.8.8
EOF

rm /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

Finally, I enabled and started networkd and resolved:

systemctl enable systemd-networkd
systemctl enable systemd-resolved
systemctl start systemd-networkd
systemctl start systemd-resolved

A few seconds later…

-bash-4.3# ip addr list dev host0
2: host0@if29: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
 link/ether 06:14:9c:9e:ac:ca brd ff:ff:ff:ff:ff:ff link-netnsid 0
 inet 192.168.10.92/24 brd 192.168.10.255 scope global host0
 valid_lft forever preferred_lft forever

-bash-4.3# cat /etc/resolv.conf 
# This file is managed by systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known DNS servers.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 192.168.10.1

Happy hacking!