aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore22
-rw-r--r--playbooks/init_adze.yml46
l---------playbooks/pubkeys1
l---------playbooks/roles1
l---------playbooks/vars1
-rw-r--r--roles/common/README4
-rw-r--r--roles/common/defaults/main.yml36
-rw-r--r--roles/common/handlers/main.yml11
-rw-r--r--roles/common/tasks/extras.yml12
-rw-r--r--roles/common/tasks/main.yml90
-rw-r--r--roles/common/tasks/ntp.yml16
-rw-r--r--roles/common/tasks/security.yml26
-rw-r--r--roles/common/tasks/users.yml6
-rw-r--r--roles/common/templates/apticron.conf.j2101
-rw-r--r--roles/common/templates/etc_fail2ban_jail.local.j225
-rw-r--r--roles/common/templates/etc_ssh_ssh_config.j261
-rw-r--r--roles/common/templates/etc_ssh_sshd_config.j295
-rw-r--r--roles/common/templates/ntp.conf.j263
-rw-r--r--roles/common/templates/sudoers.j21
-rw-r--r--roles/debian_jessie/defaults/main.yml2
-rw-r--r--roles/debian_jessie/tasks/main.yml10
-rw-r--r--roles/debian_jessie/templates/etc_apt_apt_confd_20auto_upgrades.j24
-rw-r--r--roles/debian_jessie/templates/etc_apt_apt_confd_50unattended_upgrades.j294
-rw-r--r--roles/debian_jessie/templates/etc_apt_sources_list.j215
-rw-r--r--roles/nginx/files/nginx_default_404.html4
-rw-r--r--roles/nginx/files/nginx_default_50x.html4
-rw-r--r--roles/nginx/files/nginx_default_favicon.png0
-rw-r--r--roles/nginx/files/nginx_default_index.html4
-rw-r--r--roles/nginx/files/nginx_default_robots.txt3
-rw-r--r--roles/nginx/handlers/main.yml7
-rw-r--r--roles/nginx/tasks/main.yml24
-rw-r--r--roles/nullmailer/defaults/main.yml5
-rw-r--r--roles/nullmailer/handlers/main.yml5
-rw-r--r--roles/nullmailer/tasks/main.yml33
-rw-r--r--roles/nullmailer/templates/etc_nullmailer_adminaddr.j21
-rw-r--r--roles/nullmailer/templates/etc_nullmailer_defaultdomain.j21
-rw-r--r--roles/nullmailer/templates/etc_nullmailer_remotes.j22
-rw-r--r--roles/nullmailer/templates/mailname.j21
-rw-r--r--vars/default.yml13
39 files changed, 850 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1b86e0e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+*vault_pass.txt
+
+*.o
+*.a
+*.pyc
+*~
+*.swp
+.*
+*.tmp
+*.old
+*.profile
+*.bkp
+*.bak
+[Tt]humbs.db
+*.DS_Store
+build/
+_build/
+src/build/
+*.log
+
+# Don't ignore this file itself
+!.gitignore
diff --git a/playbooks/init_adze.yml b/playbooks/init_adze.yml
new file mode 100644
index 0000000..e2c1f79
--- /dev/null
+++ b/playbooks/init_adze.yml
@@ -0,0 +1,46 @@
+---
+- name: Initializing adze.robocracy.org
+ hosts: adze.robocracy.org
+ remote_user: root
+ gather_facts: True
+ vars_files:
+ - vars/vault.yml
+ - vars/default.yml
+
+ vars:
+ admin_email: "root@robocracy.org"
+ main_user_name: bnewbold
+
+ roles:
+ - debian_jessie
+ - common
+ - nullmailer
+ # TODO: nginx
+
+ tasks:
+ - name: Create main user account
+ user: name={{main_user_name}} state=present groups=sudo append=yes shell=/bin/bash
+ - name: Give main user account sudo power
+ template: src=roles/common/templates/sudoers.j2 dest=/etc/sudoers.d/sudoers owner=root group=root mode=0440 validate='visudo -cf %s'
+ - name: Install main user authorized SSH keys
+ authorized_key: user="{{ main_user_name}}" key="{{ item }}"
+ with_file:
+ - pubkeys/bnewbold.pub
+ - name: Install root user authorized SSH keys
+ authorized_key: user=root key="{{ item }}"
+ with_file:
+ - pubkeys/bnewbold.pub
+ - name: Extra packages for this host
+ apt: name={{item}} state=installed
+ with_items:
+ - socat
+ - rsyslog
+
+ post_tasks:
+ - name: Sanity check that we have IPv4 connectivity
+ command: /bin/ping -c 2 mit.edu
+ - name: Sanity check that we have IPv6 connectivity
+ command: /bin/ping6 -c 2 mit.edu
+ - name: Done
+ shell: echo 'Done!'
+
diff --git a/playbooks/pubkeys b/playbooks/pubkeys
new file mode 120000
index 0000000..60652d3
--- /dev/null
+++ b/playbooks/pubkeys
@@ -0,0 +1 @@
+../pubkeys/ \ No newline at end of file
diff --git a/playbooks/roles b/playbooks/roles
new file mode 120000
index 0000000..7b9ade8
--- /dev/null
+++ b/playbooks/roles
@@ -0,0 +1 @@
+../roles/ \ No newline at end of file
diff --git a/playbooks/vars b/playbooks/vars
new file mode 120000
index 0000000..b11f011
--- /dev/null
+++ b/playbooks/vars
@@ -0,0 +1 @@
+../vars/ \ No newline at end of file
diff --git a/roles/common/README b/roles/common/README
new file mode 100644
index 0000000..b43cb11
--- /dev/null
+++ b/roles/common/README
@@ -0,0 +1,4 @@
+Many of the files in here originally came from the 'jessie' branch of
+sovereign:
+
+ https://github.com/sovereign/sovereign
diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml
new file mode 100644
index 0000000..22287b0
--- /dev/null
+++ b/roles/common/defaults/main.yml
@@ -0,0 +1,36 @@
+---
+###############################################################################
+# DO NOT EDIT. Set your variables in `vars/*.yml` instead.
+# This is a reference of all the variables.
+###############################################################################
+
+common_timezone: 'Etc/UTC'
+# domain: (required)
+# main_user_name: (required)
+# admin_email: (required)
+main_user_shell: "/bin/bash"
+friendly_networks:
+ - ""
+
+# ssh
+ssh_kex_algorithms: "diffie-hellman-group-exchange-sha256"
+ssh_ciphers: "aes256-ctr,aes192-ctr,aes128-ctr"
+ssh_macs: "hmac-sha2-512,hmac-sha2-256,hmac-ripemd160"
+sshd_allow_passwd: "no"
+sshd_print_motd: "yes"
+sshd_allow_root: "without-password"
+sshd_forward_x11: "yes"
+
+# ntp
+ntp_servers:
+ # use nearby ntp servers by default
+ - 0.pool.ntp.org
+ - 1.pool.ntp.org
+ - 2.pool.ntp.org
+ - 3.pool.ntp.org
+ # use servers tailored to the server location
+ # See http://www.pool.ntp.org/en/use.html
+ # - 0.north-america.pool.ntp.org
+ # - 1.north-america.pool.ntp.org
+ # - 2.north-america.pool.ntp.org
+ # - 3.north-america.pool.ntp.org
diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml
new file mode 100644
index 0000000..3ca3bcf
--- /dev/null
+++ b/roles/common/handlers/main.yml
@@ -0,0 +1,11 @@
+---
+# Defines handlers applicable across all machines in the infrastructure.
+
+- name: restart ntp
+ service: name=ntp state=restarted
+
+- name: restart fail2ban
+ service: name=fail2ban state=restarted
+
+- name: restart ssh
+ service: name=ssh state=restarted
diff --git a/roles/common/tasks/extras.yml b/roles/common/tasks/extras.yml
new file mode 100644
index 0000000..9a4bd2f
--- /dev/null
+++ b/roles/common/tasks/extras.yml
@@ -0,0 +1,12 @@
+---
+- name: Install extras that Everybody wants
+ apt: pkg={{ item }} state=installed
+ with_items:
+ - build-essential
+ - cowsay
+ - figlet
+ - ipython
+ - ipython3
+ tags:
+ - dependencies
+
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
new file mode 100644
index 0000000..d4c2347
--- /dev/null
+++ b/roles/common/tasks/main.yml
@@ -0,0 +1,90 @@
+---
+
+- name: Update apt cache
+ apt: update_cache=yes cache_valid_time=3600
+ tags:
+ - dependencies
+
+- name: Upgrade all safe packages
+ apt: upgrade=safe
+ tags:
+ - dependencies
+
+- name: Install necessities and nice-to-haves
+ apt: pkg={{ item }} state=installed
+ with_items:
+ - apt-transport-https
+ - apticron
+ - aptitude
+ - bzip2
+ - ca-certificates
+ - curl
+ - debian-goodies
+ - dialog
+ - dnsutils
+ - etckeeper
+ # fail2ban in security
+ - file
+ - git
+ - htop
+ - iftop
+ - ifupdown
+ - iotop
+ - iproute
+ - iputils-ping
+ - isc-dhcp-client
+ - less
+ - libui-dialog-perl
+ - locales
+ - locales-all
+ - lsof
+ - lvm2
+ - man-db
+ - manpages-dev
+ - molly-guard
+ - mosh
+ - mtr-tiny
+ - netbase
+ - netcat
+ - net-tools
+ - ngrep
+ - openssh-server
+ - openssl
+ - pv
+ - python
+ - python-software-properties
+ # rkhunter in security
+ - screen
+ - sudo
+ - tcpdump
+ - unzip
+ - unattended-upgrades
+ - vim-nox
+ - wget
+ tags:
+ - dependencies
+
+- name: timezone - configure /etc/timezone
+ copy:
+ content: "{{ common_timezone | regex_replace('$', '\n') }}"
+ dest: /etc/timezone
+ owner: root
+ group: root
+ mode: 0644
+ register: common_timezone_config
+
+- name: timezone - Set localtime to UTC
+ file: src=/usr/share/zoneinfo/Etc/UTC dest=/etc/localtime
+ when: common_timezone_config.changed
+
+- name: timezone - reconfigure tzdata
+ command: dpkg-reconfigure --frontend noninteractive tzdata
+ when: common_timezone_config.changed
+
+- name: Apticron email configuration
+ template: src=apticron.conf.j2 dest=/etc/apticron/apticron.conf
+
+#- include: users.yml tags=users
+- include: security.yml tags=security
+- include: ntp.yml tags=ntp
+- include: extras.yml tags=extras
diff --git a/roles/common/tasks/ntp.yml b/roles/common/tasks/ntp.yml
new file mode 100644
index 0000000..c1489fd
--- /dev/null
+++ b/roles/common/tasks/ntp.yml
@@ -0,0 +1,16 @@
+---
+# Defines tasks applicable for NTP (Network Time Protocol)
+
+- name: Install ntp
+ apt: pkg=ntp state=installed
+ tags:
+ - dependencies
+
+- name: Configure ntp
+ template: src=ntp.conf.j2 dest=/etc/ntp.conf
+ notify:
+ - restart ntp
+
+- name: Ensure ntpd is running and enabled
+ service: name=ntp state=started enabled=yes
+
diff --git a/roles/common/tasks/security.yml b/roles/common/tasks/security.yml
new file mode 100644
index 0000000..c00b941
--- /dev/null
+++ b/roles/common/tasks/security.yml
@@ -0,0 +1,26 @@
+---
+- name: Install security-related packages
+ apt: pkg={{ item }} state=installed
+ with_items:
+ - fail2ban
+ - whois
+ - lynis
+ - rkhunter
+ - debsums
+ tags:
+ - dependencies
+
+- name: Copy fail2ban configuration into place
+ template: src=etc_fail2ban_jail.local.j2 dest=/etc/fail2ban/jail.local
+ notify: restart fail2ban
+
+- name: Ensure fail2ban is started
+ service: name=fail2ban state=started enabled=yes
+
+- name: Update sshd (server) config for PFS and more secure defaults
+ template: src=etc_ssh_sshd_config.j2 dest=/etc/ssh/sshd_config
+ notify: restart ssh
+
+- name: Update ssh (client) config for more secure defaults
+ template: src=etc_ssh_ssh_config.j2 dest=/etc/ssh/ssh_config
+
diff --git a/roles/common/tasks/users.yml b/roles/common/tasks/users.yml
new file mode 100644
index 0000000..8171bd6
--- /dev/null
+++ b/roles/common/tasks/users.yml
@@ -0,0 +1,6 @@
+---
+- name: Create main user account
+ user: name={{ main_user_name }} state=present shell={{ main_user_shell }} groups=sudo
+
+- name: Give main user account sudo power
+ template: src=roles/common/templates/sudoers.j2 dest=/etc/sudoers.d/sudoers owner=root group=root mode=0440 validate='visudo -cf %s'
diff --git a/roles/common/templates/apticron.conf.j2 b/roles/common/templates/apticron.conf.j2
new file mode 100644
index 0000000..512a682
--- /dev/null
+++ b/roles/common/templates/apticron.conf.j2
@@ -0,0 +1,101 @@
+# apticron.conf
+# {{ ansible_managed }}
+#
+# set EMAIL to a space separated list of addresses which will be notified of
+# impending updates
+#
+EMAIL="{{ admin_email }}"
+
+#
+# Set DIFF_ONLY to "1" to only output the difference of the current run
+# compared to the last run (ie. only new upgrades since the last run). If there
+# are no differences, no output/email will be generated. By default, apticron
+# will output everything that needs to be upgraded.
+#
+# DIFF_ONLY="1"
+
+#
+# Set LISTCHANGES_PROFILE if you would like apticron to invoke apt-listchanges
+# with the --profile option. You should add a corresponding profile to
+# /etc/apt/listchanges.conf
+#
+# LISTCHANGES_PROFILE="apticron"
+
+#
+# From hostname manpage: "Displays all FQDNs of the machine. This option
+# enumerates all configured network addresses on all configured network inter‐
+# faces, and translates them to DNS domain names. Addresses that cannot be
+# translated (i.e. because they do not have an appro‐ priate reverse DNS
+# entry) are skipped. Note that different addresses may resolve to the same
+# name, therefore the output may contain duplicate entries. Do not make any
+# assumptions about the order of the output."
+#
+# ALL_FQDNS="1"
+
+#
+# Set SYSTEM if you would like apticron to use something other than the output
+# of "hostname -f" for the system name in the mails it generates. This option
+# overrides the ALL_FQDNS above.
+#
+# SYSTEM="foobar.example.com"
+
+#
+# Set IPADDRESSNUM if you would like to configure the maximal number of IP
+# addresses apticron displays. The default is to display 1 address of each
+# family type (inet, inet6), if available.
+#
+# IPADDRESSNUM="1"
+
+#
+# Set IPADDRESSES to a whitespace separated list of reachable addresses for
+# this system. By default, apticron will try to work these out using the
+# "ip" command
+#
+# IPADDRESSES="192.0.2.1 2001:db8:1:2:3::1"
+
+#
+# Set NOTIFY_HOLDS="0" if you don't want to be notified about new versions of
+# packages on hold in your system. The default behavior is downloading and
+# listing them as any other package.
+#
+# NOTIFY_HOLDS="0"
+
+#
+# Set NOTIFY_NEW="0" if you don't want to be notified about packages which
+# are not installed in your system. Yes, it's possible! There are some issues
+# related to systems which have mixed stable/unstable sources. In these cases
+# apt-get will consider for example that packages with "Priority:
+# required"/"Essential: yes" in unstable but not in stable should be installed,
+# so they will be listed in dist-upgrade output. Please take a look at
+# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=531002#44
+#
+NOTIFY_NEW="0"
+
+#
+# Set NOTIFY_NO_UPDATES="0" if you don't want to be notified when there is no
+# new versions. Set to 1 could assure you that apticron works well.
+#
+NOTIFY_NO_UPDATE="0"
+
+#
+# Set CUSTOM_SUBJECT if you want to replace the default subject used in
+# the notification e-mails. This may help filtering/sorting client-side e-mail.
+# If you want to use internal vars please use single quotes here. Ex:
+# $CUSTOM_SUBJECT='[apticron] $SYSTEM: $NUM_PACKAGES package update(s)'
+#
+# CUSTOM_SUBJECT=""
+
+# Set CUSTOM_NO_UPDATES_SUBJECT if you want to replace the default subject used
+# in the no update notification e-mails. This may help filtering/sorting
+# client-side e-mail.
+# If you want to use internal vars please use single quotes here. Ex:
+# $CUSTOM_NO_UPDATES_SUBJECT='[apticron] $SYSTEM: no updates'
+#
+# CUSTOM_NO_UPDATES_SUBJECT=""
+
+#
+# Set CUSTOM_FROM if you want to replace the default sender by changing the
+# 'From:' field used in the notification e-mails. Your default sender will
+# be something like root@eschaton.
+#
+# CUSTOM_FROM=""
diff --git a/roles/common/templates/etc_fail2ban_jail.local.j2 b/roles/common/templates/etc_fail2ban_jail.local.j2
new file mode 100644
index 0000000..35c161c
--- /dev/null
+++ b/roles/common/templates/etc_fail2ban_jail.local.j2
@@ -0,0 +1,25 @@
+# {{ ansible_managed }}
+
+[DEFAULT]
+ignoreip = 127.0.0.1 {{ ansible_default_ipv4.address }} {{ ' '.join(friendly_networks) }}
+bantime = 10800
+destemail = {{ admin_email }}
+banaction = iptables-multiport
+action = %(action_)s
+
+# JAILS
+[ssh]
+enabled = true
+maxretry = 8
+
+[pam-generic]
+enabled = true
+banaction = iptables-allports
+
+[ssh-ddos]
+enabled = true
+
+[postfix]
+enabled = true
+maxretry = 3
+
diff --git a/roles/common/templates/etc_ssh_ssh_config.j2 b/roles/common/templates/etc_ssh_ssh_config.j2
new file mode 100644
index 0000000..db15675
--- /dev/null
+++ b/roles/common/templates/etc_ssh_ssh_config.j2
@@ -0,0 +1,61 @@
+# {{ ansible_managed }}
+
+# This is the ssh client system-wide configuration file. See
+# ssh_config(5) for more information. This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+# 1. command line options
+# 2. user-specific file
+# 3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options. For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+Host *
+# ForwardAgent no
+# ForwardX11 no
+# ForwardX11Trusted yes
+# RhostsRSAAuthentication no
+# RSAAuthentication yes
+# PasswordAuthentication yes
+# HostbasedAuthentication no
+# GSSAPIAuthentication no
+# GSSAPIDelegateCredentials no
+# GSSAPIKeyExchange no
+# GSSAPITrustDNS no
+# BatchMode no
+# CheckHostIP yes
+# AddressFamily any
+# ConnectTimeout 0
+# StrictHostKeyChecking ask
+# IdentityFile ~/.ssh/identity
+# IdentityFile ~/.ssh/id_rsa
+# IdentityFile ~/.ssh/id_dsa
+# Port 22
+# Protocol 2,1
+# Cipher 3des
+# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
+# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
+# EscapeChar ~
+# Tunnel no
+# TunnelDevice any:any
+# PermitLocalCommand no
+# VisualHostKey no
+# ProxyCommand ssh -q -W %h:%p gateway.example.com
+# RekeyLimit 1G 1h
+ SendEnv LANG LC_*
+ HashKnownHosts yes
+ GSSAPIAuthentication yes
+ GSSAPIDelegateCredentials no
+
+ Ciphers {{ ssh_ciphers }}
+ KexAlgorithms {{ ssh_kex_algorithms }}
+ MACs {{ ssh_macs }}
+ #PasswordAuthentication no
+ UseRoaming no
diff --git a/roles/common/templates/etc_ssh_sshd_config.j2 b/roles/common/templates/etc_ssh_sshd_config.j2
new file mode 100644
index 0000000..d9978e0
--- /dev/null
+++ b/roles/common/templates/etc_ssh_sshd_config.j2
@@ -0,0 +1,95 @@
+# {{ ansible_managed }}
+# See the sshd_config(5) manpage for details
+
+# What ports, IPs and protocols we listen for
+Port 22
+# Use these options to restrict which interfaces/protocols sshd will bind to
+#ListenAddress ::
+#ListenAddress 0.0.0.0
+Protocol 2
+# HostKeys for protocol version 2
+HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+#HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+#Privilege Separation is turned on for security
+UsePrivilegeSeparation yes
+
+KexAlgorithms {{ ssh_kex_algorithms }}
+Ciphers {{ ssh_ciphers }}
+MACs {{ ssh_macs }}
+
+# Lifetime and size of ephemeral version 1 server key
+KeyRegenerationInterval 3600
+#ServerKeyBits 768
+ServerKeyBits 1024
+
+# Logging
+SyslogFacility AUTH
+LogLevel INFO
+
+# Authentication:
+LoginGraceTime 120
+PermitRootLogin {{ sshd_allow_root }}
+StrictModes yes
+
+RSAAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile %h/.ssh/authorized_keys
+
+# Don't read the user's ~/.rhosts and ~/.shosts files
+IgnoreRhosts yes
+# For this to work you will also need host keys in /etc/ssh_known_hosts
+RhostsRSAAuthentication no
+# similar for protocol version 2
+HostbasedAuthentication no
+# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
+#IgnoreUserKnownHosts yes
+
+# To enable empty passwords, change to yes (NOT RECOMMENDED)
+PermitEmptyPasswords no
+
+# Change to yes to enable challenge-response passwords (beware issues with
+# some PAM modules and threads)
+# ChallengeResponseAuthentication no
+ChallengeResponseAuthentication yes
+
+# Change to no to disable tunnelled clear text passwords
+PasswordAuthentication {{ sshd_allow_passwd }}
+
+# Kerberos options
+#KerberosAuthentication no
+#KerberosGetAFSToken no
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+
+# GSSAPI options
+#GSSAPIAuthentication no
+#GSSAPICleanupCredentials yes
+
+X11Forwarding {{ sshd_forward_x11 }}
+X11DisplayOffset 10
+PrintMotd {{ sshd_print_motd }}
+PrintLastLog yes
+TCPKeepAlive yes
+#UseLogin no
+
+#MaxStartups 10:30:60
+#Banner /etc/issue.net
+
+# Allow client to pass locale environment variables
+AcceptEnv LANG LC_*
+
+Subsystem sftp /usr/lib/openssh/sftp-server
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication and
+# PasswordAuthentication. Depending on your PAM configuration,
+# PAM authentication via ChallengeResponseAuthentication may bypass
+# the setting of "PermitRootLogin without-password".
+# If you just want the PAM account and session checks to run without
+# PAM authentication, then enable this but set PasswordAuthentication
+# and ChallengeResponseAuthentication to 'no'.
+UsePAM yes
+
diff --git a/roles/common/templates/ntp.conf.j2 b/roles/common/templates/ntp.conf.j2
new file mode 100644
index 0000000..903f08a
--- /dev/null
+++ b/roles/common/templates/ntp.conf.j2
@@ -0,0 +1,63 @@
+# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
+# {{ ansible_managed }}
+
+driftfile /var/lib/ntp/ntp.drift
+
+
+# Enable this if you want statistics to be logged.
+#statsdir /var/log/ntpstats/
+
+statistics loopstats peerstats clockstats
+filegen loopstats file loopstats type day enable
+filegen peerstats file peerstats type day enable
+filegen clockstats file clockstats type day enable
+
+
+# You do need to talk to an NTP server or two (or three).
+#server ntp.your-provider.example
+
+# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
+# pick a different set every time it starts up. Please consider joining the
+# pool: <http://www.pool.ntp.org/join.html>
+#server 0.debian.pool.ntp.org iburst
+#server 1.debian.pool.ntp.org iburst
+#server 2.debian.pool.ntp.org iburst
+#server 3.debian.pool.ntp.org iburst
+
+# Use servers configured via Ansible
+{% for server in ntp_servers %}
+server {{ server }} iburst
+{% endfor %}
+
+# fallback
+server tick.usno.navy.mil
+
+# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
+# details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
+# might also be helpful.
+#
+# Note that "restrict" applies to both servers and clients, so a configuration
+# that might be intended to block requests from certain clients could also end
+# up blocking replies from your own upstream servers.
+
+# By default, exchange time with everybody, but don't allow configuration.
+restrict -4 default kod notrap nomodify nopeer noquery
+restrict -6 default kod notrap nomodify nopeer noquery
+
+# Local users may interrogate the ntp server more closely.
+restrict 127.0.0.1
+restrict ::1
+
+# Clients from this (example!) subnet have unlimited access, but only if
+# cryptographically authenticated.
+#restrict 192.168.123.0 mask 255.255.255.0 notrust
+
+
+# If you want to provide time to your local subnet, change the next line.
+# (Again, the address is an example only.)
+#broadcast 192.168.123.255
+
+# If you want to listen to time broadcasts on your local subnet, de-comment the
+# next lines. Please do this only if you trust everybody on the network!
+#disable auth
+#broadcastclient
diff --git a/roles/common/templates/sudoers.j2 b/roles/common/templates/sudoers.j2
new file mode 100644
index 0000000..18172d8
--- /dev/null
+++ b/roles/common/templates/sudoers.j2
@@ -0,0 +1 @@
+{{ main_user_name }} ALL=(ALL) NOPASSWD: ALL
diff --git a/roles/debian_jessie/defaults/main.yml b/roles/debian_jessie/defaults/main.yml
new file mode 100644
index 0000000..3703452
--- /dev/null
+++ b/roles/debian_jessie/defaults/main.yml
@@ -0,0 +1,2 @@
+
+admin_email: "root"
diff --git a/roles/debian_jessie/tasks/main.yml b/roles/debian_jessie/tasks/main.yml
new file mode 100644
index 0000000..145b58d
--- /dev/null
+++ b/roles/debian_jessie/tasks/main.yml
@@ -0,0 +1,10 @@
+
+- name: Configure sources.list for jessie
+ template: src=etc_apt_sources_list.j2 dest=/etc/apt/sources.list
+
+- name: Enable automatic upgrades
+ template: src=etc_apt_apt_confd_20auto_upgrades.j2 dest=/etc/apt/apt.conf.d/20auto-upgrades
+
+- name: Configure unattended upgrades for jessie
+ template: src=etc_apt_apt_confd_50unattended_upgrades.j2 dest=/etc/apt/apt.conf.d/50unattended-upgrades
+
diff --git a/roles/debian_jessie/templates/etc_apt_apt_confd_20auto_upgrades.j2 b/roles/debian_jessie/templates/etc_apt_apt_confd_20auto_upgrades.j2
new file mode 100644
index 0000000..c75a5d7
--- /dev/null
+++ b/roles/debian_jessie/templates/etc_apt_apt_confd_20auto_upgrades.j2
@@ -0,0 +1,4 @@
+# {{ ansible_managed }}
+
+APT::Periodic::Update-Package-Lists "1";
+APT::Periodic::Unattended-Upgrade "1";
diff --git a/roles/debian_jessie/templates/etc_apt_apt_confd_50unattended_upgrades.j2 b/roles/debian_jessie/templates/etc_apt_apt_confd_50unattended_upgrades.j2
new file mode 100644
index 0000000..8567429
--- /dev/null
+++ b/roles/debian_jessie/templates/etc_apt_apt_confd_50unattended_upgrades.j2
@@ -0,0 +1,94 @@
+// Unattended-Upgrade::Origins-Pattern controls which packages are
+// upgraded.
+//
+// {{ ansible_managed }}
+//
+// Lines below have the format format is "keyword=value,...". A
+// package will be upgraded only if the values in its metadata match
+// all the supplied keywords in a line. (In other words, omitted
+// keywords are wild cards.) The keywords originate from the Release
+// file, but several aliases are accepted. The accepted keywords are:
+// a,archive,suite (eg, "stable")
+// c,component (eg, "main", "crontrib", "non-free")
+// l,label (eg, "Debian", "Debian-Security")
+// o,origin (eg, "Debian", "Unofficial Multimedia Packages")
+// n,codename (eg, "jessie", "jessie-updates")
+// site (eg, "http.debian.net")
+// The available values on the system are printed by the command
+// "apt-cache policy", and can be debugged by running
+// "unattended-upgrades -d" and looking at the log file.
+//
+// Within lines unattended-upgrades allows 2 macros whose values are
+// derived from /etc/debian_version:
+// ${distro_id} Installed origin.
+// ${distro_codename} Installed codename (eg, "jessie")
+Unattended-Upgrade::Origins-Pattern {
+ // Codename based matching:
+ // This will follow the migration of a release through different
+ // archives (e.g. from testing to stable and later oldstable).
+ "o=Debian,n=jessie";
+ "o=Debian,n=jessie-updates";
+// "o=Debian,n=jessie-proposed-updates";
+ "o=Debian,n=jessie,l=Debian-Security";
+
+ // Archive or Suite based matching:
+ // Note that this will silently match a different release after
+ // migration to the specified archive (e.g. testing becomes the
+ // new stable).
+// "o=Debian,a=stable";
+// "o=Debian,a=stable-updates";
+// "o=Debian,a=proposed-updates";
+ "origin=Debian,codename=${distro_codename},label=Debian-Security";
+};
+
+// List of packages to not update (regexp are supported)
+Unattended-Upgrade::Package-Blacklist {
+ "vim";
+ "libc6";
+ "libc6-dev";
+ "libc6-i686";
+};
+
+// This option allows you to control if on a unclean dpkg exit
+// unattended-upgrades will automatically run
+// dpkg --force-confold --configure -a
+// The default is true, to ensure updates keep getting installed
+//Unattended-Upgrade::AutoFixInterruptedDpkg "false";
+
+// Split the upgrade into the smallest possible chunks so that
+// they can be interrupted with SIGUSR1. This makes the upgrade
+// a bit slower but it has the benefit that shutdown while a upgrade
+// is running is possible (with a small delay)
+Unattended-Upgrade::MinimalSteps "true";
+
+// Install all unattended-upgrades when the machine is shuting down
+// instead of doing it in the background while the machine is running
+// This will (obviously) make shutdown slower
+//Unattended-Upgrade::InstallOnShutdown "true";
+
+// Send email to this address for problems or packages upgrades
+// If empty or unset then no email is sent, make sure that you
+// have a working mail setup on your system. A package that provides
+// 'mailx' must be installed. E.g. "user@example.com"
+Unattended-Upgrade::Mail "{{ admin_email }}";
+
+// Set this value to "true" to get emails only on errors. Default
+// is to always send a mail if Unattended-Upgrade::Mail is set
+Unattended-Upgrade::MailOnlyOnError "true";
+
+// Do automatic removal of new unused dependencies after the upgrade
+// (equivalent to apt-get autoremove)
+//Unattended-Upgrade::Remove-Unused-Dependencies "false";
+
+// Automatically reboot *WITHOUT CONFIRMATION* if
+// the file /var/run/reboot-required is found after the upgrade
+Unattended-Upgrade::Automatic-Reboot "false";
+
+// If automatic reboot is enabled and needed, reboot at the specific
+// time instead of immediately
+// Default: "now"
+//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
+
+// Use apt bandwidth limit feature, this example limits the download
+// speed to 70kb/sec
+//Acquire::http::Dl-Limit "70";
diff --git a/roles/debian_jessie/templates/etc_apt_sources_list.j2 b/roles/debian_jessie/templates/etc_apt_sources_list.j2
new file mode 100644
index 0000000..b45f1b7
--- /dev/null
+++ b/roles/debian_jessie/templates/etc_apt_sources_list.j2
@@ -0,0 +1,15 @@
+# {{ ansible_managed }}
+
+deb http://http.debian.net/debian/ jessie main
+deb-src http://http.debian.net/debian/ jessie main
+
+deb http://security.debian.org/ jessie/updates main
+deb-src http://security.debian.org/ jessie/updates main
+
+# jessie-updates, previously known as 'volatile'
+deb http://http.debian.net/debian/ jessie-updates main
+deb-src http://http.debian.net/debian/ jessie-updates main
+
+# jessie-backports, previously on backports.debian.org
+deb http://http.debian.net/debian/ jessie-backports main
+deb-src http://http.debian.net/debian/ jessie-backports main
diff --git a/roles/nginx/files/nginx_default_404.html b/roles/nginx/files/nginx_default_404.html
new file mode 100644
index 0000000..5c918f2
--- /dev/null
+++ b/roles/nginx/files/nginx_default_404.html
@@ -0,0 +1,4 @@
+<html>
+<head><title>404: Not Found</title></head>
+<body>404: Not Found</body>
+</html>
diff --git a/roles/nginx/files/nginx_default_50x.html b/roles/nginx/files/nginx_default_50x.html
new file mode 100644
index 0000000..9af1842
--- /dev/null
+++ b/roles/nginx/files/nginx_default_50x.html
@@ -0,0 +1,4 @@
+<html>
+<head><title>50x: Server Error</title></head>
+<body>50x: Server Error</body>
+</html>
diff --git a/roles/nginx/files/nginx_default_favicon.png b/roles/nginx/files/nginx_default_favicon.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/roles/nginx/files/nginx_default_favicon.png
diff --git a/roles/nginx/files/nginx_default_index.html b/roles/nginx/files/nginx_default_index.html
new file mode 100644
index 0000000..6d805dc
--- /dev/null
+++ b/roles/nginx/files/nginx_default_index.html
@@ -0,0 +1,4 @@
+<html>
+<head><title>Index</title></head>
+<body>You probably shouldn't be seeing this, but hello anyways!</body>
+</html>
diff --git a/roles/nginx/files/nginx_default_robots.txt b/roles/nginx/files/nginx_default_robots.txt
new file mode 100644
index 0000000..e8d19f5
--- /dev/null
+++ b/roles/nginx/files/nginx_default_robots.txt
@@ -0,0 +1,3 @@
+# Disallow all bots for this server
+User-agent: *
+Disallow: /
diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml
new file mode 100644
index 0000000..c63e4a3
--- /dev/null
+++ b/roles/nginx/handlers/main.yml
@@ -0,0 +1,7 @@
+---
+- name: test nginx
+ command: nginx -t
+ notify: reload nginx
+
+- name: restart nginx
+ service: name=nginx state=restarted enabled=yes
diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml
new file mode 100644
index 0000000..8b32f07
--- /dev/null
+++ b/roles/nginx/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+- name: Install nginx
+ apt: name=nginx state=present
+
+- name: Copy nginx configuration for wordpress
+ template: src=default.conf dest=/etc/nginx/conf.d/default.conf
+ notify: restart nginx
+
+mkdir -p /srv/http/default
+
+- name: Setup default nginx pages
+ copy:
+ src: "{{item.src}}"
+ dest: "/srv/http/default/www/{{item.dest}}"
+ owner: www-data
+ group: www-data
+ force: no
+ tags:
+ - nginx
+ with_items:
+ - {src: "static_files/nginx_default_404.html", dest: "404.html"}
+ - {src: "static_files/nginx_default_50x.html", dest: "50x.html"}
+ - {src: "static_files/nginx_default_favicon.png", dest: "favicon.png"}
+ - {src: "static_files/nginx_default_index.html", dest: "index.html"}
diff --git a/roles/nullmailer/defaults/main.yml b/roles/nullmailer/defaults/main.yml
new file mode 100644
index 0000000..8ce958d
--- /dev/null
+++ b/roles/nullmailer/defaults/main.yml
@@ -0,0 +1,5 @@
+
+# REQUIRED nullmailer_smtp_host
+# REQUIRED nullmailer_smtp_user
+# REQUIRED nullmailer_smtp_pass
+email_domain: "{{ ansible_domain }}"
diff --git a/roles/nullmailer/handlers/main.yml b/roles/nullmailer/handlers/main.yml
new file mode 100644
index 0000000..d25367d
--- /dev/null
+++ b/roles/nullmailer/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: reload nullmailer
+ service:
+ name: nullmailer
+ state: reloaded \ No newline at end of file
diff --git a/roles/nullmailer/tasks/main.yml b/roles/nullmailer/tasks/main.yml
new file mode 100644
index 0000000..d694173
--- /dev/null
+++ b/roles/nullmailer/tasks/main.yml
@@ -0,0 +1,33 @@
+---
+- name: Install nullmailer and mailx
+ apt: name={{ item }} state=installed
+ with_items:
+ - nullmailer
+ - heirloom-mailx
+ tags:
+ - dependencies
+
+- name: Enable and run nullmailer service
+ service:
+ name: nullmailer
+ enabled: yes
+ state: restarted
+
+- name: Configure nullmailer - adminaddr
+ template: src=etc_nullmailer_adminaddr.j2 dest=/etc/nullmailer/adminaddr
+ when: admin_email is defined
+
+- name: Configure nullmailer - defaultdomain
+ template: src=etc_nullmailer_defaultdomain.j2 dest=/etc/nullmailer/defaultdomain
+ when: email_domain is defined
+
+- name: Configure nullmailer - remotes
+ template: src=etc_nullmailer_remotes.j2 dest=/etc/nullmailer/remotes
+ when: nullmailer_smtp_pass is defined
+ notify: reload nullmailer
+
+- name: Create mailname
+ template: src=mailname.j2 dest=/etc/mailname mode=0644
+ when: email_domain is defined
+ notify: reload nullmailer
+
diff --git a/roles/nullmailer/templates/etc_nullmailer_adminaddr.j2 b/roles/nullmailer/templates/etc_nullmailer_adminaddr.j2
new file mode 100644
index 0000000..aac956b
--- /dev/null
+++ b/roles/nullmailer/templates/etc_nullmailer_adminaddr.j2
@@ -0,0 +1 @@
+{{ admin_email }}
diff --git a/roles/nullmailer/templates/etc_nullmailer_defaultdomain.j2 b/roles/nullmailer/templates/etc_nullmailer_defaultdomain.j2
new file mode 100644
index 0000000..f1e1018
--- /dev/null
+++ b/roles/nullmailer/templates/etc_nullmailer_defaultdomain.j2
@@ -0,0 +1 @@
+{{ email_domain }}
diff --git a/roles/nullmailer/templates/etc_nullmailer_remotes.j2 b/roles/nullmailer/templates/etc_nullmailer_remotes.j2
new file mode 100644
index 0000000..0e4f1ae
--- /dev/null
+++ b/roles/nullmailer/templates/etc_nullmailer_remotes.j2
@@ -0,0 +1,2 @@
+# {{ ansible_managed }}
+{{ nullmailer_smtp_host }} smtp --port=465 --ssl --user={{ nullmailer_smtp_user }} --pass={{ nullmailer_smtp_pass }}
diff --git a/roles/nullmailer/templates/mailname.j2 b/roles/nullmailer/templates/mailname.j2
new file mode 100644
index 0000000..b305ac1
--- /dev/null
+++ b/roles/nullmailer/templates/mailname.j2
@@ -0,0 +1 @@
+{{ ansible_fqdn }} \ No newline at end of file
diff --git a/vars/default.yml b/vars/default.yml
new file mode 100644
index 0000000..9b4f1f7
--- /dev/null
+++ b/vars/default.yml
@@ -0,0 +1,13 @@
+
+# XXX: main_user_name: "number"
+email_domain: "robocracy.org"
+admin_email: "root@robocracy.org"
+friendly_networks:
+ - "robocracy.org"
+ - "bnewbold.net"
+ - "the-nsa.org"
+ - "numm.org"
+
+nullmailer_smtp_host: mail.the-nsa.org
+nullmailer_smtp_user: nullmail@the-nsa.org
+nullmailer_smtp_pass: "{{ vault_nullmailer_smtp_pass }}"