Skip to content

Commit 063a8d8

Browse files
committed
First import
0 parents  commit 063a8d8

33 files changed

+1023
-0
lines changed

.gitattributes

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
###############################################################################
2+
# Set default behavior to automatically normalize line endings.
3+
###############################################################################
4+
* text eol=lf
5+
6+
###############################################################################
7+
# Set default behavior for command prompt diff.
8+
#
9+
# This is need for earlier builds of msysgit that does not have it on by
10+
# default for csharp files.
11+
# Note: This is only used by command line
12+
###############################################################################
13+
#*.cs diff=csharp
14+
15+
###############################################################################
16+
# Set the merge driver for project and solution files
17+
#
18+
# Merging from the command prompt will add diff markers to the files if there
19+
# are conflicts (Merging from VS is not affected by the settings below, in VS
20+
# the diff markers are never inserted). Diff markers may cause the following
21+
# file extensions to fail to load in VS. An alternative would be to treat
22+
# these files as binary and thus will always conflict and require user
23+
# intervention with every merge. To do so, just uncomment the entries below
24+
###############################################################################
25+
#*.sln merge=binary
26+
#*.csproj merge=binary
27+
#*.vbproj merge=binary
28+
#*.vcxproj merge=binary
29+
#*.vcproj merge=binary
30+
#*.dbproj merge=binary
31+
#*.fsproj merge=binary
32+
#*.lsproj merge=binary
33+
#*.wixproj merge=binary
34+
#*.modelproj merge=binary
35+
#*.sqlproj merge=binary
36+
#*.wwaproj merge=binary
37+
38+
###############################################################################
39+
# behavior for image files
40+
#
41+
# image files are treated as binary by default.
42+
###############################################################################
43+
#*.jpg binary
44+
#*.png binary
45+
#*.gif binary
46+
47+
###############################################################################
48+
# diff behavior for common document formats
49+
#
50+
# Convert binary document formats to text before diffing them. This feature
51+
# is only available from the command line. Turn it on by uncommenting the
52+
# entries below.
53+
###############################################################################
54+
#*.doc diff=astextplain
55+
#*.DOC diff=astextplain
56+
#*.docx diff=astextplain
57+
#*.DOCX diff=astextplain
58+
#*.dot diff=astextplain
59+
#*.DOT diff=astextplain
60+
#*.pdf diff=astextplain
61+
#*.PDF diff=astextplain
62+
#*.rtf diff=astextplain
63+
#*.RTF diff=astextplain

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
hosts
2+
fetch
3+
bootstrap.retry
4+
provision-*.retry
5+
vault*decrypted.yml
6+
venv

README.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Perfect Linux machine setup with Ansible
2+
3+
In 2020, having a Linux IaaS machine configured and setup should be easy and fast: after all, it's the basic task anybody has to do in order to start working on more-meaningful and productive activities.
4+
5+
However, this is not always the case: you work in different environments (different cloud providers, on-premises environments, lab environments) where you have different base images and different tools, and creating the very same machine is still quite a daunting - or at least *time-consuming* - task.
6+
7+
This project aims to solve that, by providing a **boilerplate yet complete** and **easy-to-use** and **easy-to-customize** way to spin up your own Linux machine.
8+
9+
## Usage
10+
11+
You will need [Ansible](https://ansible.com) on your workstation in order to run this project, and you will need to first install a base Linux image on your target system. The target system can be a Debian-based system or an Ubuntu-based system, since the [apt](https://it.wikipedia.org/wiki/Advanced_Packaging_Tool) package is used.
12+
13+
You can start the fun with the [install.sh](/install.sh) script which takes in input the hostname to configure.
14+
15+
In the output, you will receive the passwords for the default user and the `root` user.
16+
The script will add your local SSH keys as trusted keys for remote login, and will harden the Linux installation quite a bit.
17+
In the end, you will also have several utilities installed and a Docker daemon.
18+
19+
The playbook also uses the [olivomarco/dotfiles](https://github.com/olivomarco/dotfiles) repo in order to setup a custom and productive shell for the users of the system.
20+
21+
## Parameters
22+
23+
Please note that some of the parameters provided by this template repo **MUST BE CHANGED** before running the script.
24+
25+
Customization starts by modifying files in [this folder](/group_vars/). In particular, consider that:
26+
27+
- in [all.yml](/group_vars/all.yml) you must modify the `default_username` variable
28+
- in [all.yml](/group_vars/all.yml) you must modify the `dot_forward_email` variable
29+
- the [vault.yml](/group_vars/vault.yml) is an [ansible-vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html) encrypted file (default password: `secretpassword`) which you must customize with your SMTP parameters
30+
31+
## Final notes
32+
33+
You can, of course, customize everything and add your own tools and configurations: **if you think you have found something useful which can be beneficial to any user using this package, please open a feature request and I will gladly evaluate it**.

ansible.cfg

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[defaults]
2+
inventory = hosts

group_vars/all.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
# general settings
3+
default_username: debian
4+
dot_forward_email: <YOUR_EMAIL_GOES_HERE>
5+
private_key: .ssh/id_rsa
6+
public_key: .ssh/id_rsa.pub
7+
ntpserver: pool.ntp.org
8+
timezone: Europe/Rome
9+
10+
# default sshd port
11+
sshd_port: 22
12+
13+
# generate random passwords for default user and root user
14+
default_password: "{{lookup('password', '/dev/null length=15 chars=ascii_letters,digits,punctuation')}}"
15+
root_password: "{{lookup('password', '/dev/null length=15 chars=ascii_letters,digits,punctuation')}}"
16+
17+
# unattended packages install configuration
18+
unattended_mail: "{{dot_forward_email}}"
19+
unattended_remove_unused_dependencies: true
20+
unattended_automatic_reboot_time: "03:00"
21+
unattended_update_days: "Sat"
22+
unattended_clean_interval: 7
23+
24+
# fail2ban
25+
fail2ban_loglevel: INFO
26+
fail2ban_services:
27+
- name: ssh
28+
port: ssh
29+
filter: sshd
30+
logpath: /var/log/auth.log

group_vars/apt.yml

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
# packages to install
3+
packages_to_install:
4+
- sudo
5+
- python-apt
6+
- git-core
7+
- ufw
8+
- dnsutils
9+
- build-essential
10+
- acl
11+
- screen
12+
- bash-completion
13+
- ntp
14+
- jq
15+
- htop
16+
- psmisc
17+
- python-pip
18+
- python3-pip
19+
- vim
20+
- netcat
21+
- net-tools
22+
- nmap
23+
- lynx
24+
- wget
25+
- curl
26+
- gzip
27+
- rsync
28+
- logrotate
29+
# - logcheck
30+
- rkhunter
31+
- cryptsetup
32+
- python-glade2
33+
- dos2unix
34+
- mlocate
35+
- rclone
36+
- bc
37+
- zsh
38+
- hddtemp
39+
- lm-sensors
40+
- qemu-guest-agent
41+
- atop
42+
- sshfs
43+
- reptyr
44+
- lvm2
45+
- parted
46+
- rename
47+
- glances
48+
- gnupg

group_vars/docker.yml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
# docker
3+
docker__channel: ["stable"]
4+
docker__version: "19.03.5"
5+
docker__state: "present"
6+
docker__compose_version: "1.25.0"
7+
docker__users: ["{{default_username}}"]
8+
docker__daemon_flags:
9+
- "-H unix://"
10+
#- "-H unix:// --iptables=false"
11+
# "a" removes unused images (useful in production).
12+
# "f" forces it to happen without prompting you to agree.
13+
docker__cron_jobs_prune_flags: "af"
14+
docker__cron_jobs:
15+
- name: "Docker disk clean up"
16+
job: "docker system prune -{{docker__cron_jobs_prune_flags}} > /dev/null 2>&1"
17+
schedule: ["0", "0", "*", "*", "0"]
18+
cron_file: "docker-disk-clean-up"
19+
user: "{{(docker__users | first) | d('root')}}"
20+
state: "present"

group_vars/monit.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
# monit
3+
config_monit: true
4+
monit_enable_email_notifications: false
5+
monit_email_to: "{{dot_forward_email}}"
6+
monit_enable_web_server: false
7+
monit_web_server_allow_list:
8+
- localhost
9+
monit_web_server_local_only: true
10+
monit_monitor_services:
11+
- name: "cron"
12+
monitored: true
13+
pidfile: "/var/run/crond.pid"
14+
start_program: "/usr/sbin/service cron start"
15+
stop_program: "/usr/sbin/service cron stop"
16+
- name: "fail2ban"
17+
monitored: true
18+
pidfile: "/var/run/fail2ban/fail2ban.pid"
19+
start_program: "/etc/init.d/fail2ban start"
20+
stop_program: "/etc/init.d/fail2ban stop"
21+
- name: "sshd"
22+
monitored: true
23+
pidfile: "/var/run/sshd.pid"
24+
start_program: "/etc/init.d/ssh start"
25+
stop_program: "/etc/init.d/ssh stop"
26+
- name: "syslogd"
27+
monitored: true
28+
pidfile: "/var/run/rsyslogd.pid"
29+
start_program: "/etc/init.d/rsyslog start"
30+
stop_program: "/etc/init.d/rsyslog stop"

group_vars/networking.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
# Local LAN IP-range addresses
3+
local_lan: "192.168.0.0/16"
4+
docker_overlay_ips: "172.0.0.0/8"
5+
6+
# ufw rules
7+
ufw_rules:
8+
- {rule: allow, port: 22, src: "{{local_lan}}", proto: tcp, direction: "in"}
9+
- {rule: allow, port: 22, src: "{{docker_overlay_ips}}", proto: tcp, direction: "in"}
10+
# - {rule: allow, port: 80, src: "0.0.0.0/0", proto: tcp, direction: "in"}
11+
# - {rule: allow, port: 443, src: "0.0.0.0/0", proto: tcp, direction: "in"}
12+
13+
# network configuration for our server
14+
interfaces_template: "interfaces-dhcp-server.j2"

group_vars/vault.yml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
$ANSIBLE_VAULT;1.1;AES256
2+
36663239336238393633346563366232393635633365343535663163336438613066633062626133
3+
3630376365643565653430363030616132383332306339370a393139616163366461376133373935
4+
35386535363862353237306264336230646334346162316666613238343863303336633533626538
5+
3364313966306362330a626634313961326664303761363635633039333138353331306132636261
6+
35623366333637353962383730613966336461623936376235313365303661663238316563613838
7+
33303032306137373863303564643236653530333366366136363837666661663864376139626634
8+
64613839333335663237333533633464393831663331356437376133396330396661366366373461
9+
33353462393063313731316364333034373066653563336533363032363038326331303433666634
10+
62376637343463386538333566303234313330663234313664616433653563353165386366653638
11+
65613736633135316463316537653638326233353134343537393239663537613734313762346434
12+
63393437356366613332623666383532363365303239666637666362626366623862666334303537
13+
35333663343137643737383533323134363937386239616136326534653261636361386463326236
14+
64306433666465343066333136346434656537626631656632393737626565396130373036333530
15+
3265646137373062393035636531376339623231366139373664

install.sh

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/bash
2+
3+
usage() {
4+
echo "USAGE: ${0} [-h] [-D] -H hostname [-p password_file]"
5+
echo ""
6+
echo "Configures the given role for the given hostname."
7+
echo ""
8+
echo "Options:"
9+
echo " -h runs help (this screen)"
10+
echo " -D debug mode on (more verbose output)"
11+
echo ""
12+
echo " -H the target hostname to configure"
13+
echo " -p password_file is an optional path to a password file for Ansible"
14+
echo ""
15+
}
16+
17+
# check invocation
18+
if (! getopts ":hDH:p:" opt); then
19+
usage
20+
exit $E_OPTERROR;
21+
fi
22+
23+
debug_mode=0
24+
25+
# parse arguments
26+
while getopts ":hDH:p:" opt; do
27+
case $opt in
28+
h)
29+
usage
30+
exit 1
31+
;;
32+
D)
33+
debug_mode=1
34+
;;
35+
H)
36+
hostname=($OPTARG)
37+
;;
38+
p)
39+
password_file=($OPTARG)
40+
;;
41+
\?)
42+
echo "Invalid option: -${OPTARG}" >&2
43+
usage
44+
exit 1
45+
;;
46+
esac
47+
done
48+
shift $((OPTIND -1))
49+
50+
virtualenv -q -p $(which python3) venv
51+
source venv/bin/activate
52+
53+
# install local requirements for ansible
54+
ansible-galaxy install -r requirements.yml
55+
# install additional pre-requirements
56+
pip install jmespath dnspython
57+
58+
# export ansible variables
59+
export ANSIBLE_LOAD_CALLBACK_PLUGINS=1
60+
if [ $debug_mode -eq 0 ] ; then
61+
export ANSIBLE_STDOUT_CALLBACK="unixy"
62+
else
63+
export ANSIBLE_STDOUT_CALLBACK="skippy"
64+
fi
65+
66+
# create hosts file
67+
echo "[prod]" > hosts
68+
echo "${hostname}" >> hosts
69+
70+
# run ansible
71+
if [ -z $password_file ] ; then
72+
ansible-playbook -i hosts provision.yml --vault-id @prompt
73+
else
74+
ansible-playbook -i hosts provision.yml --vault-password-file $password_file
75+
fi
76+
77+
deactivate

provision.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
- hosts: prod
3+
vars_files:
4+
- group_vars/all.yml
5+
- group_vars/apt.yml
6+
- group_vars/docker.yml
7+
- group_vars/monit.yml
8+
- group_vars/networking.yml
9+
- group_vars/vault.yml
10+
user: "{{default_username}}" # run whole script with default user
11+
become: yes
12+
roles: # order is not random!
13+
- role: nickjj.fail2ban
14+
tags: fail2ban
15+
- role: common
16+
tags: common
17+
- role: ufw
18+
tags: ufw
19+
- role: user
20+
tags: user
21+
- role: ssh
22+
tags: ssh
23+
- role: nickjj.docker
24+
tags: docker
25+
- role: docker
26+
tags: docker
27+
- role: jnv.debian-backports
28+
tags: common
29+
- role: ansible-monit
30+
tags: common
31+
- role: jnv.unattended-upgrades
32+
tags: common
33+
- role: networking
34+
tags: networking
35+
- role: reboot
36+
tags: reboot

requirements.yml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
- src: nickjj.fail2ban
3+
- src: nickjj.docker
4+
- src: https://github.com/mrlesmithjr/ansible-monit
5+
- src: jnv.debian-backports
6+
- src: jnv.unattended-upgrades

0 commit comments

Comments
 (0)