dev

Is This a Common Way How Software is Developed and Delivered to Big, non-IT Companies in These Days? Really?

Overview

Before almost a year my friend developing mobile applications asked me to help him with importing some data into Azure DocumentDb because he has never worked with it. When I asked him why he was doing it instead of somebody who was responsible for it, he replied that there was nobody else. So we imported data, wrote a manual. And at this point the fun begun.

A Story

A company A wanted a mobile game (with some backed stuff). Because of internal rules, one company made analysis and another company developed the product. So firm B wrote a business analysis. Company C did the backend part and company D did mobile apps. Because there was another company’s A politics, company E was maintaining many backend apps for company (and it happened that even the company E was taking money for it they were not able to update db).
The game had to be developed for all platforms, even not so common Windows Phone, so external developer F made this version for C. A department of company A (G) was controlling sign process for app stores and required manuals for mobile apps. Which is correct. IOS and Android was published without problems, WP not.
Because of “Works on my machine”, there was a problem with WP app. So why not to go to the company and solve the problem on site? The problem was the developer F. He didn’t want to go. Don’t ask me why, I don’t know. So they asked me if I could try to make it working. I have never worked with Unity and I wrote just two simple WP apps for fun – not so many experiences. It took me a few hours to inspect the code and make it working successfully (e.g., Unity needs full paths that is almost not possible to change and the better solution is to create same folder structure as on original PC where the project created). So I compiled it and sent it to store under my account. Good, it was working. Next I wrote a tutorial and went to G department. We run the app build and it failed. There were missing libraries. After inspection we found the problem. The app was targeted for Visual Studio 2015, but the firm run officially on Visual Studio 2013. But there was no requirement for that. So we changed versions of referenced libs to older versions, built it, signed it and deployed it. Finally with success, but it took us time that could be saved.

A single diagram of relations
A single diagram of relations

A Story Continues

After more than half a year I was asked to update the app backend. Ok. Give me specification and code. They sent me the code in a zip file. There was no source control. That was all they had. The app was not able to build because of missing configuration file that was excluded from the source versioning system (it was easy to fix, but it should be mentioned somewhere – there were custom keys for app configuration). When I opened the project, there was no single test. But a lot of TODO comments about what is missing and should be done. No code comment. Next it had a strange code structure – mixture of models and business logic together. Entities from DocumentDb were sent out of the API exposing internal _id and other properties that should not be published to API consumer. Next, there was no official staging environment, simply nothing. …

Conclusion

My question is how is this possible in these days (and that is not all):

  • No backend code documentation for the company A (G).
  • No official code versioning in company’s A (G) repository.
  • No staging environment.
  • No tests – how to update the app if we do not know if the change did not corrupt current functionality.
  • It seems there was no company’s A (G) code review process because of many TODOs and design mistakes.
  • Specification does not contain such non-functional requirements.
  • Company that is paid for controlling particular apps using particular technology does not manage this technology.
  • This quite simple app, so what about some bigger and more complex project?
  • What about lost money?

So I hope that this is not a common model how a software for companies is done. Especially in these days with hundreds of tutorials, best practices, certifications and audits.

dev

From StartSSL to Let’s Encrypt on Raspbian (and Azure or IIS)

Outline

I have been using free StartSSL certificates for many years on my sites running on Azure or Raspberry PI. All what I had to do was generation of a new certificate once a year. But suddenly, after renew of the certificate this January, Chrome started to show that my site is untrusted with NET::ERR_CERT_AUTHORITY_INVALID error. There was no error in Edge or Firefox or in Chrome on other machine. After some searching there were some hints to clear browser (system) cache, etc., but without any progress. Still the same error. So I decided to use Let’s Encrypt (LE) [1] for this site, the most popular free certificate provided in these days.

Setup on Raspbian Jessie with Nginx

To be able to use Certbot [2], an official tool from LE, you must setup it in following way. I have inspired in Digital Ocean tutorial [3]. Suppose we have site exemple.org and files located in /var/www/example.org:

# download certbot-auto (there is no official Certbot package for Raspbian)
cd /usr/local/sbin
sudo wget https://dl.eff.org/certbot-auto
sudo chmod a+x /usr/local/sbin/certbot-auto

# run the tool
# you will be asked to set a contact email and agree with TOS
certbot-auto certonly -a webroot --webroot-path=/var/www/example.org -d example.org -d www.example.org

Now, certificates should be stored in /etc/letsencrypt/archive/example.org. This folder contains all needed files: cert.pem (site certificate), chain.pem (ceritficate chain), fullchain.pem (combination of previous) and privkey.pem (your private key).

All these files have symlinks create in /etc/letsencrypt/live/example.org and you should use these symlinks in your Nginx config.

Edit crontab:

sudo crontab -e

Add following lines:

# Run every Monday at 2:30 am
30 2 * * 1 /usr/local/sbin/certbot-auto renew >> /var/log/le-renew.log
# Run every Monday at 2:35 am
35 2 * * 1 /etc/init.d/nginx reload 

Generate Diffe-Helman Group (DHG):

To raise security, generate DHG. For more details check [4].

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Update your nginx site configuration (suppose file /etc/nginx/sites-available/default):

...
listen 443 ssl;
server_name example.org www.example.org;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on; # for nginx since v1.3.7
ssl_stapling_verify on; # for nginx sincev1.3.7
add_header Strict-Transport-Security max-age=15768000;
...

Finally, check if Nginx configuration is ok and reload it:

sudo nginx -t
sudo service nginx reload

Generate Certificate with Own CSR File

But there is one problem – certbot creates own new private key and csr. But what if I want to use own private key (or do not belive to certbot about using generated private key). There is a –csr option where you can specify path to own csr file. But with this flag you have to manage all certificate files yourself (–cert-path, –chain-path and –fullchain-path), see documentation for more details [5]. Certbot does not know about them and certbot renew command does not work with it.

Next, if you run the command again to simulate the renew, it fails because the script tries to create new certificates, but they already exist [6]. So possible solution is to create a script that removes these files before calling certbot again (do not forget to change path to private key and full-chain files in nginx config):

#!/bin/bash
echo "Removing old certs"
# remove old certs (certbot fails when they exist)
rm -rf PATH_TO_CRT PATH_TO_CHAIN PATH_TO_FULL_CHAIN
# generate new certificate
echo "Generation of new certificates"
certbot-auto certonly -a webroot --webroot-path=/var/www --csr PATH_TO_CSR --cert-path PATH_TO_CRT --chain-path PATH_TO_CHAIN --fullchain-path PATH_TO_FULL_CHAIN
# reload nginx
echo "Reloading nginx"
service nginx reload

Finally, add this script to cronjob

# Run every Monday at 2:30 am
30 2 * * 1 PATH_TO_UPDATE_SCRIPT

Or, there is another solution using acme-tiny tool [7, 8]

Now, you validate your site for the security: https://www.ssllabs.com/ssltest/analyze.html?d=YOUR_WEB_SITE

ssltest

Let’s Encrypt in Azure and IIS

There are good tutorial how to use LE on Azure [9] and IIS [10].

Conclusion

StartSSL is a good service providing free Class 1 site certificates. Certificate is valid for one year and the request process is well described. The only problem is every year renew procedure which takes a few minutes and user has to know something about certificates. LE is a very popular service for free site certificates in these days. Certificate is valid just for 90 days, but on the other side there are tools that manage automatic renew that makes it usable for many people and can be in various situations, e.g., in combination with Docker.

References

  1. https://letsencrypt.org/
  2. https://certbot.eff.org
  3. https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-14-04
  4. https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
  5. https://certbot.eff.org/docs/using.html#certbot-command-line-options
  6. https://community.letsencrypt.org/t/certbot-with-csr-doesnt-put-cert-in-live-path/16901/3
  7. https://scotthelme.co.uk/setting-up-le/
  8. https://scotthelme.co.uk/lets-encrypt-smart-renew/
  9. https://gooroo.io/GoorooTHINK/Article/16420/Lets-Encrypt-Azure-Web-Apps-the-Free-and-Easy-Way/21872#.WJXnYzsrKCo
  10. https://weblog.west-wind.com/posts/2016/feb/22/using-lets-encrypt-with-iis-on-windows