Skip to content

Commit

Permalink
He11o wor1d
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcin Mierzejewski committed Jan 7, 2015
0 parents commit 582e821
Show file tree
Hide file tree
Showing 24 changed files with 327 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
group_vars/server.yml
hosts
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Boostrapping and securing an Ubuntu server

This repository contains [Ansible](http://ansible.com) scripts for bootstrapping and securing an Ubuntu server.
Scripts have been tested on Ubuntu 14.04 hosted on [RunAbove](http://www.runabove.com) and [DigitalOcean](http://www.digitalocean.com).

The included tasks are following:

* Update and upgrade Ubuntu packages via apt-get
* Configure locale
* Install vim and mc (my personal preference)
* Install fail2ban to block ssh brute-force attempts
* Delete root password
* Lock down sudo
* Lock down ssh to prevent root and password login
* Setup the ufw firewall
* Configure unattended security upgrades
* Install collectd deamon and collect-web front-end client (optionally)
* Create users (optionally)

## Ansible

First of all, install the latest version of Ansible, in Ubuntu:

```
$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
```

## Clone scripts

Next, you have to clone this repository:

```
$ git clone https://github.com/zenzire/ansible-bootstrap-ubuntu.git
```

## Configuration files

Copy sample configuration files:

```
$ cp hosts.sample hosts
$ cp global_vars/server.yml.sample global_vars/server.yml
```

Edit configuration files (hosts and global_vars/server.yml) with your own configuration.

## Prerequisites for RunAbove hosting

We need to set password for admin user and assing him to sudoers group.

```
$ ansible-playbook user.yml
Enter username: admin
Enter password:
confirm Enter password:
Enter id_rsa.pub path [~/.ssh/id_rsa.pub]:
Add user to sudoers group (y/n) [n]: y
```

## Prerequisites for DigitalOcean hosting

We need to create admin user and assing him to sudoers group.

```
$ ansible-playbook user.yml --user root
Enter username: admin
Enter password:
confirm Enter password:
Enter id_rsa.pub path [~/.ssh/id_rsa.pub]:
Add user to sudoers group (y/n) [n]: y
```


## Script execution

Finally, execute bootstrap Ansible task for admin user:

```
ansible-playbook bootstrap.yml --ask-sudo
```

## Collectd

Also you can install [collectd](https://collectd.org/), deamon which collects system performance statistics
periodically and [collectd-web](https://github.com/httpdss/collectd-web), web-based front-end for data
collected by collectd.

```
$ ansible-playbook collectd.yml --ask-sudo
```

## Users

You can add new user or update the existing one using the following script:

```
$ ansible-playbook user.yml --ask-sudo
```


## License

Released under the MIT License, Copyright (c) 2015 - Marcin Mierzejewski

3 changes: 3 additions & 0 deletions ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[defaults]
hostfile = hosts
remote_user = admin
6 changes: 6 additions & 0 deletions bootstrap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: Bootstrap Ubuntu servers
hosts: server
sudo: yes
roles:
- bootstrap
7 changes: 7 additions & 0 deletions collectd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Bootstrap Ubuntu servers
hosts: server
sudo: yes
roles:
- nginx
- collectd
7 changes: 7 additions & 0 deletions group_vars/server.yml.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
hostname: 'mydomain.com'
collectd_server_name: 'collecd-web.mydomain.com'
locale: 'en_US.UTF-8'
language: 'en_US:en'
timezone: 'Europe/Warsaw'

2 changes: 2 additions & 0 deletions hosts.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[server]
127.0.0.1
6 changes: 6 additions & 0 deletions roles/bootstrap/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: restart ssh
action: service name=ssh state=restarted

- name: update tzdata
command: /usr/sbin/dpkg-reconfigure --frontend noninteractive tzdata
16 changes: 16 additions & 0 deletions roles/bootstrap/tasks/apt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
- name: Update APT package cache
action: apt update_cache=yes

- name: Upgrade APT to the lastest packages
action: apt upgrade=safe

- name: Install unattended-upgrades
action: apt pkg=unattended-upgrades state=present

- name: Adjust APT update intervals
template: src=apt/10periodic dest=/etc/apt/apt.conf.d/10periodic

- name: Make sure unattended-upgrades only installs from security
action: lineinfile dest=/etc/apt/apt.conf.d/50unattended-upgrades regexp="distro_codename\}\-updates" state=absent

4 changes: 4 additions & 0 deletions roles/bootstrap/tasks/hostname.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
- name: Set hostname
action: shell hostname {{ hostname }}

14 changes: 14 additions & 0 deletions roles/bootstrap/tasks/locale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
- name: Generate locale
command: /usr/sbin/locale-gen {{ locale }}

- name: Set locale
command: /usr/sbin/update-locale LANG={{ locale }} LC_ALL={{ locale }} LANGUAGE={{ language }}

- name: Set /etc/localtime
command: /bin/cp /usr/share/zoneinfo/{{ timezone }} /etc/localtime

- name: Set timezone (/etc/timezone)
template: src=timezone dest=/etc/timezone
notify: update tzdata

7 changes: 7 additions & 0 deletions roles/bootstrap/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- include: hostname.yml
- include: locale.yml
- include: apt.yml
- include: secure.yml
- include: packages.yml

7 changes: 7 additions & 0 deletions roles/bootstrap/tasks/packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Install packages
action: apt pkg={{ item }} state=installed
with_items:
- vim
- mc

29 changes: 29 additions & 0 deletions roles/bootstrap/tasks/secure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
- name: Install fail2ban
action: apt pkg=fail2ban state=installed

- name: Disallow password authentication
action: lineinfile dest=/etc/ssh/sshd_config regexp="^PasswordAuthentication" line="PasswordAuthentication no" state=present
notify: restart ssh

- name: Disallow root SSH access
action: lineinfile dest=/etc/ssh/sshd_config regexp="^PermitRootLogin" line="PermitRootLogin no" state=present
notify: restart ssh

- name: Delete /etc/sudoers.d/ files
action: shell rm -f /etc/sudoers.d/*

- name: Setup ufw 22/tcp
action: shell ufw allow 22/tcp

- name: Setup ufw 80/tcp
action: shell ufw allow 80/tcp

- name: Setup ufw 443/tcp
action: shell ufw allow 443/tcp

- name: Enable ufw
action: shell echo 'y' | ufw enable

- name: Delete root password
action: shell passwd -d root
4 changes: 4 additions & 0 deletions roles/bootstrap/templates/apt/10periodic
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
1 change: 1 addition & 0 deletions roles/bootstrap/templates/timezone
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ timezone }}
3 changes: 3 additions & 0 deletions roles/collectd/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: restart supervisor
action: service name=supervisor state=restarted
28 changes: 28 additions & 0 deletions roles/collectd/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
- name: Add collectd user
action: user name=collectd shell=/usr/sbin/nologin

- name: Install collectd and dependencies
action: apt pkg={{ item }} state=installed
with_items:
- git
- collectd
- librrds-perl
- libjson-perl
- libhtml-parser-perl

- name: Clone collectd-web
git: repo=https://github.com/httpdss/collectd-web.git dest=/home/collectd/collectd-web

- name: Copy nginx configuration
template: src=nginx.conf dest=/etc/nginx/sites-enabled/collectd.conf
notify: restart nginx

- name: Install supervisor
action: apt pkg=supervisor state=present

- name: Copy supervisor configuration
template: src=supervisor.conf dest=/etc/supervisor/conf.d/collectd.conf
notify: restart supervisor


10 changes: 10 additions & 0 deletions roles/collectd/templates/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
server {
listen 80;
server_name {{ collectd_server_name }};

location / {
proxy_pass http://127.0.0.1:8093;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
8 changes: 8 additions & 0 deletions roles/collectd/templates/supervisor.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[program:collectd]
command=/home/collectd/collectd-web/runserver.py 127.0.0.1 8093
directory=/home/collectd/collectd-web
user=collectd
numprocs=1
autostart=true
autorestart=true
startsecs=10
3 changes: 3 additions & 0 deletions roles/nginx/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: restart nginx
action: service name=nginx state=restarted
7 changes: 7 additions & 0 deletions roles/nginx/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Install nginx
action: apt pkg=nginx state=present

- name: Remove default nginx configuration
action: file path=/etc/nginx/sites-enabled/default state=absent
notify: restart nginx
16 changes: 16 additions & 0 deletions roles/user/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
- name: Add or update user and set password
action: user name={{ username }} password={{ password }}

- name: Add or udpate authorized key
action: authorized_key user={{ username }} key="{{ lookup('file', id_rsa_path) }}"
when: id_rsa_path is defined

- name: Add user to sudoers
action: lineinfile dest=/etc/sudoers regexp="{{ username }} ALL" line="{{ username }} ALL=(ALL) ALL" state=present
when: sudoers == 'y'

- name: Remove user to sudoers
action: lineinfile dest=/etc/sudoers regexp="{{ username }} ALL" line="{{ username }} ALL=(ALL) ALL" state=absent
when: sudoers == 'n'

28 changes: 28 additions & 0 deletions user.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
- name: Add or update the existing user on Ubuntu servers
hosts: server
sudo: yes
roles:
- user

vars_prompt:
- name: "username"
prompt: "Enter username"
private: no

- name: "password"
prompt: "Enter password"
encrypt: "md5_crypt"
salt_size: 7

This comment has been minimized.

Copy link
@gasi

gasi Mar 6, 2016

Pssst, md5_crypt has been deprecated due to security flaws: https://pythonhosted.org/passlib/lib/passlib.hash.md5_crypt.html

I switched one of the recommendations, i.e. sha512_crypt, and it worked well 😄

P.S. Thanks for sharing these great Ansible playbooks ❤️

confirm: yes

- name: "id_rsa_path"
prompt: "Enter id_rsa.pub path"
default: "~/.ssh/id_rsa.pub"
private: no

- name: "sudoers"
prompt: "Add user to sudoers group (y/n)"
default: 'n'
private: no

0 comments on commit 582e821

Please sign in to comment.