Archive for the 'Software' category

Missing colors for PHPUnit

published on July 20, 2016.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

I ran accross a minor issue today that I never experienced before. The colors for the PHPUnit’s output were missing. I had the colors=true directive set in the phpunit.xml configuration file, but the output was just black and white.

Turns out I was missing the posix extension, which is provided by the php-process package on Fedora. After installing it:

$ sudo dnf install php-process

all was good again in the world of unit testing.

Oh well.

Happy hackin’!

Tags: phpunit, php.
Categories: Programming, Software, Development.

Setting up SSL certificates with Let's Encrypt

published on July 06, 2016.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

SSL Report Summary

This past week I finally got around to setting up SSL certificates using Let’s Encrypt. Let’s Encrypt is an open certificate authority that provides free SSL/TLS certificates. It’s goal is to make creating, renewing and using SSL certs painless.

And it most certainly is. I was expecting a lot more hassle to set up all this, but it was really easy to do.

Install certbot

Certbot is a Let’s Encrypt client that helps setting up a certificate by obtaining and installing it on your servers. There are many more clients out there, but certbot is the recommended one to use.

I simply installed certbot using dnf:

sudo dnf install certbot

but if your OS has no package for it yet, there’s always the manual way.

Creating a certificate

Certbot has a number of plugins that can be used to create and install a certificate on a server. I chose the webroot plugin which only gets the certificate for me and leaves the webserver configuration up to me.

sudo certbot --text --renew-by-default --agree-tos --webroot \
--email youremail@domain.tld \
--domains domain.tld,www.domain.tld \
--webroot-path /path/to/site/public \
certonly

This will create the certificate and it’s private key in the /etc/letsencrypt/live/domain.tld/ directory.

Configuring nginx

The next step is to configure nginx by enabling SSL, providing the paths to the certificate and the private key, and which protocols and ciphers to use. I added these to the server block:

listen 443 ssl;

ssl on;
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

After restarting nginx, you should be able to load up your site through https. Just remember to allow traffic on the 443 port:

sudo firewall-cmd -add-service=https --permanent
sudo firewall-cmd reload

Additional configuration

To further harden the Diffie-Helman key exchange, create new parameters for it using openssl:

sudo mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
sudo openssl dhparam -out dhparams.pem 2048

I told nginx to use it by adding it to the same server block where I set up the SSL configuration:

ssl_dhparam /etc/nginx/ssl/dhparams.pem;

I also did some SSL optimizations and enabled Strict Transport Security:

ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_buffer_size 8k;
add_header Strict-Transport-Security max-age=31536000;

This blog post explains HTTP Strict Transport Security nicely.

All this and my website gets an A+ rating on the Qualys SSL Server Test.

Enable OCSP stapling

Thanks to Goran Jurić for pointing out to enable OCSP stapling. I did so by adding this to the nginx server config:

ssl_stapling on;
ssl_stapling_verify on;

According to the nginx documentation the ssl_trusted_certificate directive is needed only when the ssl_certificate file does not contain intermediate certificates, but the fullchain.pem created by Let’s Encrypt does contain them, so I’m skipping that.

To test whether OCSP stapling is enabled, reload nginx, and from a local terminal run the following:

openssl s_client -connect domain.tld:443 -status

The output should have something like:

OCSP response:
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

Installing Python2 with Ansible

published on June 29, 2016.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Ansible uses Python2 to run the provisioning commands on the host machines. At this time it does not support Python3, which is the default python version in Fedora releases for quite some time now.

So to be able to manage Fedora machines with Ansible, I need to install Python2, but how to install it when all the Ansible modules depend on Python2 being installed? Turns out it’s quite simple, by turning of the gathering of facts in Ansible and using the raw module to install the required packages:

- hosts: all
  gather_facts: no
  become: yes
  tasks:
    - name: Install python2 and python2-dnf
      raw: dnf -y install python2 python2-dnf
    - name: Gather facts
      setup:

Just remember this needs to be the very first thing that happens on all your Fedora hosts. After python2 is installed, gather the facts for all the hosts by running the setup module.

Happy hackin’!

Creating a PostgreSQL user in Vagrant with Ansible

published on June 28, 2016.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Lately I’ve been playing around with provisioning a PostgreSQL server with Ansible in a local Vagrant machine that runs a Fedora 23 image.

The first task after installing and starting the PostgreSQL server is to create a database user and a database. So far I have found an ugly way, a really ugly way and a nice way to do this.

How it should be done

The proper way to do this would be to use the postgresql_user Ansible module and the become, become_user and become_method directives, like so:

- name: Create a PostgreSQL database user
  postgresql_user: name=project password=project role_attr_flags=CREATEDB state=present
  become: yes
  become_user: postgres
  become_method: sudo

But this fails because sudo expects us to enter the password:

TASK [postgresql : Create user] ************************************************
fatal: [default]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", "module_stdout": "sudo: a password is required\r\n", "msg": "MODULE FAILURE", "parsed": false}

You can read more about privilege escalation in Ansible in their documentation.

The really ugly way

This solution is so bad I’m not even sure I should write it down. It depends on changing the default identification method for local connections from peer to the trust method, so we can use the default vagrant user to create new users without any checks, based only on, well, trust.

- name: Change peer identification to trust
  shell: /bin/sed -i '/^local/s/peer/trust/' /var/lib/pgsql/data/pg_hba.conf
  notify: restart dbserver

- meta: flush_handlers

- name: Create a PostgreSQL database user
  postgresql_user: name=project password=project role_attr_flags=CREATEDB state=present

- name: Change trust identification back to peer
  shell: /bin/sed -i '/^local/s/trust/peer/' /var/lib/pgsql/data/pg_hba.conf
  notify: restart dbserver

- meta: flush_handlers

This is just bad, there must be a better way.

The less ugly way

But still ugly. This is based on running a psql command using the shell Ansible module.

- name: Create a PostgreSQL database user
  shell: sudo -u postgres bash -c "psql -c \"CREATE USER project WITH CREATEDB PASSWORD 'project';\""

This one has an additional problem of that it only works when we run it for the first time, because we can’t create the same user twice. A possible solution would be to wrap the CREATE USER ... in an additional IF NOT EXISTS (SELECT * FROM pg_catalog.pg_user ... query, but that’s just… Ugh. No.

Back to square one

Let’s go back to the way how it should be done, by using the become and become_user directives. But how do we handle the sudo password? We tell sudo to not ask for a password by editing the /etc/sudoers files. The line to add is:

vagrant ALL=(postgres) NOPASSWD:/bin/sh

This tells sudo that the user vagrant on ALL hosts can run the /bin/sh program with NOPASSWD as the user postgres. I’m explicitly limiting the possible commands to /bin/sh as that is the only command we need to be able to run to make things work. I don’t want to add more if I don’t need to.

The Ansible tasks are now:

- name: Enable passwordless sudo
  lineinfile: dest=/etc/sudoers regexp=^vagrant line="vagrant ALL=(postgres) NOPASSWD:/bin/sh"

- name: Create a PostgreSQL database user
  postgresql_user: name=project password=project role_attr_flags=CREATEDB state=present
  become: yes
  become_user: postgres
  become_method: sudo

For added bonus we can cleanup the sudoers file after we are done by removing the line we added.

Happy hackin’!

P.S.: If you want to use a good quality Ansible role for PostgreSQL take a look at this one. Thanks to Gilles Cornu for pointing it out!

GitHub flavoured code fences in Hugo

published on March 28, 2016.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

This was an undocumented feature until today, so I missed it when I was converting my site to Hugo last week. It is also possible to highlight code examples with GitHub flavoured code fences, or, in other words, with triple backticks ```.

I like this a lot because it makes highlighting code in posts easier. Typing the {{< highlight >}} shortcode is just awkward and I always end up forgetting either the angle brackets or add too much or too little currly brackets. Backticks are much nicer.

The code fences are not enabled by default, though. We need to set PygmentsCodeFences to true in Hugo’s configuration file and that’s about it. Everything else about syntax highlighting stays the same.

Change to backticks in old posts

I used these two simple sed one-liners to change all the highlighting shortcodes to the code fences:

find -name "*.md" -print0 | xargs -0 sed -i 's/&#123;&#123;< highlight \([a-z]*\) >&#125;&#125;/``` \1/g'
find -name "*.md" -print0 | xargs -0 sed -i 's/&#123;&#123;< \/highlight >&#125;&#125;/```/g'

Now I don’t even need a custom Vim function to insert the highlighting shortcode. Sweet.

Robert Basic

Robert Basic

Software engineer, consultant, open source contributor.

Let's work together!

If you require outsourcing or consulting help on your projects, I'm available!

Robert Basic © 2008 — 2019
Get the feed