Category Archives: Ruby on Rails

Ruby on Rails bottom up security – hardening the servers

Reading Time: 3 minutes

TL;DR

Next series of blog posts is about Ruby on Rails bottom up security. I will cover all aspects of web application written in Ruby on Rails framework. Described security concepts could be applied to any other modern web framework because we will describe which security problem particular concept resolves. I will start with hardening the server that runs the web application.

You probably think that hardening (reducing the surface of vulnerability) the server is impossible task. But I will prove you wrong. I found this excellent blog post that is foundation for hardening the server.

It has all instructions for Ubuntu linux how to harden the server. And you could be done with this task in 5 minutes!

Precondition is that server is up and running, and you know root password. You should first login as root.

  1. Select linux distribution

As you probably know, there are various linux distributions. I suggest latest CentOS for two reasons:

  1. it has excellent database about security patches
  2. it is tailored for servers that run server side services (e.g. web application)

2. Change root password

Unix command is

passwd

Tip. We suggest that you use LastPass password manager for creating and storing that password.

2. Update the system

You want to have latest software version as starting point.

yum -y -d 0 -e 0 update yum
yum -y -e 0 -d 0 update

3. Install fail2ban

yum install fail2ban

fail2ban is daemon written in Python that monitors suspicious activities and if detected, automatically bans client ip addresses for some time.

4. create new user

useradd deploy

mkdir /home/deploy

mkdir /home/deploy/.ssh

chmod 700 /home/deploy/.ssh

You will use only that user to connect to your server! Never use root user for establishing ssh connection. Note important command, chmod and number 700. At first, this look very cryptic. Read this for more info, and for now, remember that 700 gives all access ONLY to deploy user to .ssh folder (1+2+4 = 7).

5. ssh using public/private key authentication

In order to connect to your server, you will use ssh without password. How to set up that type of access? I recommend github tutorial:

Check for existing ssh keys is not needed, since you have new fresh server.

Generate new ssh key pair. You should set up password phrase (which is by default optional). Also, add private key  to ssh agent, so you will not need to enter password phrase. Be sure to store password phrase to lastpass!

Test your ssh connection.

Add your public key to the server. Previous link contains instructions how to copy your public key. The you have to paste it:

vim /home/deploy/.ssh/authorized_keys

Save file and run:

chmod 400 /home/deploy/.ssh/authorized_keys chown deploy:deploy /home/deploy -R

Mode 400 is read only. This is highest security, and without that mode, you will get cryptic error when you will try to establish ssh connection.

6. Test The New User

Keep existing terminal open, and from new terminal type:

ssh deploy@server_ip_address

7. Enable sudo

In your first terminal as root, first set deploy user password:

passwd deploy

Save deploy user password in LastPass!

visudo

You are now in vi editor. Comment all lines and add at the bottom:

root ALL=(ALL) ALL

deploy ALL=(ALL) ALL

That means when you will run sudo as deploy user, you WILL BE ASKED TO ENTER PASSWORD!

8. Lock Down SSH

Via ssh, you will not be able to:

  • connect as as root user
  • connect using password
  • connect from any client, but only from clients that you will list in setting.
vim /etc/ssh/sshd_config

Enter this, and be sure that original entries ARE DELETED:

PermitRootLogin no
PasswordAuthentication no
AllowUsers deploy@(your-ip) deploy@(another-ip-if-any)
systemctl sshd restart

9. What about firewall ?

I strongly do not recommend that your server is directly exposed to the Internet. It must be BEHIND dedicated FIREWALL. Ask your IAAS provider about details.

10. Enable Automatic Security Updates

This should be set, at least for security update. Set it in cron to run automatically on daily basis.

vi /etc/cron.daily/yumupdate.sh

#!/bin/bash
 YUM=/usr/bin/yum
 $YUM -y -d 0 -e 0 update yum
 $YUM -y -e 0 -d 0 update

11. Install Logwatch To Keep An Eye On Things

Logwatch is tool that automatically monitors server logs and its logs can give you a hint about server intrusion.

yum install logwatch

vi /etc/cron.daily/logwatch_daily.sh

/usr/sbin/logwatch --output mail --mailto test@gmail.com --detail high

You are done with basic server hardening. In next post, I will explain how to harden servers based on their purpose. Web server, database server, cache server, job server have a slightly different security configuration.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Product moving parts as source for test strategy

Reading Time: 2 minutes

In this post I will explain how I identify product moving parts (what changed in product) as a source for test strategy of product release.

Tools that I am using are Github and Huboard. Everybody knows github, and huboard is application that integrates with Github and creates Kanab board automatically from Github issues. The glue between Kanab and Github are Github labels. Github label assigned to the issue puts that issue in Huboard list.

What are tools if they are not used by humans. Every issue could be an issue or new feature. Their body should contain text that help me to understand what should be implemented. No help of tools if that body is poorly written.

Every huboard issue is connected with Github pull request. Pull request contains all files that are related with that issue. By investigating github pull request, I am identifying product moving parts.

As the application context is Rails application, pull request contains application and data (database migration files) changes. As rails uses MVC pattern, this helps a lot how to direct my testing. For example, if change is in view, controller or model file, I know which feature and scenarios I should test.

If change is in helper file, by searching the codebase for the changed method, I can also identify features that should be tested.

Rails has rake tasks, which are also under github control. If there is change in rake tasks, I know that some scripts should be run in order to prepare environment for the new feature (for example, populate database with static data).

What are the benefits of this ability to identify product moving parts? I do not need to run single browser automation test!

All the testing is done using my brain, eyes, hands and browser.

Browser automation tests are usually developed as part of regression tests. We often hear: “We are running our cucumber tests to be sure that nothing is broken”.

This is not good practice. This is like putting patient again and again through x rays to be sure that he does not have pneumonia. But asking patient questions about his physical conditions can give as quick answer about possible pneumonia.

Instead of putting hours of work in creating scripts for browser automation, try to organize your project  to have:

  • code base under git
  • use kanab boards
  • use branches
  • learn basics how product code is organized (MVC in Rails)
  • learn basic about programming language that is used (Ruby in Rails)

 

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

How to smart test minor version Ruby on Rails upgrade?

Reading Time: 1 minute

TL;DR

In this post I will explain what should be checked after Ruby on Rails minor version upgrade. Minor version upgrades are usually connected with security releases.

As I am subscribed to Ruby on Rails security Google group, when I receive information about latest security issue, I need to act very fast. Update must be pushed to production almost immediately, so there is no time for extensive regression testing.

How can we do quick test and be sure that everything still works as before upgrade?

Heuristic 1. Rails upgrade was extensively regression tested.

That heuristic proved itself to be always true.

Heuristic 2. Inspect Gemfile.lock to be sure that only Rails gem is upgraded.

How do we actually upgrade Ruby on Rails?

Edit gemfile:gem 'rails', '4.2.5.2'
bundle update rails

Investigate Gemfile.lock changes using git diff to see what else was updated beside Rails. If some other gem (not part of Rails) was also updated, check, using Google search, possible issues for that gem that are connected with Rails upgrade.

Heuristic 3. Search Google for Ruby on rails upgrade to n.n.n.n version issues (bugs, problems)

Conclusion.

For minor Ruby on Rails upgrades, using those three heuristics, you can do regression test in smart and quick way.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Simulating time in Ruby on Rails

Reading Time: 1 minute

TL;DR

In this post I will provide an example why Ruby on Rails is great framework that has testability in its core design.

Time is a measure in which events can be ordered from the past through the present into the future, and also the measure of durations of events and the intervals between them. Time is often referred to as the fourth dimension, along with the three spatial dimensions [source: Wikipedia].

When tester needs to test time related features, he needs to become time traveler. Ruby on Rails has very interesting time machine. It consists of Rails console and panel that helps you to set in which direction you are traveling.

Using that time machine, you can easily simulate time lapses. For example, using UI interface, you created one business object. Features says that email about this object should be sent after one week. What is easier, setting the machine system time, or simulate that time lapse in Ruby console? Here is gist:

Instead of setting system time one week in the future, we updated object time to be one week in the past. Notice plain english for setting created_at parameter! Refer to [direction you are traveling] link for more time calculation idioms.

Congratulations on your first time travel in Ruby on Rails framework!

But I am not using Ruby on Rails framework! Do not worry, by knowing Rails time machine, consult your developer does his framework has something similar.

 

 



rails console

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather